summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2014-05-14 12:13:11 +0100
committerTorne (Richard Coles) <torne@google.com>2014-05-14 12:13:11 +0100
commita3c8d4e0e27f55f266f3518886e623ace2762ae3 (patch)
tree871c17a0e3caa8aacf710175e60b5c0f41bc3664
parent387c8cc80208ae0986a49c6f36004f5e73396b38 (diff)
parentaefa5915b1afd972a37fc1aee03c95a989fef6e4 (diff)
downloadopenssl-a3c8d4e0e27f55f266f3518886e623ace2762ae3.tar.gz
Merge from Chromium at DEPS revision 269336
This commit was generated by merge_to_master.py. Change-Id: Ia8cc378112bd04b4091175297e16ffe2a3dcc817
-rw-r--r--README.chromium15
-rw-r--r--openssl.gyp3
-rw-r--r--openssl.target.darwin-arm.mk2
-rw-r--r--openssl.target.darwin-x86.mk2
-rw-r--r--openssl.target.darwin-x86_64.mk2
-rw-r--r--openssl.target.linux-arm.mk2
-rw-r--r--openssl.target.linux-x86.mk2
-rw-r--r--openssl.target.linux-x86_64.mk2
-rw-r--r--openssl/ssl/d1_clnt.c2
-rw-r--r--openssl/ssl/s23_clnt.c11
-rw-r--r--openssl/ssl/s3_clnt.c4
-rw-r--r--openssl/ssl/ssl_locl.h4
-rw-r--r--openssl/ssl/t1_lib.c176
-rw-r--r--patches.chromium/0011-fix_limit_checks.patch121
-rw-r--r--patches.chromium/0012-paddingext2.patch137
-rw-r--r--patches.chromium/0013-reorder_extensions.patch136
16 files changed, 516 insertions, 105 deletions
diff --git a/README.chromium b/README.chromium
index d994e1b..443a75d 100644
--- a/README.chromium
+++ b/README.chromium
@@ -192,13 +192,26 @@ located in patches.chromium/. Currently this consists of:
chacha.patch
Add support for ChaCha20+Poly1305 cipher suites.
+ paddingext.patch
+ paddingext2.patch
+ Add ClientHello padding to workaround bug in F5 terminators.
+
stricter_cutthrough.patch
Requires NPN and a PFS cipher suite to enable cut-through (false start) on
the client.
mac_osx32_assembly.patch
Add support for 32 bit OS X with assembly optimization.
-
+
+ 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.gyp b/openssl.gyp
index 1eb08d5..4406155 100644
--- a/openssl.gyp
+++ b/openssl.gyp
@@ -92,6 +92,9 @@
},
}],
['component == "shared_library"', {
+ 'xcode_settings': {
+ 'GCC_SYMBOLS_PRIVATE_EXTERN': 'NO', # no -fvisibility=hidden
+ },
'cflags!': ['-fvisibility=hidden'],
}],
['clang==1', {
diff --git a/openssl.target.darwin-arm.mk b/openssl.target.darwin-arm.mk
index a1aa51d..b44c4a8 100644
--- a/openssl.target.darwin-arm.mk
+++ b/openssl.target.darwin-arm.mk
@@ -599,7 +599,6 @@ MY_CFLAGS_Debug := \
-w \
-Wno-format \
-fno-tree-sra \
- -fuse-ld=gold \
-Wno-psabi \
-ffunction-sections \
-funwind-tables \
@@ -703,7 +702,6 @@ MY_CFLAGS_Release := \
-w \
-Wno-format \
-fno-tree-sra \
- -fuse-ld=gold \
-Wno-psabi \
-ffunction-sections \
-funwind-tables \
diff --git a/openssl.target.darwin-x86.mk b/openssl.target.darwin-x86.mk
index f97f1fc..93bc202 100644
--- a/openssl.target.darwin-x86.mk
+++ b/openssl.target.darwin-x86.mk
@@ -601,7 +601,6 @@ MY_CFLAGS_Debug := \
-mfpmath=sse \
-mmmx \
-m32 \
- -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -711,7 +710,6 @@ MY_CFLAGS_Release := \
-mfpmath=sse \
-mmmx \
-m32 \
- -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
diff --git a/openssl.target.darwin-x86_64.mk b/openssl.target.darwin-x86_64.mk
index 8428dbd..07bd9e3 100644
--- a/openssl.target.darwin-x86_64.mk
+++ b/openssl.target.darwin-x86_64.mk
@@ -604,7 +604,6 @@ MY_CFLAGS_Debug := \
-Wno-format \
-m64 \
-march=x86-64 \
- -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -714,7 +713,6 @@ MY_CFLAGS_Release := \
-Wno-format \
-m64 \
-march=x86-64 \
- -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
diff --git a/openssl.target.linux-arm.mk b/openssl.target.linux-arm.mk
index a1aa51d..b44c4a8 100644
--- a/openssl.target.linux-arm.mk
+++ b/openssl.target.linux-arm.mk
@@ -599,7 +599,6 @@ MY_CFLAGS_Debug := \
-w \
-Wno-format \
-fno-tree-sra \
- -fuse-ld=gold \
-Wno-psabi \
-ffunction-sections \
-funwind-tables \
@@ -703,7 +702,6 @@ MY_CFLAGS_Release := \
-w \
-Wno-format \
-fno-tree-sra \
- -fuse-ld=gold \
-Wno-psabi \
-ffunction-sections \
-funwind-tables \
diff --git a/openssl.target.linux-x86.mk b/openssl.target.linux-x86.mk
index f97f1fc..93bc202 100644
--- a/openssl.target.linux-x86.mk
+++ b/openssl.target.linux-x86.mk
@@ -601,7 +601,6 @@ MY_CFLAGS_Debug := \
-mfpmath=sse \
-mmmx \
-m32 \
- -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -711,7 +710,6 @@ MY_CFLAGS_Release := \
-mfpmath=sse \
-mmmx \
-m32 \
- -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
diff --git a/openssl.target.linux-x86_64.mk b/openssl.target.linux-x86_64.mk
index 8428dbd..07bd9e3 100644
--- a/openssl.target.linux-x86_64.mk
+++ b/openssl.target.linux-x86_64.mk
@@ -604,7 +604,6 @@ MY_CFLAGS_Debug := \
-Wno-format \
-m64 \
-march=x86-64 \
- -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
@@ -714,7 +713,6 @@ MY_CFLAGS_Release := \
-Wno-format \
-m64 \
-march=x86-64 \
- -fuse-ld=gold \
-ffunction-sections \
-funwind-tables \
-g \
diff --git a/openssl/ssl/d1_clnt.c b/openssl/ssl/d1_clnt.c
index 7e8077e..735e544 100644
--- a/openssl/ssl/d1_clnt.c
+++ b/openssl/ssl/d1_clnt.c
@@ -874,7 +874,7 @@ int dtls1_client_hello(SSL *s)
*(p++)=0; /* Add the NULL method */
#ifndef OPENSSL_NO_TLSEXT
- if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+ if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, 0)) == NULL)
{
SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
goto err;
diff --git a/openssl/ssl/s23_clnt.c b/openssl/ssl/s23_clnt.c
index 08ee86d..750d208 100644
--- a/openssl/ssl/s23_clnt.c
+++ b/openssl/ssl/s23_clnt.c
@@ -467,9 +467,9 @@ static int ssl23_client_hello(SSL *s)
/* create Client Hello in SSL 3.0/TLS 1.0 format */
/* do the record header (5 bytes) and handshake message
- * header (4 bytes) last. Note: the code to add the
- * padding extension in t1_lib.c depends on the size of
- * this prefix. */
+ * header (4 bytes) last. Note: the final argument to
+ * ssl_add_clienthello_tlsext below depends on the size
+ * of this prefix. */
d = p = &(buf[9]);
*(p++) = version_major;
@@ -526,7 +526,10 @@ static int ssl23_client_hello(SSL *s)
SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
return -1;
}
- if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+ /* The buffer includes the 5 byte record header, so
+ * subtract it to compute hlen for
+ * ssl_add_clienthello_tlsext. */
+ if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, p-buf-5)) == NULL)
{
SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
return -1;
diff --git a/openssl/ssl/s3_clnt.c b/openssl/ssl/s3_clnt.c
index d1b3224..640df80 100644
--- a/openssl/ssl/s3_clnt.c
+++ b/openssl/ssl/s3_clnt.c
@@ -759,7 +759,7 @@ int ssl3_client_hello(SSL *s)
goto err;
/* Do the message type and length last.
- * Note: the code to add the padding extension in t1_lib.c
+ * Note: the final argument to ssl_add_clienthello_tlsext below
* depends on the size of this prefix. */
d=p= &(buf[4]);
@@ -867,7 +867,7 @@ int ssl3_client_hello(SSL *s)
SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
goto err;
}
- if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+ if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, p-buf)) == NULL)
{
SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
goto err;
diff --git a/openssl/ssl/ssl_locl.h b/openssl/ssl/ssl_locl.h
index 3732825..531a291 100644
--- a/openssl/ssl/ssl_locl.h
+++ b/openssl/ssl/ssl_locl.h
@@ -1127,8 +1127,8 @@ int tls1_ec_nid2curve_id(int nid);
#endif /* OPENSSL_NO_EC */
#ifndef OPENSSL_NO_TLSEXT
-unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit);
-unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit);
+unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit, size_t header_len);
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit);
int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
int ssl_prepare_clienthello_tlsext(SSL *s);
diff --git a/openssl/ssl/t1_lib.c b/openssl/ssl/t1_lib.c
index 7a507f9..ea7fefa 100644
--- a/openssl/ssl/t1_lib.c
+++ b/openssl/ssl/t1_lib.c
@@ -341,15 +341,19 @@ int tls12_get_req_sig_algs(SSL *s, unsigned char *p)
return (int)slen;
}
-unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
+/* header_len is the length of the ClientHello header written so far, used to
+ * compute padding. It does not include the record header. Pass 0 if no padding
+ * is to be done. */
+unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit, size_t header_len)
{
int extdatalen=0;
- unsigned char *ret = p;
+ unsigned char *orig = buf;
+ unsigned char *ret = buf;
/* don't add extensions for SSLv3 unless doing secure renegotiation */
if (s->client_version == SSL3_VERSION
&& !s->s3->send_connection_binding)
- return p;
+ return orig;
ret+=2;
@@ -398,7 +402,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
return NULL;
}
- if((limit - p - 4 - el) < 0) return NULL;
+ if((limit - ret - 4 - el) < 0) return NULL;
s2n(TLSEXT_TYPE_renegotiate,ret);
s2n(el,ret);
@@ -440,55 +444,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
#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;
@@ -647,7 +602,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
- if((limit - p - 4 - el) < 0) return NULL;
+ if((limit - ret - 4 - el) < 0) return NULL;
s2n(TLSEXT_TYPE_use_srtp,ret);
s2n(el,ret);
@@ -661,49 +616,104 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
}
#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 */
- {
- int hlen = ret - (unsigned char *)s->init_buf->data;
- /* The code in s23_clnt.c to build ClientHello messages includes the
- * 5-byte record header in the buffer, while the code in s3_clnt.c does
- * not. */
- if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
- hlen -= 5;
- if (hlen > 0xff && hlen < 0x200)
+ if (header_len > 0)
{
- hlen = 0x200 - hlen;
- if (hlen >= 4)
- hlen -= 4;
- else
- hlen = 0;
+ header_len += ret - orig;
+ if (header_len > 0xff && header_len < 0x200)
+ {
+ size_t padding_len = 0x200 - header_len;
+ /* 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 = 1;
+ if (limit - ret - 4 - (long)padding_len < 0)
+ return NULL;
- s2n(TLSEXT_TYPE_padding, ret);
- s2n(hlen, ret);
- memset(ret, 0, hlen);
- ret += hlen;
+ s2n(TLSEXT_TYPE_padding, ret);
+ s2n(padding_len, ret);
+ memset(ret, 0, padding_len);
+ ret += padding_len;
+ }
}
- }
- if ((extdatalen = ret-p-2)== 0)
- return p;
+ if ((extdatalen = ret-orig-2)== 0)
+ return orig;
- s2n(extdatalen,p);
+ s2n(extdatalen, orig);
return ret;
}
-unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit)
{
int extdatalen=0;
- unsigned char *ret = p;
+ unsigned char *orig = buf;
+ unsigned char *ret = buf;
#ifndef OPENSSL_NO_NEXTPROTONEG
int next_proto_neg_seen;
#endif
/* don't add extensions for SSLv3, unless doing secure renegotiation */
if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
- return p;
+ return orig;
ret+=2;
if (ret>=limit) return NULL; /* this really never occurs, but ... */
@@ -726,7 +736,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
return NULL;
}
- if((limit - p - 4 - el) < 0) return NULL;
+ if((limit - ret - 4 - el) < 0) return NULL;
s2n(TLSEXT_TYPE_renegotiate,ret);
s2n(el,ret);
@@ -806,7 +816,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
- if((limit - p - 4 - el) < 0) return NULL;
+ if((limit - ret - 4 - el) < 0) return NULL;
s2n(TLSEXT_TYPE_use_srtp,ret);
s2n(el,ret);
@@ -885,10 +895,10 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
s2n(0,ret);
}
- if ((extdatalen = ret-p-2)== 0)
- return p;
+ if ((extdatalen = ret-orig-2)== 0)
+ return orig;
- s2n(extdatalen,p);
+ s2n(extdatalen, orig);
return ret;
}
diff --git a/patches.chromium/0011-fix_limit_checks.patch b/patches.chromium/0011-fix_limit_checks.patch
new file mode 100644
index 0000000..b4ab8a3
--- /dev/null
+++ b/patches.chromium/0011-fix_limit_checks.patch
@@ -0,0 +1,121 @@
+diff --git android-openssl.orig/ssl/ssl_locl.h android-openssl/ssl/ssl_locl.h
+index 3732825..4e27d9e 100644
+--- android-openssl.orig/ssl/ssl_locl.h
++++ android-openssl/ssl/ssl_locl.h
+@@ -1127,8 +1127,8 @@ int tls1_ec_nid2curve_id(int nid);
+ #endif /* OPENSSL_NO_EC */
+
+ #ifndef OPENSSL_NO_TLSEXT
+-unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit);
+-unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit);
++unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit);
++unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit);
+ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
+ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
+ int ssl_prepare_clienthello_tlsext(SSL *s);
+diff --git android-openssl.orig/ssl/t1_lib.c android-openssl/ssl/t1_lib.c
+index 7a507f9..a53d56b 100644
+--- android-openssl.orig/ssl/t1_lib.c
++++ android-openssl/ssl/t1_lib.c
+@@ -341,15 +341,16 @@ int tls12_get_req_sig_algs(SSL *s, unsigned char *p)
+ return (int)slen;
+ }
+
+-unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
++unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit)
+ {
+ int extdatalen=0;
+- unsigned char *ret = p;
++ unsigned char *orig = buf;
++ unsigned char *ret = buf;
+
+ /* don't add extensions for SSLv3 unless doing secure renegotiation */
+ if (s->client_version == SSL3_VERSION
+ && !s->s3->send_connection_binding)
+- return p;
++ return orig;
+
+ ret+=2;
+
+@@ -398,7 +399,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
+ return NULL;
+ }
+
+- if((limit - p - 4 - el) < 0) return NULL;
++ if((limit - ret - 4 - el) < 0) return NULL;
+
+ s2n(TLSEXT_TYPE_renegotiate,ret);
+ s2n(el,ret);
+@@ -647,7 +648,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
+
+ ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
+
+- if((limit - p - 4 - el) < 0) return NULL;
++ if((limit - ret - 4 - el) < 0) return NULL;
+
+ s2n(TLSEXT_TYPE_use_srtp,ret);
+ s2n(el,ret);
+@@ -686,24 +687,25 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
+ }
+
+
+- if ((extdatalen = ret-p-2)== 0)
+- return p;
++ if ((extdatalen = ret-orig-2)== 0)
++ return orig;
+
+- s2n(extdatalen,p);
++ s2n(extdatalen, orig);
+ return ret;
+ }
+
+-unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
++unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit)
+ {
+ int extdatalen=0;
+- unsigned char *ret = p;
++ unsigned char *orig = buf;
++ unsigned char *ret = buf;
+ #ifndef OPENSSL_NO_NEXTPROTONEG
+ int next_proto_neg_seen;
+ #endif
+
+ /* don't add extensions for SSLv3, unless doing secure renegotiation */
+ if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
+- return p;
++ return orig;
+
+ ret+=2;
+ if (ret>=limit) return NULL; /* this really never occurs, but ... */
+@@ -726,7 +728,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
+ return NULL;
+ }
+
+- if((limit - p - 4 - el) < 0) return NULL;
++ if((limit - ret - 4 - el) < 0) return NULL;
+
+ s2n(TLSEXT_TYPE_renegotiate,ret);
+ s2n(el,ret);
+@@ -806,7 +808,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
+
+ ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
+
+- if((limit - p - 4 - el) < 0) return NULL;
++ if((limit - ret - 4 - el) < 0) return NULL;
+
+ s2n(TLSEXT_TYPE_use_srtp,ret);
+ s2n(el,ret);
+@@ -885,10 +887,10 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
+ s2n(0,ret);
+ }
+
+- if ((extdatalen = ret-p-2)== 0)
+- return p;
++ if ((extdatalen = ret-orig-2)== 0)
++ return orig;
+
+- s2n(extdatalen,p);
++ s2n(extdatalen, orig);
+ return ret;
+ }
+
diff --git a/patches.chromium/0012-paddingext2.patch b/patches.chromium/0012-paddingext2.patch
new file mode 100644
index 0000000..cb7652a
--- /dev/null
+++ b/patches.chromium/0012-paddingext2.patch
@@ -0,0 +1,137 @@
+diff --git android-openssl.orig/ssl/d1_clnt.c android-openssl/ssl/d1_clnt.c
+index 7e8077e..735e544 100644
+--- android-openssl.orig/ssl/d1_clnt.c
++++ android-openssl/ssl/d1_clnt.c
+@@ -874,7 +874,7 @@ int dtls1_client_hello(SSL *s)
+ *(p++)=0; /* Add the NULL method */
+
+ #ifndef OPENSSL_NO_TLSEXT
+- if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
++ if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, 0)) == NULL)
+ {
+ SSLerr(SSL_F_DTLS1_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
+ goto err;
+diff --git android-openssl.orig/ssl/s23_clnt.c android-openssl/ssl/s23_clnt.c
+index 08ee86d..750d208 100644
+--- android-openssl.orig/ssl/s23_clnt.c
++++ android-openssl/ssl/s23_clnt.c
+@@ -467,9 +467,9 @@ static int ssl23_client_hello(SSL *s)
+ /* create Client Hello in SSL 3.0/TLS 1.0 format */
+
+ /* do the record header (5 bytes) and handshake message
+- * header (4 bytes) last. Note: the code to add the
+- * padding extension in t1_lib.c depends on the size of
+- * this prefix. */
++ * header (4 bytes) last. Note: the final argument to
++ * ssl_add_clienthello_tlsext below depends on the size
++ * of this prefix. */
+ d = p = &(buf[9]);
+
+ *(p++) = version_major;
+@@ -526,7 +526,10 @@ static int ssl23_client_hello(SSL *s)
+ SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
+ return -1;
+ }
+- if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
++ /* The buffer includes the 5 byte record header, so
++ * subtract it to compute hlen for
++ * ssl_add_clienthello_tlsext. */
++ if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, p-buf-5)) == NULL)
+ {
+ SSLerr(SSL_F_SSL23_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
+ return -1;
+diff --git android-openssl.orig/ssl/s3_clnt.c android-openssl/ssl/s3_clnt.c
+index d1b3224..640df80 100644
+--- android-openssl.orig/ssl/s3_clnt.c
++++ android-openssl/ssl/s3_clnt.c
+@@ -759,7 +759,7 @@ int ssl3_client_hello(SSL *s)
+ goto err;
+
+ /* Do the message type and length last.
+- * Note: the code to add the padding extension in t1_lib.c
++ * Note: the final argument to ssl_add_clienthello_tlsext below
+ * depends on the size of this prefix. */
+ d=p= &(buf[4]);
+
+@@ -867,7 +867,7 @@ int ssl3_client_hello(SSL *s)
+ SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
+ goto err;
+ }
+- if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
++ if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, p-buf)) == NULL)
+ {
+ SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
+ goto err;
+diff --git android-openssl.orig/ssl/ssl_locl.h android-openssl/ssl/ssl_locl.h
+index 4e27d9e..531a291 100644
+--- android-openssl.orig/ssl/ssl_locl.h
++++ android-openssl/ssl/ssl_locl.h
+@@ -1127,7 +1127,7 @@ int tls1_ec_nid2curve_id(int nid);
+ #endif /* OPENSSL_NO_EC */
+
+ #ifndef OPENSSL_NO_TLSEXT
+-unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit);
++unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit, size_t header_len);
+ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit);
+ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
+ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
+diff --git android-openssl.orig/ssl/t1_lib.c android-openssl/ssl/t1_lib.c
+index a53d56b..3fe6612 100644
+--- android-openssl.orig/ssl/t1_lib.c
++++ android-openssl/ssl/t1_lib.c
+@@ -341,7 +341,10 @@ int tls12_get_req_sig_algs(SSL *s, unsigned char *p)
+ return (int)slen;
+ }
+
+-unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit)
++/* header_len is the length of the ClientHello header written so far, used to
++ * compute padding. It does not include the record header. Pass 0 if no padding
++ * is to be done. */
++unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned char *limit, size_t header_len)
+ {
+ int extdatalen=0;
+ unsigned char *orig = buf;
+@@ -664,27 +667,25 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c
+
+ /* Add padding to workaround bugs in F5 terminators.
+ * See https://tools.ietf.org/html/draft-agl-tls-padding-02 */
+- {
+- int hlen = ret - (unsigned char *)s->init_buf->data;
+- /* The code in s23_clnt.c to build ClientHello messages includes the
+- * 5-byte record header in the buffer, while the code in s3_clnt.c does
+- * not. */
+- if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
+- hlen -= 5;
+- if (hlen > 0xff && hlen < 0x200)
++ if (header_len > 0)
+ {
+- hlen = 0x200 - hlen;
+- if (hlen >= 4)
+- hlen -= 4;
+- else
+- hlen = 0;
++ header_len += ret - orig;
++ if (header_len > 0xff && header_len < 0x200)
++ {
++ size_t padding_len = 0x200 - header_len;
++ if (padding_len >= 4)
++ padding_len -= 4;
++ else
++ padding_len = 0;
++ if (limit - ret - 4 - (long)padding_len < 0)
++ return NULL;
+
+- s2n(TLSEXT_TYPE_padding, ret);
+- s2n(hlen, ret);
+- memset(ret, 0, hlen);
+- ret += hlen;
++ s2n(TLSEXT_TYPE_padding, ret);
++ s2n(padding_len, ret);
++ memset(ret, 0, padding_len);
++ ret += padding_len;
++ }
+ }
+- }
+
+
+ if ((extdatalen = ret-orig-2)== 0)
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;
+