summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordavidben@chromium.org <davidben@chromium.org@4ff67af0-8c30-449e-8e8b-ad334ec8d88c>2014-05-01 23:51:14 +0000
committerdavidben@chromium.org <davidben@chromium.org@4ff67af0-8c30-449e-8e8b-ad334ec8d88c>2014-05-01 23:51:14 +0000
commit55b9eb8eb546355b3d55945cf09a45a434cd796f (patch)
tree8bc82dc55d39d01e1aff42e1d2532da19f82f00b
parent152164bc423807c6945662c94d724554a027eeca (diff)
downloadopenssl-55b9eb8eb546355b3d55945cf09a45a434cd796f.tar.gz
Move ECC SSL extensions to the end in OpenSSL.
WebSphere Application Server 7.0 appears to be intolerant of an empty extension at the end. To that end, also ensure we never send an empty padding extension. BUG=363583 Review URL: https://codereview.chromium.org/241613002 git-svn-id: http://src.chromium.org/svn/trunk/deps/third_party/openssl@267674 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
-rw-r--r--README.chromium7
-rw-r--r--openssl/ssl/t1_lib.c109
-rw-r--r--patches.chromium/0013-reorder_extensions.patch136
3 files changed, 200 insertions, 52 deletions
diff --git a/README.chromium b/README.chromium
index 30df8b5..443a75d 100644
--- a/README.chromium
+++ b/README.chromium
@@ -206,7 +206,12 @@ located in patches.chromium/. Currently this consists of:
fix_limit_checks.patch
Fix limit checks in writing extensions. BUF_MEM_grow allocates 4/3 the size
requested, so it doesn't overflow the actual allocation.
-
+
+ reorder_extensions.patch
+ Move the ECC extensions to the end of the ClientHello to work around a
+ server bug. Some servers are intolerant to the last extension being empty.
+ See https://crbug.com/363583
+
**************************************************************************
Adding new Chromium patches:
diff --git a/openssl/ssl/t1_lib.c b/openssl/ssl/t1_lib.c
index 3fe6612..ea7fefa 100644
--- a/openssl/ssl/t1_lib.c
+++ b/openssl/ssl/t1_lib.c
@@ -444,55 +444,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
}
#endif
-#ifndef OPENSSL_NO_EC
- if (s->tlsext_ecpointformatlist != NULL &&
- s->version != DTLS1_VERSION)
- {
- /* Add TLS extension ECPointFormats to the ClientHello message */
- long lenmax;
-
- if ((lenmax = limit - ret - 5) < 0) return NULL;
- if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
- if (s->tlsext_ecpointformatlist_length > 255)
- {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- s2n(TLSEXT_TYPE_ec_point_formats,ret);
- s2n(s->tlsext_ecpointformatlist_length + 1,ret);
- *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
- memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
- ret+=s->tlsext_ecpointformatlist_length;
- }
- if (s->tlsext_ellipticcurvelist != NULL &&
- s->version != DTLS1_VERSION)
- {
- /* Add TLS extension EllipticCurves to the ClientHello message */
- long lenmax;
-
- if ((lenmax = limit - ret - 6) < 0) return NULL;
- if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax) return NULL;
- if (s->tlsext_ellipticcurvelist_length > 65532)
- {
- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- s2n(TLSEXT_TYPE_elliptic_curves,ret);
- s2n(s->tlsext_ellipticcurvelist_length + 2, ret);
-
- /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
- * elliptic_curve_list, but the examples use two bytes.
- * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
- * resolves this to two bytes.
- */
- s2n(s->tlsext_ellipticcurvelist_length, ret);
- memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
- ret+=s->tlsext_ellipticcurvelist_length;
- }
-#endif /* OPENSSL_NO_EC */
-
if (!(SSL_get_options(s) & SSL_OP_NO_TICKET))
{
int ticklen;
@@ -665,6 +616,58 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
}
#endif
+#ifndef OPENSSL_NO_EC
+ /* WebSphere Application Server 7.0 is intolerant to the last extension
+ * being zero-length. ECC extensions are non-empty and not dropped until
+ * fallback to SSL3, at which point all extensions are gone. */
+ if (s->tlsext_ecpointformatlist != NULL &&
+ s->version != DTLS1_VERSION)
+ {
+ /* Add TLS extension ECPointFormats to the ClientHello message */
+ long lenmax;
+
+ if ((lenmax = limit - ret - 5) < 0) return NULL;
+ if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
+ if (s->tlsext_ecpointformatlist_length > 255)
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ s2n(TLSEXT_TYPE_ec_point_formats,ret);
+ s2n(s->tlsext_ecpointformatlist_length + 1,ret);
+ *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
+ memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
+ ret+=s->tlsext_ecpointformatlist_length;
+ }
+ if (s->tlsext_ellipticcurvelist != NULL &&
+ s->version != DTLS1_VERSION)
+ {
+ /* Add TLS extension EllipticCurves to the ClientHello message */
+ long lenmax;
+
+ if ((lenmax = limit - ret - 6) < 0) return NULL;
+ if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax) return NULL;
+ if (s->tlsext_ellipticcurvelist_length > 65532)
+ {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+ return NULL;
+ }
+
+ s2n(TLSEXT_TYPE_elliptic_curves,ret);
+ s2n(s->tlsext_ellipticcurvelist_length + 2, ret);
+
+ /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
+ * elliptic_curve_list, but the examples use two bytes.
+ * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
+ * resolves this to two bytes.
+ */
+ s2n(s->tlsext_ellipticcurvelist_length, ret);
+ memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
+ ret+=s->tlsext_ellipticcurvelist_length;
+ }
+#endif /* OPENSSL_NO_EC */
+
/* Add padding to workaround bugs in F5 terminators.
* See https://tools.ietf.org/html/draft-agl-tls-padding-02 */
if (header_len > 0)
@@ -673,10 +676,14 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
if (header_len > 0xff && header_len < 0x200)
{
size_t padding_len = 0x200 - header_len;
- if (padding_len >= 4)
+ /* Extensions take at least four bytes to encode. Always
+ * include least one byte of data if including the
+ * extension. WebSphere Application Server 7.0 is
+ * intolerant to the last extension being zero-length. */
+ if (padding_len >= 4 + 1)
padding_len -= 4;
else
- padding_len = 0;
+ padding_len = 1;
if (limit - ret - 4 - (long)padding_len < 0)
return NULL;
diff --git a/patches.chromium/0013-reorder_extensions.patch b/patches.chromium/0013-reorder_extensions.patch
new file mode 100644
index 0000000..11bb6a0
--- /dev/null
+++ b/patches.chromium/0013-reorder_extensions.patch
@@ -0,0 +1,136 @@
+diff --git android-openssl.orig/ssl/t1_lib.c android-openssl/ssl/t1_lib.c
+index 3fe6612..ea7fefa 100644
+--- android-openssl.orig/ssl/t1_lib.c
++++ android-openssl/ssl/t1_lib.c
+@@ -444,55 +444,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
+ }
+ #endif
+
+-#ifndef OPENSSL_NO_EC
+- if (s->tlsext_ecpointformatlist != NULL &&
+- s->version != DTLS1_VERSION)
+- {
+- /* Add TLS extension ECPointFormats to the ClientHello message */
+- long lenmax;
+-
+- if ((lenmax = limit - ret - 5) < 0) return NULL;
+- if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
+- if (s->tlsext_ecpointformatlist_length > 255)
+- {
+- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+- return NULL;
+- }
+-
+- s2n(TLSEXT_TYPE_ec_point_formats,ret);
+- s2n(s->tlsext_ecpointformatlist_length + 1,ret);
+- *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
+- memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
+- ret+=s->tlsext_ecpointformatlist_length;
+- }
+- if (s->tlsext_ellipticcurvelist != NULL &&
+- s->version != DTLS1_VERSION)
+- {
+- /* Add TLS extension EllipticCurves to the ClientHello message */
+- long lenmax;
+-
+- if ((lenmax = limit - ret - 6) < 0) return NULL;
+- if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax) return NULL;
+- if (s->tlsext_ellipticcurvelist_length > 65532)
+- {
+- SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+- return NULL;
+- }
+-
+- s2n(TLSEXT_TYPE_elliptic_curves,ret);
+- s2n(s->tlsext_ellipticcurvelist_length + 2, ret);
+-
+- /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
+- * elliptic_curve_list, but the examples use two bytes.
+- * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
+- * resolves this to two bytes.
+- */
+- s2n(s->tlsext_ellipticcurvelist_length, ret);
+- memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
+- ret+=s->tlsext_ellipticcurvelist_length;
+- }
+-#endif /* OPENSSL_NO_EC */
+-
+ if (!(SSL_get_options(s) & SSL_OP_NO_TICKET))
+ {
+ int ticklen;
+@@ -665,6 +616,58 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
+ }
+ #endif
+
++#ifndef OPENSSL_NO_EC
++ /* WebSphere Application Server 7.0 is intolerant to the last extension
++ * being zero-length. ECC extensions are non-empty and not dropped until
++ * fallback to SSL3, at which point all extensions are gone. */
++ if (s->tlsext_ecpointformatlist != NULL &&
++ s->version != DTLS1_VERSION)
++ {
++ /* Add TLS extension ECPointFormats to the ClientHello message */
++ long lenmax;
++
++ if ((lenmax = limit - ret - 5) < 0) return NULL;
++ if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) return NULL;
++ if (s->tlsext_ecpointformatlist_length > 255)
++ {
++ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
++ return NULL;
++ }
++
++ s2n(TLSEXT_TYPE_ec_point_formats,ret);
++ s2n(s->tlsext_ecpointformatlist_length + 1,ret);
++ *(ret++) = (unsigned char) s->tlsext_ecpointformatlist_length;
++ memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
++ ret+=s->tlsext_ecpointformatlist_length;
++ }
++ if (s->tlsext_ellipticcurvelist != NULL &&
++ s->version != DTLS1_VERSION)
++ {
++ /* Add TLS extension EllipticCurves to the ClientHello message */
++ long lenmax;
++
++ if ((lenmax = limit - ret - 6) < 0) return NULL;
++ if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax) return NULL;
++ if (s->tlsext_ellipticcurvelist_length > 65532)
++ {
++ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
++ return NULL;
++ }
++
++ s2n(TLSEXT_TYPE_elliptic_curves,ret);
++ s2n(s->tlsext_ellipticcurvelist_length + 2, ret);
++
++ /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for
++ * elliptic_curve_list, but the examples use two bytes.
++ * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html
++ * resolves this to two bytes.
++ */
++ s2n(s->tlsext_ellipticcurvelist_length, ret);
++ memcpy(ret, s->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist_length);
++ ret+=s->tlsext_ellipticcurvelist_length;
++ }
++#endif /* OPENSSL_NO_EC */
++
+ /* Add padding to workaround bugs in F5 terminators.
+ * See https://tools.ietf.org/html/draft-agl-tls-padding-02 */
+ if (header_len > 0)
+@@ -673,10 +676,14 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
+ if (header_len > 0xff && header_len < 0x200)
+ {
+ size_t padding_len = 0x200 - header_len;
+- if (padding_len >= 4)
++ /* Extensions take at least four bytes to encode. Always
++ * include least one byte of data if including the
++ * extension. WebSphere Application Server 7.0 is
++ * intolerant to the last extension being zero-length. */
++ if (padding_len >= 4 + 1)
+ padding_len -= 4;
+ else
+- padding_len = 0;
++ padding_len = 1;
+ if (limit - ret - 4 - (long)padding_len < 0)
+ return NULL;
+