Add advisory for SA-15:10.openssl.

This commit is contained in:
Xin LI 2015-06-12 07:33:55 +00:00
parent 9fd2f7e563
commit 3c90fafa17
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=46817
6 changed files with 2837 additions and 0 deletions

View file

@ -0,0 +1,202 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
=============================================================================
FreeBSD-SA-15:10.openssl Security Advisory
The FreeBSD Project
Topic: Multiple OpenSSL vulnerabilities
Category: contrib
Module: openssl
Announced: 2015-06-12
Affects: All supported versions of FreeBSD.
Corrected: 2015-06-11 19:07:45 UTC (stable/10, 10.1-STABLE)
2015-06-12 07:23:55 UTC (releng/10.1, 10.1-RELEASE-p12)
2015-06-11 19:39:27 UTC (stable/9, 9.3-STABLE)
2015-06-12 07:23:55 UTC (releng/9.3, 9.3-RELEASE-p16)
2015-06-11 19:39:27 UTC (stable/8, 8.4-STABLE)
2015-06-12 07:23:55 UTC (releng/8.4, 8.4-RELEASE-p30)
CVE Name: CVE-2015-1788, CVE-2015-1789, CVE-2015-1790, CVE-2015-1791
CVE-2015-1792, CVE-2015-4000
For general information regarding FreeBSD Security Advisories,
including descriptions of the fields above, security branches, and the
following sections, please visit <URL:https://security.FreeBSD.org/>.
I. Background
FreeBSD includes software from the OpenSSL Project. The OpenSSL Project is
a collaborative effort to develop a robust, commercial-grade, full-featured
Open Source toolkit implementing the Secure Sockets Layer (SSL v2/v3)
and Transport Layer Security (TLS v1) protocols as well as a full-strength
general purpose cryptography library.
II. Problem Description
A vulnerability in the TLS protocol would allow a man-in-the-middle
attacker to downgrade vulnerable TLS connections using ephemeral
Diffie-Hellman key exchange to 512-bit export-grade cryptography.
This vulnerability is also known as Logjam [CVE-2015-4000].
When processing an ECParameters structure OpenSSL enters an infinite
loop if the curve specified is over a specially malformed binary
polynomial field. [CVE-2015-1788]
X509_cmp_time does not properly check the length of the ASN1_TIME
string and can read a few bytes out of bounds. In addition,
X509_cmp_time accepts an arbitrary number of fractional seconds in
the time string. [CVE-2015-1789]
The PKCS#7 parsing code does not handle missing inner EncryptedContent
correctly. [CVE-2015-1790]
When verifying a signedData message the CMS code can enter an infinite
loop if presented with an unknown hash function OID. [CVE-2015-1792]
If a NewSessionTicket is received by a multi-threaded client when
attempting to reuse a previous ticket then a race condition can occur,
potentially leading to a double free of the ticket data. [CVE-2015-1791]
The OpenSSL advisory also describes a problem that is identified as
CVE-2014-8176, which is already fixed by an earlier FreeBSD Errata
Notice, FreeBSD-EN-15:02.openssl.
III. Impact
A man-in-the-middle attacker may be able to downgrade vulnerable TLS
connections using ephemeral Diffie-Hellman key exchange to 512-bit
export-grade cryptography. [CVE-2015-4000]. On FreeBSD 10.1, the
patch contains a countermeasure for clients by rejecting handshakes
with DH parameters shorter than 768 bits.
An attacker who is able to use a certificate to authenticate with
a remote system perform denial of service against any system which
processes public keys, certificate requests or certificates.
[CVE-2015-1788]. This affects FreeBSD 10.1 only, as the problem
was no longer exist in OpenSSL 0.9.8 series since July 2012.
An attacker can use the CVE-2015-1789 issue by using specifically
crafted certificates and CRLs of various sizes and potentially
cause a segmentation fault, resulting in a DoS on applications that
verify certificates or CRLs.
An attacker who can create specifically crafted malformed ASN.1-encoded
PKCS#7 blobs with missing content and trigger a NULL pointer dereference
on parsing. [CVE-2015-1790]. Applications that decrypt PKCS#7 data
or otherwise parse PKCS#7 structures from untrusted sources are
affected. OpenSSL clients and servers are not affected.
An attacker can perform denial of service against any system which
verifies signedData messages using the CMS code. [CVE-2015-1792]
An attacker may be able to crash multi-thread applications that
supports resumed TLS handshakes. [CVE-2015-1791]
IV. Workaround
No workaround is available.
V. Solution
Perform one of the following:
1) Upgrade your vulnerable system to a supported FreeBSD stable or
release / security branch (releng) dated after the correction date.
2) To update your vulnerable system via a binary patch:
Systems running a RELEASE version of FreeBSD on the i386 or amd64
platforms can be updated via the freebsd-update(8) utility:
# freebsd-update fetch
# freebsd-update install
3) To update your vulnerable system via a source code patch:
The following patches have been verified to apply to the applicable
FreeBSD release branches.
a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.
[FreeBSD 10.1]
# fetch https://security.FreeBSD.org/patches/SA-15:10/openssl-10.1.patch
# fetch https://security.FreeBSD.org/patches/SA-15:10/openssl-10.1.patch.asc
# gpg --verify openssl-10.1.patch.asc
[FreeBSD 9.3 and 8.4]
# fetch https://security.FreeBSD.org/patches/SA-15:10/openssl-8.4.patch
# fetch https://security.FreeBSD.org/patches/SA-15:10/openssl-8.4.patch.asc
# gpg --verify openssl-8.4.patch.asc
b) Apply the patch. Execute the following commands as root:
# cd /usr/src
# patch < /path/to/patch
c) Recompile the operating system using buildworld and installworld as
described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.
Restart all deamons using the library, or reboot the system.
VI. Correction details
The following list contains the correction revision numbers for each
affected branch.
Branch/path Revision
- -------------------------------------------------------------------------
stable/8/ r284286
releng/8.4/ r284295
stable/9/ r284286
releng/9.3/ r284295
stable/10/ r284285
releng/10.1/ r284295
- -------------------------------------------------------------------------
To see which files were modified by a particular revision, run the
following command, replacing NNNNNN with the revision number, on a
machine with Subversion installed:
# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
Or visit the following URL, replacing NNNNNN with the revision number:
<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
VII. References
<URL:https://www.openssl.org/news/secadv_20150611.txt>
<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1788>
<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1789>
<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1790>
<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1791>
<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1792>
<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4000>
The latest revision of this advisory is available at
<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-15:10.openssl.asc>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.1.4 (FreeBSD)
iQIcBAEBCgAGBQJVeopGAAoJEO1n7NZdz2rnzhQP/Ak6el188Y+7QbEYVfCZ7eG8
BQLj5TMGHV5swSKVlPcEuBlMwTjpgB5Gqhc8luDS0eIAuJGdcMPSrZDdXxWQFtPf
pbfIwp/ElFc7d6ut0Y8t6fFLJbhTOoHJpzTGkFRfJkjinGOx7OZQPeLJsxSubbnL
JKugZ3diH6yk6IPMf9SvhO/kYXUF1VbXQvHNTnqgdhFVkgF6tK22Pkl2XoJ9EHbh
vBXft1yJwiYlZ//DxZuScTUj1pHYzK3bOpg//REJMWCMj1RVwQr2EyDa0Q2cT02d
eRnSZykXD69eybyzEck+BvwnUYYJICimnHuE5t78UIr0D/NWyOAZTQ99z5TID5aV
HXkcil+1E/Q+xBB4+5UOOnESf6cmiWwewQOVvD26ZY39E6oJXvsrWnyxIuCG6DL9
sLtxB6iTYlTX5Civ/VJX8H7rFiw4UwMembthvGzck22026iHjplWM3GCWz0E8O3R
PrXBHjAzNFawK3owNMxFSUFTuFw/qY7EEwJ3SKCEC+hoxcLOl26NMxrQKRIAUk+I
MMOaZfvOh2uM19y9SJZz8+sqU8gIm7ihDm5fuSkO8kY0jdvLwyS9bXAejN/lZ6oJ
TyfTDDyXDOdaPpnpQehh6vQV0NiaJ+WXfGhfiE8/G/t6b1E0LlCaaGJTpYkildGe
vVCM4Nyx4S9WDFOi76ug
=dyhg
-----END PGP SIGNATURE-----

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.1.4 (FreeBSD)
iQIcBAABCgAGBQJVeopRAAoJEO1n7NZdz2rn1HIQALmSCore8pFtOXVFyB25t+1t
ljHMw02bhcnsFSxPkOffbCyag0vYR0f3PvMy0acruQMHQ5cTaBfp8DlVzHF5f0/w
HZhN2aX3gB2BZSyGTxqeErAfy9mg62G+irUDurn4oYiijyt1bLXpQRbrDmybmQoq
/AEbNlUcy4eXZx5DAIz6Dyx7Sqk2JDxKdHyZCwBn/UzsINzQQB63nvC02+3L5cE/
jJE1I66wndXdf5cN8QuBMvUkfklMhaxbZ/m9kfqkHfA9OYXQFbYLqpMYWrOOvPF9
xWj4ocU3OM9ifzM6VZvcWndTmY94br3q2+kB2VpBp4xO7nxI4PSjxW653b/0pvJ+
dngLkefOUhgR4nD11es1yn0TgNpXClNjw3rdz2b1ibZ04f0XSQ4RMiFrVEWYhXGj
dcqA854eWHeO8Y3nSE020g90aw4z9X0ic5Wtbs/VxecPwZny7w7dAMUN6kIBhPVu
WoXNdsWF0MGx0KJXLk2TIqSTSnmeReAB2f5pbfigFryxCsNDK1wX8Ki1WnXDV8rv
HwGE0Dy7tm3XEKCoZNcBLGMLKBT/azK5a6NHG34gs1faIQ5I0+l5XS0vBJmN+AUi
z+pjZnYie1NBbn3ePGF0dWmYwR5dJ8WXthPX8/b/M1E4hYHHVCFyUbujahjsxTfy
pyeJ6YUPDgl7gEMS21Vr
=LAVX
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,692 @@
Index: crypto/openssl/crypto/bn/bn_print.c
===================================================================
--- crypto/openssl/crypto/bn/bn_print.c (revision 284286)
+++ crypto/openssl/crypto/bn/bn_print.c (working copy)
@@ -71,6 +71,12 @@ char *BN_bn2hex(const BIGNUM *a)
char *buf;
char *p;
+ if (a->neg && BN_is_zero(a)) {
+ /* "-0" == 3 bytes including NULL terminator */
+ buf = OPENSSL_malloc(3);
+ } else {
+ buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
+ }
buf=(char *)OPENSSL_malloc(a->top*BN_BYTES*2+2);
if (buf == NULL)
{
Index: crypto/openssl/crypto/cms/cms_smime.c
===================================================================
--- crypto/openssl/crypto/cms/cms_smime.c (revision 284286)
+++ crypto/openssl/crypto/cms/cms_smime.c (working copy)
@@ -141,7 +141,7 @@ static void do_free_upto(BIO *f, BIO *upto)
BIO_free(f);
f = tbio;
}
- while (f != upto);
+ while (f && f != upto);
}
else
BIO_free_all(f);
Index: crypto/openssl/crypto/ec/ec2_smpl.c
===================================================================
--- crypto/openssl/crypto/ec/ec2_smpl.c (revision 284286)
+++ crypto/openssl/crypto/ec/ec2_smpl.c (working copy)
@@ -657,7 +657,8 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group
if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
}
- if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
+ /* test required by X9.62 */
+ if (EC_POINT_is_on_curve(group, point, ctx) <= 0)
{
ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
Index: crypto/openssl/crypto/ec/ec_check.c
===================================================================
--- crypto/openssl/crypto/ec/ec_check.c (revision 284286)
+++ crypto/openssl/crypto/ec/ec_check.c (working copy)
@@ -88,7 +88,7 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX *
ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
goto err;
}
- if (!EC_POINT_is_on_curve(group, group->generator, ctx))
+ if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0)
{
ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
Index: crypto/openssl/crypto/ec/ec_key.c
===================================================================
--- crypto/openssl/crypto/ec/ec_key.c (revision 284286)
+++ crypto/openssl/crypto/ec/ec_key.c (working copy)
@@ -316,7 +316,7 @@ int EC_KEY_check_key(const EC_KEY *eckey)
goto err;
/* testing whether the pub_key is on the elliptic curve */
- if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx))
+ if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0)
{
ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
Index: crypto/openssl/crypto/ec/ec_lib.c
===================================================================
--- crypto/openssl/crypto/ec/ec_lib.c (revision 284286)
+++ crypto/openssl/crypto/ec/ec_lib.c (working copy)
@@ -1040,7 +1040,15 @@ int EC_POINT_is_at_infinity(const EC_GROUP *group,
}
-int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
+/*
+ * Check whether an EC_POINT is on the curve or not. Note that the return
+ * value for this function should NOT be treated as a boolean. Return values:
+ * 1: The point is on the curve
+ * 0: The point is not on the curve
+ * -1: An error occurred
+ */
+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
+ BN_CTX *ctx)
{
if (group->meth->is_on_curve == 0)
{
Index: crypto/openssl/crypto/ec/ecp_smpl.c
===================================================================
--- crypto/openssl/crypto/ec/ecp_smpl.c (revision 284286)
+++ crypto/openssl/crypto/ec/ecp_smpl.c (working copy)
@@ -983,7 +983,8 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group,
if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err;
}
- if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */
+ /* test required by X9.62 */
+ if (EC_POINT_is_on_curve(group, point, ctx) <= 0)
{
ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
Index: crypto/openssl/crypto/ec/ectest.c
===================================================================
--- crypto/openssl/crypto/ec/ectest.c (revision 284286)
+++ crypto/openssl/crypto/ec/ectest.c (working copy)
@@ -267,7 +267,7 @@ void prime_field_tests()
if (!BN_hex2bn(&x, "D")) ABORT;
if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, Q, ctx))
+ if (EC_POINT_is_on_curve(group, Q, ctx) <= 0)
{
if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT;
fprintf(stderr, "Point is not on curve: x = 0x");
@@ -363,7 +363,7 @@ void prime_field_tests()
if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) ABORT;
if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) ABORT;
if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) ABORT;
if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
@@ -407,7 +407,7 @@ void prime_field_tests()
if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT;
if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT;
if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
@@ -453,7 +453,7 @@ void prime_field_tests()
if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
@@ -499,7 +499,7 @@ void prime_field_tests()
if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT;
if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
"84F3B9CAC2FC632551")) ABORT;
if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
@@ -550,7 +550,7 @@ void prime_field_tests()
if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
"9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT;
if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
"FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT;
if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
@@ -606,7 +606,7 @@ void prime_field_tests()
"B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
"3C1856A429BF97E7E31C2E5BD66")) ABORT;
if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
"FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
"C9B8899C47AEBB6FB71E91386409")) ABORT;
@@ -651,7 +651,7 @@ void prime_field_tests()
if (!EC_POINT_copy(Q, P)) ABORT;
if (EC_POINT_is_at_infinity(group, Q)) ABORT;
if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
@@ -764,7 +764,7 @@ void prime_field_tests()
#define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \
if (!BN_hex2bn(&x, _x)) ABORT; \
if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \
if (!BN_hex2bn(&z, _order)) ABORT; \
if (!BN_hex2bn(&cof, _cof)) ABORT; \
if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
@@ -782,7 +782,7 @@ void prime_field_tests()
if (!BN_hex2bn(&x, _x)) ABORT; \
if (!BN_hex2bn(&y, _y)) ABORT; \
if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \
if (!BN_hex2bn(&z, _order)) ABORT; \
if (!BN_hex2bn(&cof, _cof)) ABORT; \
if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \
@@ -895,7 +895,7 @@ void char2_field_tests()
if (!BN_hex2bn(&y, "8")) ABORT;
if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT;
#endif
- if (!EC_POINT_is_on_curve(group, Q, ctx))
+ if (EC_POINT_is_on_curve(group, Q, ctx) <= 0)
{
/* Change test based on whether binary point compression is enabled or not. */
#ifdef OPENSSL_EC_BIN_PT_COMP
@@ -1134,7 +1134,7 @@ void char2_field_tests()
if (!EC_POINT_copy(Q, P)) ABORT;
if (EC_POINT_is_at_infinity(group, Q)) ABORT;
if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
+ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT;
if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
Index: crypto/openssl/crypto/objects/obj_dat.c
===================================================================
--- crypto/openssl/crypto/objects/obj_dat.c (revision 284286)
+++ crypto/openssl/crypto/objects/obj_dat.c (working copy)
@@ -377,6 +377,9 @@ int OBJ_obj2nid(const ASN1_OBJECT *a)
if (a->nid != 0)
return(a->nid);
+ if (a->length == 0)
+ return NID_undef;
+
if (added != NULL)
{
ad.type=ADDED_DATA;
Index: crypto/openssl/crypto/pkcs7/pk7_doit.c
===================================================================
--- crypto/openssl/crypto/pkcs7/pk7_doit.c (revision 284286)
+++ crypto/openssl/crypto/pkcs7/pk7_doit.c (working copy)
@@ -410,6 +410,12 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, B
goto err;
}
+ /* Detached content must be supplied via in_bio instead. */
+ if (data_body == NULL && in_bio == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+ goto err;
+ }
+
/* We will be checking the signature */
if (md_sk != NULL)
{
@@ -587,12 +593,9 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, B
}
#if 1
- if (PKCS7_is_detached(p7) || (in_bio != NULL))
- {
- bio=in_bio;
- }
- else
- {
+ if (in_bio != NULL) {
+ bio = in_bio;
+ } else {
#if 0
bio=BIO_new(BIO_s_mem());
/* We need to set this so that when we have read all
Index: crypto/openssl/crypto/x509/x509_vfy.c
===================================================================
--- crypto/openssl/crypto/x509/x509_vfy.c (revision 284286)
+++ crypto/openssl/crypto/x509/x509_vfy.c (working copy)
@@ -1040,82 +1040,120 @@ int X509_cmp_current_time(ASN1_TIME *ctm)
}
int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time)
- {
+{
char *str;
ASN1_TIME atm;
long offset;
- char buff1[24],buff2[24],*p;
- int i,j;
+ char buff1[24], buff2[24], *p;
+ int i, j, remaining;
- p=buff1;
- i=ctm->length;
- str=(char *)ctm->data;
- if (ctm->type == V_ASN1_UTCTIME)
- {
- if ((i < 11) || (i > 17)) return 0;
- memcpy(p,str,10);
- p+=10;
- str+=10;
+ p = buff1;
+ remaining = ctm->length;
+ str = (char *)ctm->data;
+ /*
+ * Note that the following (historical) code allows much more slack in the
+ * time format than RFC5280. In RFC5280, the representation is fixed:
+ * UTCTime: YYMMDDHHMMSSZ
+ * GeneralizedTime: YYYYMMDDHHMMSSZ
+ */
+ if (ctm->type == V_ASN1_UTCTIME) {
+ /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
+ int min_length = sizeof("YYMMDDHHMMZ") - 1;
+ int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
+ if (remaining < min_length || remaining > max_length)
+ return 0;
+ memcpy(p, str, 10);
+ p += 10;
+ str += 10;
+ remaining -= 10;
+ } else {
+ /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
+ int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
+ int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
+ if (remaining < min_length || remaining > max_length)
+ return 0;
+ memcpy(p, str, 12);
+ p += 12;
+ str += 12;
+ remaining -= 12;
}
- else
- {
- if (i < 13) return 0;
- memcpy(p,str,12);
- p+=12;
- str+=12;
- }
- if ((*str == 'Z') || (*str == '-') || (*str == '+'))
- { *(p++)='0'; *(p++)='0'; }
- else
- {
- *(p++)= *(str++);
- *(p++)= *(str++);
- /* Skip any fractional seconds... */
- if (*str == '.')
- {
+ if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
+ *(p++) = '0';
+ *(p++) = '0';
+ } else {
+ /* SS (seconds) */
+ if (remaining < 2)
+ return 0;
+ *(p++) = *(str++);
+ *(p++) = *(str++);
+ remaining -= 2;
+ /*
+ * Skip any (up to three) fractional seconds...
+ * TODO(emilia): in RFC5280, fractional seconds are forbidden.
+ * Can we just kill them altogether?
+ */
+ if (remaining && *str == '.') {
str++;
- while ((*str >= '0') && (*str <= '9')) str++;
+ remaining--;
+ for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
+ if (*str < '0' || *str > '9')
+ break;
}
-
}
- *(p++)='Z';
- *(p++)='\0';
- if (*str == 'Z')
- offset=0;
- else
- {
+ }
+ *(p++) = 'Z';
+ *(p++) = '\0';
+
+ /* We now need either a terminating 'Z' or an offset. */
+ if (!remaining)
+ return 0;
+ if (*str == 'Z') {
+ if (remaining != 1)
+ return 0;
+ offset = 0;
+ } else {
+ /* (+-)HHMM */
if ((*str != '+') && (*str != '-'))
return 0;
- offset=((str[1]-'0')*10+(str[2]-'0'))*60;
- offset+=(str[3]-'0')*10+(str[4]-'0');
+ /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
+ if (remaining != 5)
+ return 0;
+ if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
+ str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
+ return 0;
+ offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
+ offset += (str[3] - '0') * 10 + (str[4] - '0');
if (*str == '-')
- offset= -offset;
+ offset = -offset;
}
- atm.type=ctm->type;
- atm.length=sizeof(buff2);
- atm.data=(unsigned char *)buff2;
+ atm.type = ctm->type;
+ atm.length = sizeof(buff2);
+ atm.data = (unsigned char *)buff2;
- if (X509_time_adj(&atm, offset*60, cmp_time) == NULL)
+ if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
return 0;
- if (ctm->type == V_ASN1_UTCTIME)
- {
- i=(buff1[0]-'0')*10+(buff1[1]-'0');
- if (i < 50) i+=100; /* cf. RFC 2459 */
- j=(buff2[0]-'0')*10+(buff2[1]-'0');
- if (j < 50) j+=100;
+ if (ctm->type == V_ASN1_UTCTIME) {
+ i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
+ if (i < 50)
+ i += 100; /* cf. RFC 2459 */
+ j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
+ if (j < 50)
+ j += 100;
- if (i < j) return -1;
- if (i > j) return 1;
+ if (i < j)
+ return -1;
+ if (i > j)
+ return 1;
}
- i=strcmp(buff1,buff2);
+ i = strcmp(buff1, buff2);
if (i == 0) /* wait a second then return younger :-) */
return -1;
else
return i;
- }
+}
ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
{
Index: crypto/openssl/ssl/d1_lib.c
===================================================================
--- crypto/openssl/ssl/d1_lib.c (revision 284286)
+++ crypto/openssl/ssl/d1_lib.c (working copy)
@@ -507,6 +507,9 @@ int dtls1_listen(SSL *s, struct sockaddr *client)
{
int ret;
+ /* Ensure there is no state left over from a previous invocation */
+ SSL_clear(s);
+
SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
s->d1->listen = 1;
Index: crypto/openssl/ssl/s3_clnt.c
===================================================================
--- crypto/openssl/ssl/s3_clnt.c (revision 284286)
+++ crypto/openssl/ssl/s3_clnt.c (working copy)
@@ -1805,6 +1805,38 @@ int ssl3_get_new_session_ticket(SSL *s)
}
p=d=(unsigned char *)s->init_msg;
+
+ if (s->session->session_id_length > 0) {
+ int i = s->session_ctx->session_cache_mode;
+ SSL_SESSION *new_sess;
+ /*
+ * We reused an existing session, so we need to replace it with a new
+ * one
+ */
+ if (i & SSL_SESS_CACHE_CLIENT) {
+ /*
+ * Remove the old session from the cache
+ */
+ if (i & SSL_SESS_CACHE_NO_INTERNAL_STORE) {
+ if (s->session_ctx->remove_session_cb != NULL)
+ s->session_ctx->remove_session_cb(s->session_ctx,
+ s->session);
+ } else {
+ /* We carry on if this fails */
+ SSL_CTX_remove_session(s->session_ctx, s->session);
+ }
+ }
+
+ if ((new_sess = ssl_session_dup(s->session, 0)) == 0) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
+ goto f_err;
+ }
+
+ SSL_SESSION_free(s->session);
+ s->session = new_sess;
+ }
+
n2l(p, s->session->tlsext_tick_lifetime_hint);
n2s(p, ticklen);
/* ticket_lifetime_hint + ticket_length + ticket */
Index: crypto/openssl/ssl/s3_srvr.c
===================================================================
--- crypto/openssl/ssl/s3_srvr.c (revision 284286)
+++ crypto/openssl/ssl/s3_srvr.c (working copy)
@@ -2012,6 +2012,7 @@ int ssl3_get_client_key_exchange(SSL *s)
int padl, outl;
krb5_timestamp authtime = 0;
krb5_ticket_times ttimes;
+ int kerr = 0;
EVP_CIPHER_CTX_init(&ciph_ctx);
@@ -2124,19 +2125,22 @@ int ssl3_get_client_key_exchange(SSL *s)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
- goto err;
+ kerr = 1;
+ goto kclean;
}
if (outl > SSL_MAX_MASTER_KEY_LENGTH)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
- goto err;
+ kerr = 1;
+ goto kclean;
}
if (!EVP_DecryptFinal_ex(&ciph_ctx,&(pms[outl]),&padl))
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
- goto err;
+ kerr = 1;
+ goto kclean;
}
outl += padl;
if (outl > SSL_MAX_MASTER_KEY_LENGTH)
@@ -2143,7 +2147,8 @@ int ssl3_get_client_key_exchange(SSL *s)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DATA_LENGTH_TOO_LONG);
- goto err;
+ kerr = 1;
+ goto kclean;
}
if (!((pms[0] == (s->client_version>>8)) && (pms[1] == (s->client_version & 0xff))))
{
@@ -2159,7 +2164,8 @@ int ssl3_get_client_key_exchange(SSL *s)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_AD_DECODE_ERROR);
- goto err;
+ kerr = 1;
+ goto kclean;
}
}
@@ -2185,8 +2191,12 @@ int ssl3_get_client_key_exchange(SSL *s)
** kssl_ctx = kssl_ctx_free(kssl_ctx);
** if (s->kssl_ctx) s->kssl_ctx = NULL;
*/
- }
- else
+
+ kclean:
+ OPENSSL_cleanse(pms, sizeof(pms));
+ if (kerr)
+ goto err;
+ } else
#endif /* OPENSSL_NO_KRB5 */
#ifndef OPENSSL_NO_ECDH
Index: crypto/openssl/ssl/ssl.h
===================================================================
--- crypto/openssl/ssl/ssl.h (revision 284286)
+++ crypto/openssl/ssl/ssl.h (working copy)
@@ -1851,6 +1851,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_READ 223
#define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187
#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188
+#define SSL_F_SSL_SESSION_DUP 348
#define SSL_F_SSL_SESSION_NEW 189
#define SSL_F_SSL_SESSION_PRINT_FP 190
#define SSL_F_SSL_SESS_CERT_NEW 225
Index: crypto/openssl/ssl/ssl_err.c
===================================================================
--- crypto/openssl/ssl/ssl_err.c (revision 284286)
+++ crypto/openssl/ssl/ssl_err.c (working copy)
@@ -233,6 +233,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{ERR_FUNC(SSL_F_SSL_READ), "SSL_read"},
{ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"},
{ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"},
+{ERR_FUNC(SSL_F_SSL_SESSION_DUP), "ssl_session_dup"},
{ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"},
{ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"},
{ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW), "SSL_SESS_CERT_NEW"},
Index: crypto/openssl/ssl/ssl_locl.h
===================================================================
--- crypto/openssl/ssl/ssl_locl.h (revision 284286)
+++ crypto/openssl/ssl/ssl_locl.h (working copy)
@@ -731,6 +731,7 @@ void ssl_sess_cert_free(SESS_CERT *sc);
int ssl_set_peer_cert_type(SESS_CERT *c, int type);
int ssl_get_new_session(SSL *s, int session);
int ssl_get_prev_session(SSL *s, unsigned char *session,int len, const unsigned char *limit);
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket);
int ssl_cipher_id_cmp(const SSL_CIPHER *a,const SSL_CIPHER *b);
int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap,
const SSL_CIPHER * const *bp);
Index: crypto/openssl/ssl/ssl_sess.c
===================================================================
--- crypto/openssl/ssl/ssl_sess.c (revision 284286)
+++ crypto/openssl/ssl/ssl_sess.c (working copy)
@@ -132,6 +132,79 @@ SSL_SESSION *SSL_SESSION_new(void)
return(ss);
}
+/*
+ * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
+ * ticket == 0 then no ticket information is duplicated, otherwise it is.
+ */
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
+{
+ SSL_SESSION *dest;
+
+ dest = OPENSSL_malloc(sizeof(*src));
+ if (dest == NULL) {
+ goto err;
+ }
+ memcpy(dest, src, sizeof(*dest));
+
+ /*
+ * Set the various pointers to NULL so that we can call SSL_SESSION_free in
+ * the case of an error whilst halfway through constructing dest
+ */
+ dest->ciphers = NULL;
+#ifndef OPENSSL_NO_TLSEXT
+ dest->tlsext_hostname = NULL;
+#endif
+ dest->tlsext_tick = NULL;
+ memset(&dest->ex_data, 0, sizeof(dest->ex_data));
+
+ /* We deliberately don't copy the prev and next pointers */
+ dest->prev = NULL;
+ dest->next = NULL;
+
+ dest->references = 1;
+
+ if (src->sess_cert != NULL)
+ CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT);
+
+ if (src->peer != NULL)
+ CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509);
+
+ if(src->ciphers != NULL) {
+ dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers);
+ if (dest->ciphers == NULL)
+ goto err;
+ }
+
+ if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,
+ &dest->ex_data, &src->ex_data)) {
+ goto err;
+ }
+
+#ifndef OPENSSL_NO_TLSEXT
+ if (src->tlsext_hostname) {
+ dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname);
+ if (dest->tlsext_hostname == NULL) {
+ goto err;
+ }
+ }
+#endif
+
+ if (ticket != 0) {
+ dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen);
+ if(dest->tlsext_tick == NULL)
+ goto err;
+ } else {
+ dest->tlsext_tick_lifetime_hint = 0;
+ dest->tlsext_ticklen = 0;
+ }
+
+ return dest;
+err:
+ SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE);
+ SSL_SESSION_free(dest);
+ return NULL;
+}
+
const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
{
if(len)

View file

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.1.4 (FreeBSD)
iQIcBAABCgAGBQJVeopRAAoJEO1n7NZdz2rnZYsQAJRiUWdpLgWCu/G3BK66YfGg
2UbZ9+dH0toD9CCiaFrgupP58ui9PYxwR97k4/M2RXcZ4gz6bpJ5meyTKM8R283U
EuBmnvKcJGdXaWobYThrvV9rsK4dvYcvL1f4PsA/5rEYP3WQzvOFEeIqaSy0KlS/
ojCfuPP8IkPWtVRbqFOIZOHUpopyzxoi1Kj72p2rEsK+89ppei+ruHOM2fCSfRHY
ZgUriMkTQM+lge6XCFhZNQd3sCnvSyLiAAvX9xHDENKXjcMhlLnwezpQp7/WOsyj
jirEFgOmkcleJFWVB+mwkJp2RumINqBfhSS4M+vDgmv/4FWXyORSZqPVJW7rS9Cu
BZZgTrVrTuUrhHiyKzLT7sSrJgD+tgWPGVBi/3Deb4l7vLuZLivQBumN4nENdERv
N8dm0SEOPBHnSQ2VhXaDd3UWrHs36KGjYLvEFqcym3kA4wC1V8kX7WujnmEjLmWg
O4I0xWjje9vQL/XCUWJmFLyZ4SsaAss4MqNJXyQpLMxglxtfqz8t6C/NKCMFQxif
o0HyYzD+lAXEI3AwV9FWtGEx6Ld676QQtjYrUYra92pPnBDvyd1Z18Uvch9zg8ND
2fOa3XzKlb8hIQvaGLUQTj8D1cA5ZjcrMwD6PMneE2XCaHdYw7nUoLCeyB5NM8BS
4iCv8E2CdsITAL6edWqq
=TifN
-----END PGP SIGNATURE-----

View file

@ -7,6 +7,18 @@
<year>
<name>2015</name>
<month>
<name>6</name>
<day>
<name>12</name>
<advisory>
<name>FreeBSD-SA-15:10.openssl</name>
</advisory>
</day>
</month>
<month>
<name>4</name>