summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2014-06-03 10:59:18 +0100
committerTorne (Richard Coles) <torne@google.com>2014-06-03 10:59:18 +0100
commitde3469808fd291318d632868c0f37618962e1c7a (patch)
tree6ead13b5f66beae3acb85d1ad2f840fcc3bb9331
parentcf9e44ef952b1a6a2ff9738a1cdd6283fb3f6898 (diff)
parent21ed393e0da597351a61be6df6134983fbe47ffe (diff)
downloadopenssl-de3469808fd291318d632868c0f37618962e1c7a.tar.gz
Merge from Chromium at DEPS revision 273901
This commit was generated by merge_to_master.py. Change-Id: I8a639c7a291feed376dfb255c14c27dfb0e8d364
-rw-r--r--BUILD.gn4
-rw-r--r--README.chromium7
-rw-r--r--openssl.target.darwin-arm.mk24
-rw-r--r--openssl.target.darwin-arm64.mk10
-rw-r--r--openssl.target.darwin-mips.mk12
-rw-r--r--openssl.target.darwin-x86.mk12
-rw-r--r--openssl.target.darwin-x86_64.mk10
-rw-r--r--openssl.target.linux-arm.mk24
-rw-r--r--openssl.target.linux-arm64.mk10
-rw-r--r--openssl.target.linux-mips.mk12
-rw-r--r--openssl.target.linux-x86.mk12
-rw-r--r--openssl.target.linux-x86_64.mk10
-rw-r--r--openssl/include/openssl/ssl.h10
-rw-r--r--openssl/include/openssl/ssl3.h2
-rw-r--r--openssl/include/openssl/tls1.h2
-rw-r--r--openssl/patches/new_channelid.patch273
-rw-r--r--openssl/ssl/s3_clnt.c134
-rw-r--r--openssl/ssl/ssl.h10
-rw-r--r--openssl/ssl/ssl3.h2
-rw-r--r--openssl/ssl/ssl_cert.c15
-rw-r--r--openssl/ssl/ssl_locl.h2
-rw-r--r--openssl/ssl/t1_enc.c90
-rw-r--r--openssl/ssl/t1_lib.c37
-rw-r--r--openssl/ssl/tls1.h2
-rw-r--r--patches.chromium/0014-new_channelid.patch537
-rw-r--r--patches.chromium/0015-export_certificate_types.patch80
-rw-r--r--patches.chromium/0016-send_client_verify_cleanup.patch187
27 files changed, 1427 insertions, 103 deletions
diff --git a/BUILD.gn b/BUILD.gn
index d29beed..749ba08 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -68,6 +68,10 @@ component("openssl") {
sources -= gypi_values.openssl_x86_source_excludes
defines += gypi_values.openssl_x86_defines
} else if (cpu_arch == "arm") {
+ # The ARM sources do not compile with full warnings enabled.
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [ "//build/config/compiler:no_chromium_code" ]
+
sources += gypi_values.openssl_arm_sources
sources -= gypi_values.openssl_arm_source_excludes
defines += gypi_values.openssl_arm_defines
diff --git a/README.chromium b/README.chromium
index 443a75d..4aee197 100644
--- a/README.chromium
+++ b/README.chromium
@@ -212,6 +212,13 @@ located in patches.chromium/. Currently this consists of:
server bug. Some servers are intolerant to the last extension being empty.
See https://crbug.com/363583
+ export_certificate_types.patch
+ Export the certificate_types field in CertificateRequest.
+
+ send_client_verify_cleanup.patch
+ Clean up ssl3_send_client_verify so the various cases (TLS 1.2, pre-TLS-1.2
+ cases for each cipher suite) are less intertwined.
+
**************************************************************************
Adding new Chromium patches:
diff --git a/openssl.target.darwin-arm.mk b/openssl.target.darwin-arm.mk
index f1ebd9c..38cfe62 100644
--- a/openssl.target.darwin-arm.mk
+++ b/openssl.target.darwin-arm.mk
@@ -596,9 +596,16 @@ MY_CFLAGS_Debug := \
-fvisibility=hidden \
-pipe \
-fPIC \
+ -Wno-unused-local-typedefs \
-w \
-Wno-format \
-fno-tree-sra \
+ -fno-partial-inlining \
+ -fno-early-inlining \
+ -fno-tree-copy-prop \
+ -fno-tree-loop-optimize \
+ -fno-move-loop-invariants \
+ -fno-caller-saves \
-Wno-psabi \
-ffunction-sections \
-funwind-tables \
@@ -634,12 +641,17 @@ MY_DEFS_Debug := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
@@ -700,9 +712,16 @@ MY_CFLAGS_Release := \
-fvisibility=hidden \
-pipe \
-fPIC \
+ -Wno-unused-local-typedefs \
-w \
-Wno-format \
-fno-tree-sra \
+ -fno-partial-inlining \
+ -fno-early-inlining \
+ -fno-tree-copy-prop \
+ -fno-tree-loop-optimize \
+ -fno-move-loop-invariants \
+ -fno-caller-saves \
-Wno-psabi \
-ffunction-sections \
-funwind-tables \
@@ -738,12 +757,17 @@ MY_DEFS_Release := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
diff --git a/openssl.target.darwin-arm64.mk b/openssl.target.darwin-arm64.mk
index 093bfc9..d002920 100644
--- a/openssl.target.darwin-arm64.mk
+++ b/openssl.target.darwin-arm64.mk
@@ -622,12 +622,17 @@ MY_DEFS_Debug := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
@@ -716,12 +721,17 @@ MY_DEFS_Release := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
diff --git a/openssl.target.darwin-mips.mk b/openssl.target.darwin-mips.mk
index 52b0be8..aef592a 100644
--- a/openssl.target.darwin-mips.mk
+++ b/openssl.target.darwin-mips.mk
@@ -591,6 +591,7 @@ MY_CFLAGS_Debug := \
-fvisibility=hidden \
-pipe \
-fPIC \
+ -Wno-unused-local-typedefs \
-w \
-Wno-format \
-EL \
@@ -629,12 +630,17 @@ MY_DEFS_Debug := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
@@ -693,6 +699,7 @@ MY_CFLAGS_Release := \
-fvisibility=hidden \
-pipe \
-fPIC \
+ -Wno-unused-local-typedefs \
-w \
-Wno-format \
-EL \
@@ -731,12 +738,17 @@ MY_DEFS_Release := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
diff --git a/openssl.target.darwin-x86.mk b/openssl.target.darwin-x86.mk
index 5ebaa58..c7ff427 100644
--- a/openssl.target.darwin-x86.mk
+++ b/openssl.target.darwin-x86.mk
@@ -595,6 +595,7 @@ MY_CFLAGS_Debug := \
-fvisibility=hidden \
-pipe \
-fPIC \
+ -Wno-unused-local-typedefs \
-w \
-Wno-format \
-msse2 \
@@ -635,12 +636,17 @@ MY_DEFS_Debug := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
@@ -705,6 +711,7 @@ MY_CFLAGS_Release := \
-fvisibility=hidden \
-pipe \
-fPIC \
+ -Wno-unused-local-typedefs \
-w \
-Wno-format \
-msse2 \
@@ -745,12 +752,17 @@ MY_DEFS_Release := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
diff --git a/openssl.target.darwin-x86_64.mk b/openssl.target.darwin-x86_64.mk
index cf24e4b..68b2cbf 100644
--- a/openssl.target.darwin-x86_64.mk
+++ b/openssl.target.darwin-x86_64.mk
@@ -638,12 +638,17 @@ MY_DEFS_Debug := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
@@ -748,12 +753,17 @@ MY_DEFS_Release := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
diff --git a/openssl.target.linux-arm.mk b/openssl.target.linux-arm.mk
index f1ebd9c..38cfe62 100644
--- a/openssl.target.linux-arm.mk
+++ b/openssl.target.linux-arm.mk
@@ -596,9 +596,16 @@ MY_CFLAGS_Debug := \
-fvisibility=hidden \
-pipe \
-fPIC \
+ -Wno-unused-local-typedefs \
-w \
-Wno-format \
-fno-tree-sra \
+ -fno-partial-inlining \
+ -fno-early-inlining \
+ -fno-tree-copy-prop \
+ -fno-tree-loop-optimize \
+ -fno-move-loop-invariants \
+ -fno-caller-saves \
-Wno-psabi \
-ffunction-sections \
-funwind-tables \
@@ -634,12 +641,17 @@ MY_DEFS_Debug := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
@@ -700,9 +712,16 @@ MY_CFLAGS_Release := \
-fvisibility=hidden \
-pipe \
-fPIC \
+ -Wno-unused-local-typedefs \
-w \
-Wno-format \
-fno-tree-sra \
+ -fno-partial-inlining \
+ -fno-early-inlining \
+ -fno-tree-copy-prop \
+ -fno-tree-loop-optimize \
+ -fno-move-loop-invariants \
+ -fno-caller-saves \
-Wno-psabi \
-ffunction-sections \
-funwind-tables \
@@ -738,12 +757,17 @@ MY_DEFS_Release := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
diff --git a/openssl.target.linux-arm64.mk b/openssl.target.linux-arm64.mk
index 093bfc9..d002920 100644
--- a/openssl.target.linux-arm64.mk
+++ b/openssl.target.linux-arm64.mk
@@ -622,12 +622,17 @@ MY_DEFS_Debug := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
@@ -716,12 +721,17 @@ MY_DEFS_Release := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
diff --git a/openssl.target.linux-mips.mk b/openssl.target.linux-mips.mk
index 52b0be8..aef592a 100644
--- a/openssl.target.linux-mips.mk
+++ b/openssl.target.linux-mips.mk
@@ -591,6 +591,7 @@ MY_CFLAGS_Debug := \
-fvisibility=hidden \
-pipe \
-fPIC \
+ -Wno-unused-local-typedefs \
-w \
-Wno-format \
-EL \
@@ -629,12 +630,17 @@ MY_DEFS_Debug := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
@@ -693,6 +699,7 @@ MY_CFLAGS_Release := \
-fvisibility=hidden \
-pipe \
-fPIC \
+ -Wno-unused-local-typedefs \
-w \
-Wno-format \
-EL \
@@ -731,12 +738,17 @@ MY_DEFS_Release := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
diff --git a/openssl.target.linux-x86.mk b/openssl.target.linux-x86.mk
index 5ebaa58..c7ff427 100644
--- a/openssl.target.linux-x86.mk
+++ b/openssl.target.linux-x86.mk
@@ -595,6 +595,7 @@ MY_CFLAGS_Debug := \
-fvisibility=hidden \
-pipe \
-fPIC \
+ -Wno-unused-local-typedefs \
-w \
-Wno-format \
-msse2 \
@@ -635,12 +636,17 @@ MY_DEFS_Debug := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
@@ -705,6 +711,7 @@ MY_CFLAGS_Release := \
-fvisibility=hidden \
-pipe \
-fPIC \
+ -Wno-unused-local-typedefs \
-w \
-Wno-format \
-msse2 \
@@ -745,12 +752,17 @@ MY_DEFS_Release := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
diff --git a/openssl.target.linux-x86_64.mk b/openssl.target.linux-x86_64.mk
index cf24e4b..68b2cbf 100644
--- a/openssl.target.linux-x86_64.mk
+++ b/openssl.target.linux-x86_64.mk
@@ -638,12 +638,17 @@ MY_DEFS_Debug := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
@@ -748,12 +753,17 @@ MY_DEFS_Release := \
'-DENABLE_WEBRTC=1' \
'-DUSE_PROPRIETARY_CODECS' \
'-DENABLE_CONFIGURATION_POLICY' \
+ '-DENABLE_NEW_GAMEPAD_API=1' \
'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
'-DENABLE_EGLIMAGE=1' \
'-DCLD_VERSION=1' \
'-DENABLE_PRINTING=1' \
'-DENABLE_MANAGED_USERS=1' \
+ '-DDATA_REDUCTION_FALLBACK_HOST="http://compress.googlezip.net:80/"' \
+ '-DDATA_REDUCTION_DEV_HOST="http://proxy-dev.googlezip.net:80/"' \
+ '-DSPDY_PROXY_AUTH_ORIGIN="https://proxy.googlezip.net:443/"' \
+ '-DDATA_REDUCTION_PROXY_PROBE_URL="http://check.googlezip.net/connect"' \
'-DVIDEO_HOLE=1' \
'-DNO_WINDOWS_BRAINDEATH' \
'-DPURIFY' \
diff --git a/openssl/include/openssl/ssl.h b/openssl/include/openssl/ssl.h
index a3944f1..5faae95 100644
--- a/openssl/include/openssl/ssl.h
+++ b/openssl/include/openssl/ssl.h
@@ -547,6 +547,13 @@ struct ssl_session_st
#ifndef OPENSSL_NO_SRP
char *srp_username;
#endif
+
+ /* original_handshake_hash contains the handshake hash (either
+ * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
+ * handshake that created a session. This is used by Channel IDs during
+ * resumption. */
+ unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
+ unsigned int original_handshake_hash_len;
};
#endif
@@ -1982,6 +1989,9 @@ STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
int SSL_add_client_CA(SSL *ssl,X509 *x);
int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x);
+void SSL_get_client_certificate_types(const SSL *s, const unsigned char **ctype,
+ size_t *ctype_num);
+
void SSL_set_connect_state(SSL *s);
void SSL_set_accept_state(SSL *s);
diff --git a/openssl/include/openssl/ssl3.h b/openssl/include/openssl/ssl3.h
index 899c8a8..019e8d8 100644
--- a/openssl/include/openssl/ssl3.h
+++ b/openssl/include/openssl/ssl3.h
@@ -508,7 +508,7 @@ typedef struct ssl3_state_st
/* used for certificate requests */
int cert_req;
int ctype_num;
- char ctype[SSL3_CT_NUMBER];
+ unsigned char ctype[SSL3_CT_NUMBER];
STACK_OF(X509_NAME) *ca_names;
int use_rsa_tmp;
diff --git a/openssl/include/openssl/tls1.h b/openssl/include/openssl/tls1.h
index c4f69aa..5559486 100644
--- a/openssl/include/openssl/tls1.h
+++ b/openssl/include/openssl/tls1.h
@@ -255,7 +255,7 @@ extern "C" {
#endif
/* This is not an IANA defined extension number */
-#define TLSEXT_TYPE_channel_id 30031
+#define TLSEXT_TYPE_channel_id 30032
/* NameType value from RFC 3546 */
#define TLSEXT_NAMETYPE_host_name 0
diff --git a/openssl/patches/new_channelid.patch b/openssl/patches/new_channelid.patch
new file mode 100644
index 0000000..22a8fdd
--- /dev/null
+++ b/openssl/patches/new_channelid.patch
@@ -0,0 +1,273 @@
+diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
+index a3944f1..fe92ccf 100644
+--- a/include/openssl/ssl.h
++++ b/include/openssl/ssl.h
+@@ -547,6 +547,13 @@ struct ssl_session_st
+ #ifndef OPENSSL_NO_SRP
+ char *srp_username;
+ #endif
++
++ /* original_handshake_hash contains the handshake hash (either
++ * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
++ * handshake that created a session. This is used by Channel IDs during
++ * resumption. */
++ unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
++ unsigned int original_handshake_hash_len;
+ };
+
+ #endif
+diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
+index c4f69aa..5559486 100644
+--- a/include/openssl/tls1.h
++++ b/include/openssl/tls1.h
+@@ -255,7 +255,7 @@ extern "C" {
+ #endif
+
+ /* This is not an IANA defined extension number */
+-#define TLSEXT_TYPE_channel_id 30031
++#define TLSEXT_TYPE_channel_id 30032
+
+ /* NameType value from RFC 3546 */
+ #define TLSEXT_NAMETYPE_host_name 0
+diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
+index 640df80..d6154c5 100644
+--- a/ssl/s3_clnt.c
++++ b/ssl/s3_clnt.c
+@@ -583,6 +583,18 @@ int ssl3_connect(SSL *s)
+ #endif
+ s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
+ }
++ if (s->s3->tlsext_channel_id_valid)
++ {
++ /* This is a non-resumption handshake. If it
++ * involves ChannelID, then record the
++ * handshake hashes at this point in the
++ * session so that any resumption of this
++ * session with ChannelID can sign those
++ * hashes. */
++ ret = tls1_record_handshake_hashes_for_channel_id(s);
++ if (ret <= 0)
++ goto end;
++ }
+ }
+ s->init_num=0;
+ break;
+diff --git a/ssl/ssl.h b/ssl/ssl.h
+index a3944f1..fe92ccf 100644
+--- a/ssl/ssl.h
++++ b/ssl/ssl.h
+@@ -547,6 +547,13 @@ struct ssl_session_st
+ #ifndef OPENSSL_NO_SRP
+ char *srp_username;
+ #endif
++
++ /* original_handshake_hash contains the handshake hash (either
++ * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
++ * handshake that created a session. This is used by Channel IDs during
++ * resumption. */
++ unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
++ unsigned int original_handshake_hash_len;
+ };
+
+ #endif
+diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
+index 531a291..c975d31 100644
+--- a/ssl/ssl_locl.h
++++ b/ssl/ssl_locl.h
+@@ -1102,6 +1102,7 @@ void ssl_free_wbio_buffer(SSL *s);
+ int tls1_change_cipher_state(SSL *s, int which);
+ int tls1_setup_key_block(SSL *s);
+ int tls1_enc(SSL *s, int snd);
++int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len);
+ int tls1_final_finish_mac(SSL *s,
+ const char *str, int slen, unsigned char *p);
+ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
+@@ -1158,6 +1159,7 @@ int tls12_get_sigid(const EVP_PKEY *pk);
+ const EVP_MD *tls12_get_hash(unsigned char hash_alg);
+
+ int tls1_channel_id_hash(EVP_MD_CTX *ctx, SSL *s);
++int tls1_record_handshake_hashes_for_channel_id(SSL *s);
+ #endif
+
+ int ssl3_can_cutthrough(const SSL *s);
+diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
+index 87b7021..d30ce61 100644
+--- a/ssl/t1_enc.c
++++ b/ssl/t1_enc.c
+@@ -1147,53 +1147,79 @@ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
+ return((int)ret);
+ }
+
++/* tls1_handshake_digest calculates the current handshake hash and writes it to
++ * |out|, which has space for |out_len| bytes. It returns the number of bytes
++ * written or -1 in the event of an error. This function works on a copy of the
++ * underlying digests so can be called multiple times and prior to the final
++ * update etc. */
++int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len)
++ {
++ const EVP_MD *md;
++ EVP_MD_CTX ctx;
++ int i, err = 0, len = 0;
++ long mask;
++
++ EVP_MD_CTX_init(&ctx);
++
++ for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++)
++ {
++ int hash_size;
++ unsigned int digest_len;
++ EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];
++
++ if ((mask & ssl_get_algorithm2(s)) == 0)
++ continue;
++
++ hash_size = EVP_MD_size(md);
++ if (!hdgst || hash_size < 0 || (size_t)hash_size > out_len)
++ {
++ err = 1;
++ break;
++ }
++
++ if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
++ !EVP_DigestFinal_ex(&ctx, out, &digest_len) ||
++ digest_len != (unsigned int)hash_size) /* internal error */
++ {
++ err = 1;
++ break;
++ }
++ out += digest_len;
++ out_len -= digest_len;
++ len += digest_len;
++ }
++
++ EVP_MD_CTX_cleanup(&ctx);
++
++ if (err != 0)
++ return -1;
++ return len;
++ }
++
+ int tls1_final_finish_mac(SSL *s,
+ const char *str, int slen, unsigned char *out)
+ {
+- unsigned int i;
+- EVP_MD_CTX ctx;
+ unsigned char buf[2*EVP_MAX_MD_SIZE];
+- unsigned char *q,buf2[12];
+- int idx;
+- long mask;
++ unsigned char buf2[12];
+ int err=0;
+- const EVP_MD *md;
++ int digests_len;
+
+- q=buf;
+-
+- if (s->s3->handshake_buffer)
++ if (s->s3->handshake_buffer)
+ if (!ssl3_digest_cached_records(s))
+ return 0;
+
+- EVP_MD_CTX_init(&ctx);
+-
+- for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
++ digests_len = tls1_handshake_digest(s, buf, sizeof(buf));
++ if (digests_len < 0)
+ {
+- if (mask & ssl_get_algorithm2(s))
+- {
+- int hashsize = EVP_MD_size(md);
+- if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
+- {
+- /* internal error: 'buf' is too small for this cipersuite! */
+- err = 1;
+- }
+- else
+- {
+- EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
+- EVP_DigestFinal_ex(&ctx,q,&i);
+- if (i != (unsigned int)hashsize) /* can't really happen */
+- err = 1;
+- q+=i;
+- }
+- }
++ err = 1;
++ digests_len = 0;
+ }
+-
++
+ if (!tls1_PRF(ssl_get_algorithm2(s),
+- str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
++ str,slen, buf, digests_len, NULL,0, NULL,0, NULL,0,
+ s->session->master_key,s->session->master_key_length,
+ out,buf2,sizeof buf2))
+ err = 1;
+- EVP_MD_CTX_cleanup(&ctx);
+
+ if (err)
+ return 0;
+diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
+index ea7fefa..d7ea9a5 100644
+--- a/ssl/t1_lib.c
++++ b/ssl/t1_lib.c
+@@ -2684,6 +2684,17 @@ tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
+
+ EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
+
++ if (s->hit)
++ {
++ static const char kResumptionMagic[] = "Resumption";
++ EVP_DigestUpdate(md, kResumptionMagic,
++ sizeof(kResumptionMagic));
++ if (s->session->original_handshake_hash_len == 0)
++ return 0;
++ EVP_DigestUpdate(md, s->session->original_handshake_hash,
++ s->session->original_handshake_hash_len);
++ }
++
+ EVP_MD_CTX_init(&ctx);
+ for (i = 0; i < SSL_MAX_DIGEST; i++)
+ {
+@@ -2698,3 +2709,29 @@ tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
+ return 1;
+ }
+ #endif
++
++/* tls1_record_handshake_hashes_for_channel_id records the current handshake
++ * hashes in |s->session| so that Channel ID resumptions can sign that data. */
++int tls1_record_handshake_hashes_for_channel_id(SSL *s)
++ {
++ int digest_len;
++ /* This function should never be called for a resumed session because
++ * the handshake hashes that we wish to record are for the original,
++ * full handshake. */
++ if (s->hit)
++ return -1;
++ /* It only makes sense to call this function if Channel IDs have been
++ * negotiated. */
++ if (!s->s3->tlsext_channel_id_valid)
++ return -1;
++
++ digest_len = tls1_handshake_digest(
++ s, s->session->original_handshake_hash,
++ sizeof(s->session->original_handshake_hash));
++ if (digest_len < 0)
++ return -1;
++
++ s->session->original_handshake_hash_len = digest_len;
++
++ return 1;
++ }
+diff --git a/ssl/tls1.h b/ssl/tls1.h
+index c4f69aa..5559486 100644
+--- a/ssl/tls1.h
++++ b/ssl/tls1.h
+@@ -255,7 +255,7 @@ extern "C" {
+ #endif
+
+ /* This is not an IANA defined extension number */
+-#define TLSEXT_TYPE_channel_id 30031
++#define TLSEXT_TYPE_channel_id 30032
+
+ /* NameType value from RFC 3546 */
+ #define TLSEXT_NAMETYPE_host_name 0
diff --git a/openssl/ssl/s3_clnt.c b/openssl/ssl/s3_clnt.c
index 640df80..2b094c9 100644
--- a/openssl/ssl/s3_clnt.c
+++ b/openssl/ssl/s3_clnt.c
@@ -583,6 +583,18 @@ int ssl3_connect(SSL *s)
#endif
s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
}
+ if (s->s3->tlsext_channel_id_valid)
+ {
+ /* This is a non-resumption handshake. If it
+ * involves ChannelID, then record the
+ * handshake hashes at this point in the
+ * session so that any resumption of this
+ * session with ChannelID can sign those
+ * hashes. */
+ ret = tls1_record_handshake_hashes_for_channel_id(s);
+ if (ret <= 0)
+ goto end;
+ }
}
s->init_num=0;
break;
@@ -3010,33 +3022,18 @@ int ssl3_send_client_verify(SSL *s)
unsigned char *p,*d;
unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
EVP_PKEY *pkey;
- EVP_PKEY_CTX *pctx=NULL;
+ EVP_PKEY_CTX *pctx = NULL;
EVP_MD_CTX mctx;
- unsigned u=0;
+ unsigned signature_length = 0;
unsigned long n;
- int j;
EVP_MD_CTX_init(&mctx);
if (s->state == SSL3_ST_CW_CERT_VRFY_A)
{
- d=(unsigned char *)s->init_buf->data;
- p= &(d[4]);
- pkey=s->cert->key->privatekey;
-/* Create context from key and test if sha1 is allowed as digest */
- pctx = EVP_PKEY_CTX_new(pkey,NULL);
- EVP_PKEY_sign_init(pctx);
- if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1())>0)
- {
- if (TLS1_get_version(s) < TLS1_2_VERSION)
- s->method->ssl3_enc->cert_verify_mac(s,
- NID_sha1,
- &(data[MD5_DIGEST_LENGTH]));
- }
- else
- {
- ERR_clear_error();
- }
+ d = (unsigned char *)s->init_buf->data;
+ p = &(d[4]);
+ pkey = s->cert->key->privatekey;
/* For TLS v1.2 send signature algorithm and signature
* using agreed digest and cached handshake records.
*/
@@ -3060,14 +3057,15 @@ int ssl3_send_client_verify(SSL *s)
#endif
if (!EVP_SignInit_ex(&mctx, md, NULL)
|| !EVP_SignUpdate(&mctx, hdata, hdatalen)
- || !EVP_SignFinal(&mctx, p + 2, &u, pkey))
+ || !EVP_SignFinal(&mctx, p + 2,
+ &signature_length, pkey))
{
SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
ERR_R_EVP_LIB);
goto err;
}
- s2n(u,p);
- n = u + 4;
+ s2n(signature_length, p);
+ n = signature_length + 4;
if (!ssl3_digest_cached_records(s))
goto err;
}
@@ -3075,78 +3073,80 @@ int ssl3_send_client_verify(SSL *s)
#ifndef OPENSSL_NO_RSA
if (pkey->type == EVP_PKEY_RSA)
{
+ s->method->ssl3_enc->cert_verify_mac(s, NID_md5, data);
s->method->ssl3_enc->cert_verify_mac(s,
- NID_md5,
- &(data[0]));
+ NID_sha1, &(data[MD5_DIGEST_LENGTH]));
if (RSA_sign(NID_md5_sha1, data,
- MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
- &(p[2]), &u, pkey->pkey.rsa) <= 0 )
+ MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
+ &(p[2]), &signature_length, pkey->pkey.rsa) <= 0)
{
- SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB);
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_RSA_LIB);
goto err;
}
- s2n(u,p);
- n=u+2;
+ s2n(signature_length, p);
+ n = signature_length + 2;
}
else
#endif
#ifndef OPENSSL_NO_DSA
- if (pkey->type == EVP_PKEY_DSA)
+ if (pkey->type == EVP_PKEY_DSA)
{
- if (!DSA_sign(pkey->save_type,
- &(data[MD5_DIGEST_LENGTH]),
- SHA_DIGEST_LENGTH,&(p[2]),
- (unsigned int *)&j,pkey->pkey.dsa))
+ s->method->ssl3_enc->cert_verify_mac(s, NID_sha1, data);
+ if (!DSA_sign(pkey->save_type, data,
+ SHA_DIGEST_LENGTH, &(p[2]),
+ &signature_length, pkey->pkey.dsa))
{
- SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB);
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_DSA_LIB);
goto err;
}
- s2n(j,p);
- n=j+2;
+ s2n(signature_length, p);
+ n = signature_length + 2;
}
else
#endif
#ifndef OPENSSL_NO_ECDSA
- if (pkey->type == EVP_PKEY_EC)
+ if (pkey->type == EVP_PKEY_EC)
{
- if (!ECDSA_sign(pkey->save_type,
- &(data[MD5_DIGEST_LENGTH]),
- SHA_DIGEST_LENGTH,&(p[2]),
- (unsigned int *)&j,pkey->pkey.ec))
+ s->method->ssl3_enc->cert_verify_mac(s, NID_sha1, data);
+ if (!ECDSA_sign(pkey->save_type, data,
+ SHA_DIGEST_LENGTH, &(p[2]),
+ &signature_length, pkey->pkey.ec))
{
- SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
- ERR_R_ECDSA_LIB);
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_ECDSA_LIB);
goto err;
}
- s2n(j,p);
- n=j+2;
+ s2n(signature_length, p);
+ n = signature_length + 2;
}
else
#endif
if (pkey->type == NID_id_GostR3410_94 || pkey->type == NID_id_GostR3410_2001)
- {
- unsigned char signbuf[64];
- int i;
- size_t sigsize=64;
- s->method->ssl3_enc->cert_verify_mac(s,
- NID_id_GostR3411_94,
- data);
- if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) {
- SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
- for (i=63,j=0; i>=0; j++, i--) {
- p[2+j]=signbuf[i];
- }
- s2n(j,p);
- n=j+2;
- }
+ {
+ unsigned char signbuf[64];
+ int i, j;
+ size_t sigsize=64;
+
+ s->method->ssl3_enc->cert_verify_mac(s,
+ NID_id_GostR3411_94,
+ data);
+ pctx = EVP_PKEY_CTX_new(pkey, NULL);
+ EVP_PKEY_sign_init(pctx);
+ if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
+ ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ for (i=63,j=0; i>=0; j++, i--) {
+ p[2+j]=signbuf[i];
+ }
+ s2n(j,p);
+ n=j+2;
+ }
else
- {
+ {
SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR);
goto err;
- }
+ }
*(d++)=SSL3_MT_CERTIFICATE_VERIFY;
l2n3(n,d);
diff --git a/openssl/ssl/ssl.h b/openssl/ssl/ssl.h
index a3944f1..5faae95 100644
--- a/openssl/ssl/ssl.h
+++ b/openssl/ssl/ssl.h
@@ -547,6 +547,13 @@ struct ssl_session_st
#ifndef OPENSSL_NO_SRP
char *srp_username;
#endif
+
+ /* original_handshake_hash contains the handshake hash (either
+ * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
+ * handshake that created a session. This is used by Channel IDs during
+ * resumption. */
+ unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
+ unsigned int original_handshake_hash_len;
};
#endif
@@ -1982,6 +1989,9 @@ STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
int SSL_add_client_CA(SSL *ssl,X509 *x);
int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x);
+void SSL_get_client_certificate_types(const SSL *s, const unsigned char **ctype,
+ size_t *ctype_num);
+
void SSL_set_connect_state(SSL *s);
void SSL_set_accept_state(SSL *s);
diff --git a/openssl/ssl/ssl3.h b/openssl/ssl/ssl3.h
index 899c8a8..019e8d8 100644
--- a/openssl/ssl/ssl3.h
+++ b/openssl/ssl/ssl3.h
@@ -508,7 +508,7 @@ typedef struct ssl3_state_st
/* used for certificate requests */
int cert_req;
int ctype_num;
- char ctype[SSL3_CT_NUMBER];
+ unsigned char ctype[SSL3_CT_NUMBER];
STACK_OF(X509_NAME) *ca_names;
int use_rsa_tmp;
diff --git a/openssl/ssl/ssl_cert.c b/openssl/ssl/ssl_cert.c
index 5123a89..8a61650 100644
--- a/openssl/ssl/ssl_cert.c
+++ b/openssl/ssl/ssl_cert.c
@@ -655,6 +655,21 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x)
return(add_client_CA(&(ctx->client_CA),x));
}
+void SSL_get_client_certificate_types(const SSL *s, const unsigned char **ctype,
+ size_t *ctype_num)
+ {
+ if (s->s3 == NULL)
+ {
+ *ctype = NULL;
+ *ctype_num = 0;
+ return;
+ }
+
+ /* This always returns nothing for the server. */
+ *ctype = s->s3->tmp.ctype;
+ *ctype_num = s->s3->tmp.ctype_num;
+ }
+
static int xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
{
return(X509_NAME_cmp(*a,*b));
diff --git a/openssl/ssl/ssl_locl.h b/openssl/ssl/ssl_locl.h
index 531a291..c975d31 100644
--- a/openssl/ssl/ssl_locl.h
+++ b/openssl/ssl/ssl_locl.h
@@ -1102,6 +1102,7 @@ void ssl_free_wbio_buffer(SSL *s);
int tls1_change_cipher_state(SSL *s, int which);
int tls1_setup_key_block(SSL *s);
int tls1_enc(SSL *s, int snd);
+int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len);
int tls1_final_finish_mac(SSL *s,
const char *str, int slen, unsigned char *p);
int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
@@ -1158,6 +1159,7 @@ int tls12_get_sigid(const EVP_PKEY *pk);
const EVP_MD *tls12_get_hash(unsigned char hash_alg);
int tls1_channel_id_hash(EVP_MD_CTX *ctx, SSL *s);
+int tls1_record_handshake_hashes_for_channel_id(SSL *s);
#endif
int ssl3_can_cutthrough(const SSL *s);
diff --git a/openssl/ssl/t1_enc.c b/openssl/ssl/t1_enc.c
index 87b7021..d30ce61 100644
--- a/openssl/ssl/t1_enc.c
+++ b/openssl/ssl/t1_enc.c
@@ -1147,53 +1147,79 @@ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
return((int)ret);
}
+/* tls1_handshake_digest calculates the current handshake hash and writes it to
+ * |out|, which has space for |out_len| bytes. It returns the number of bytes
+ * written or -1 in the event of an error. This function works on a copy of the
+ * underlying digests so can be called multiple times and prior to the final
+ * update etc. */
+int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len)
+ {
+ const EVP_MD *md;
+ EVP_MD_CTX ctx;
+ int i, err = 0, len = 0;
+ long mask;
+
+ EVP_MD_CTX_init(&ctx);
+
+ for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++)
+ {
+ int hash_size;
+ unsigned int digest_len;
+ EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];
+
+ if ((mask & ssl_get_algorithm2(s)) == 0)
+ continue;
+
+ hash_size = EVP_MD_size(md);
+ if (!hdgst || hash_size < 0 || (size_t)hash_size > out_len)
+ {
+ err = 1;
+ break;
+ }
+
+ if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
+ !EVP_DigestFinal_ex(&ctx, out, &digest_len) ||
+ digest_len != (unsigned int)hash_size) /* internal error */
+ {
+ err = 1;
+ break;
+ }
+ out += digest_len;
+ out_len -= digest_len;
+ len += digest_len;
+ }
+
+ EVP_MD_CTX_cleanup(&ctx);
+
+ if (err != 0)
+ return -1;
+ return len;
+ }
+
int tls1_final_finish_mac(SSL *s,
const char *str, int slen, unsigned char *out)
{
- unsigned int i;
- EVP_MD_CTX ctx;
unsigned char buf[2*EVP_MAX_MD_SIZE];
- unsigned char *q,buf2[12];
- int idx;
- long mask;
+ unsigned char buf2[12];
int err=0;
- const EVP_MD *md;
+ int digests_len;
- q=buf;
-
- if (s->s3->handshake_buffer)
+ if (s->s3->handshake_buffer)
if (!ssl3_digest_cached_records(s))
return 0;
- EVP_MD_CTX_init(&ctx);
-
- for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
+ digests_len = tls1_handshake_digest(s, buf, sizeof(buf));
+ if (digests_len < 0)
{
- if (mask & ssl_get_algorithm2(s))
- {
- int hashsize = EVP_MD_size(md);
- if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
- {
- /* internal error: 'buf' is too small for this cipersuite! */
- err = 1;
- }
- else
- {
- EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
- EVP_DigestFinal_ex(&ctx,q,&i);
- if (i != (unsigned int)hashsize) /* can't really happen */
- err = 1;
- q+=i;
- }
- }
+ err = 1;
+ digests_len = 0;
}
-
+
if (!tls1_PRF(ssl_get_algorithm2(s),
- str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
+ str,slen, buf, digests_len, NULL,0, NULL,0, NULL,0,
s->session->master_key,s->session->master_key_length,
out,buf2,sizeof buf2))
err = 1;
- EVP_MD_CTX_cleanup(&ctx);
if (err)
return 0;
diff --git a/openssl/ssl/t1_lib.c b/openssl/ssl/t1_lib.c
index ea7fefa..d7ea9a5 100644
--- a/openssl/ssl/t1_lib.c
+++ b/openssl/ssl/t1_lib.c
@@ -2684,6 +2684,17 @@ tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
+ if (s->hit)
+ {
+ static const char kResumptionMagic[] = "Resumption";
+ EVP_DigestUpdate(md, kResumptionMagic,
+ sizeof(kResumptionMagic));
+ if (s->session->original_handshake_hash_len == 0)
+ return 0;
+ EVP_DigestUpdate(md, s->session->original_handshake_hash,
+ s->session->original_handshake_hash_len);
+ }
+
EVP_MD_CTX_init(&ctx);
for (i = 0; i < SSL_MAX_DIGEST; i++)
{
@@ -2698,3 +2709,29 @@ tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
return 1;
}
#endif
+
+/* tls1_record_handshake_hashes_for_channel_id records the current handshake
+ * hashes in |s->session| so that Channel ID resumptions can sign that data. */
+int tls1_record_handshake_hashes_for_channel_id(SSL *s)
+ {
+ int digest_len;
+ /* This function should never be called for a resumed session because
+ * the handshake hashes that we wish to record are for the original,
+ * full handshake. */
+ if (s->hit)
+ return -1;
+ /* It only makes sense to call this function if Channel IDs have been
+ * negotiated. */
+ if (!s->s3->tlsext_channel_id_valid)
+ return -1;
+
+ digest_len = tls1_handshake_digest(
+ s, s->session->original_handshake_hash,
+ sizeof(s->session->original_handshake_hash));
+ if (digest_len < 0)
+ return -1;
+
+ s->session->original_handshake_hash_len = digest_len;
+
+ return 1;
+ }
diff --git a/openssl/ssl/tls1.h b/openssl/ssl/tls1.h
index c4f69aa..5559486 100644
--- a/openssl/ssl/tls1.h
+++ b/openssl/ssl/tls1.h
@@ -255,7 +255,7 @@ extern "C" {
#endif
/* This is not an IANA defined extension number */
-#define TLSEXT_TYPE_channel_id 30031
+#define TLSEXT_TYPE_channel_id 30032
/* NameType value from RFC 3546 */
#define TLSEXT_NAMETYPE_host_name 0
diff --git a/patches.chromium/0014-new_channelid.patch b/patches.chromium/0014-new_channelid.patch
new file mode 100644
index 0000000..7f607d0
--- /dev/null
+++ b/patches.chromium/0014-new_channelid.patch
@@ -0,0 +1,537 @@
+diff -burN android-openssl.orig/include/openssl/ssl.h android-openssl/include/openssl/ssl.h
+--- android-openssl.orig/include/openssl/ssl.h 2014-05-05 16:45:02.685389339 +0200
++++ android-openssl/include/openssl/ssl.h 2014-05-05 16:46:32.513390565 +0200
+@@ -544,6 +544,13 @@
+ #ifndef OPENSSL_NO_SRP
+ char *srp_username;
+ #endif
++
++ /* original_handshake_hash contains the handshake hash (either
++ * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
++ * handshake that created a session. This is used by Channel IDs during
++ * resumption. */
++ unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
++ unsigned int original_handshake_hash_len;
+ };
+
+ #endif
+diff -burN android-openssl.orig/include/openssl/tls1.h android-openssl/include/openssl/tls1.h
+--- android-openssl.orig/include/openssl/tls1.h 2014-05-05 16:45:02.689389339 +0200
++++ android-openssl/include/openssl/tls1.h 2014-05-05 16:46:32.517390565 +0200
+@@ -249,7 +249,7 @@
+ #endif
+
+ /* This is not an IANA defined extension number */
+-#define TLSEXT_TYPE_channel_id 30031
++#define TLSEXT_TYPE_channel_id 30032
+
+ /* NameType value from RFC 3546 */
+ #define TLSEXT_NAMETYPE_host_name 0
+diff -burN android-openssl.orig/patches/new_channelid.patch android-openssl/patches/new_channelid.patch
+--- android-openssl.orig/patches/new_channelid.patch 1970-01-01 01:00:00.000000000 +0100
++++ android-openssl/patches/new_channelid.patch 2014-05-05 16:48:54.429392502 +0200
+@@ -0,0 +1,273 @@
++diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
++index a3944f1..fe92ccf 100644
++--- a/include/openssl/ssl.h
+++++ b/include/openssl/ssl.h
++@@ -547,6 +547,13 @@ struct ssl_session_st
++ #ifndef OPENSSL_NO_SRP
++ char *srp_username;
++ #endif
+++
+++ /* original_handshake_hash contains the handshake hash (either
+++ * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
+++ * handshake that created a session. This is used by Channel IDs during
+++ * resumption. */
+++ unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
+++ unsigned int original_handshake_hash_len;
++ };
++
++ #endif
++diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
++index c4f69aa..5559486 100644
++--- a/include/openssl/tls1.h
+++++ b/include/openssl/tls1.h
++@@ -255,7 +255,7 @@ extern "C" {
++ #endif
++
++ /* This is not an IANA defined extension number */
++-#define TLSEXT_TYPE_channel_id 30031
+++#define TLSEXT_TYPE_channel_id 30032
++
++ /* NameType value from RFC 3546 */
++ #define TLSEXT_NAMETYPE_host_name 0
++diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
++index 640df80..d6154c5 100644
++--- a/ssl/s3_clnt.c
+++++ b/ssl/s3_clnt.c
++@@ -583,6 +583,18 @@ int ssl3_connect(SSL *s)
++ #endif
++ s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
++ }
+++ if (s->s3->tlsext_channel_id_valid)
+++ {
+++ /* This is a non-resumption handshake. If it
+++ * involves ChannelID, then record the
+++ * handshake hashes at this point in the
+++ * session so that any resumption of this
+++ * session with ChannelID can sign those
+++ * hashes. */
+++ ret = tls1_record_handshake_hashes_for_channel_id(s);
+++ if (ret <= 0)
+++ goto end;
+++ }
++ }
++ s->init_num=0;
++ break;
++diff --git a/ssl/ssl.h b/ssl/ssl.h
++index a3944f1..fe92ccf 100644
++--- a/ssl/ssl.h
+++++ b/ssl/ssl.h
++@@ -547,6 +547,13 @@ struct ssl_session_st
++ #ifndef OPENSSL_NO_SRP
++ char *srp_username;
++ #endif
+++
+++ /* original_handshake_hash contains the handshake hash (either
+++ * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
+++ * handshake that created a session. This is used by Channel IDs during
+++ * resumption. */
+++ unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
+++ unsigned int original_handshake_hash_len;
++ };
++
++ #endif
++diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
++index 531a291..c975d31 100644
++--- a/ssl/ssl_locl.h
+++++ b/ssl/ssl_locl.h
++@@ -1102,6 +1102,7 @@ void ssl_free_wbio_buffer(SSL *s);
++ int tls1_change_cipher_state(SSL *s, int which);
++ int tls1_setup_key_block(SSL *s);
++ int tls1_enc(SSL *s, int snd);
+++int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len);
++ int tls1_final_finish_mac(SSL *s,
++ const char *str, int slen, unsigned char *p);
++ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
++@@ -1158,6 +1159,7 @@ int tls12_get_sigid(const EVP_PKEY *pk);
++ const EVP_MD *tls12_get_hash(unsigned char hash_alg);
++
++ int tls1_channel_id_hash(EVP_MD_CTX *ctx, SSL *s);
+++int tls1_record_handshake_hashes_for_channel_id(SSL *s);
++ #endif
++
++ int ssl3_can_cutthrough(const SSL *s);
++diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
++index 87b7021..d30ce61 100644
++--- a/ssl/t1_enc.c
+++++ b/ssl/t1_enc.c
++@@ -1147,53 +1147,79 @@ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
++ return((int)ret);
++ }
++
+++/* tls1_handshake_digest calculates the current handshake hash and writes it to
+++ * |out|, which has space for |out_len| bytes. It returns the number of bytes
+++ * written or -1 in the event of an error. This function works on a copy of the
+++ * underlying digests so can be called multiple times and prior to the final
+++ * update etc. */
+++int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len)
+++ {
+++ const EVP_MD *md;
+++ EVP_MD_CTX ctx;
+++ int i, err = 0, len = 0;
+++ long mask;
+++
+++ EVP_MD_CTX_init(&ctx);
+++
+++ for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++)
+++ {
+++ int hash_size;
+++ unsigned int digest_len;
+++ EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];
+++
+++ if ((mask & ssl_get_algorithm2(s)) == 0)
+++ continue;
+++
+++ hash_size = EVP_MD_size(md);
+++ if (!hdgst || hash_size < 0 || (size_t)hash_size > out_len)
+++ {
+++ err = 1;
+++ break;
+++ }
+++
+++ if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
+++ !EVP_DigestFinal_ex(&ctx, out, &digest_len) ||
+++ digest_len != (unsigned int)hash_size) /* internal error */
+++ {
+++ err = 1;
+++ break;
+++ }
+++ out += digest_len;
+++ out_len -= digest_len;
+++ len += digest_len;
+++ }
+++
+++ EVP_MD_CTX_cleanup(&ctx);
+++
+++ if (err != 0)
+++ return -1;
+++ return len;
+++ }
+++
++ int tls1_final_finish_mac(SSL *s,
++ const char *str, int slen, unsigned char *out)
++ {
++- unsigned int i;
++- EVP_MD_CTX ctx;
++ unsigned char buf[2*EVP_MAX_MD_SIZE];
++- unsigned char *q,buf2[12];
++- int idx;
++- long mask;
+++ unsigned char buf2[12];
++ int err=0;
++- const EVP_MD *md;
+++ int digests_len;
++
++- q=buf;
++-
++- if (s->s3->handshake_buffer)
+++ if (s->s3->handshake_buffer)
++ if (!ssl3_digest_cached_records(s))
++ return 0;
++
++- EVP_MD_CTX_init(&ctx);
++-
++- for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
+++ digests_len = tls1_handshake_digest(s, buf, sizeof(buf));
+++ if (digests_len < 0)
++ {
++- if (mask & ssl_get_algorithm2(s))
++- {
++- int hashsize = EVP_MD_size(md);
++- if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
++- {
++- /* internal error: 'buf' is too small for this cipersuite! */
++- err = 1;
++- }
++- else
++- {
++- EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
++- EVP_DigestFinal_ex(&ctx,q,&i);
++- if (i != (unsigned int)hashsize) /* can't really happen */
++- err = 1;
++- q+=i;
++- }
++- }
+++ err = 1;
+++ digests_len = 0;
++ }
++-
+++
++ if (!tls1_PRF(ssl_get_algorithm2(s),
++- str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
+++ str,slen, buf, digests_len, NULL,0, NULL,0, NULL,0,
++ s->session->master_key,s->session->master_key_length,
++ out,buf2,sizeof buf2))
++ err = 1;
++- EVP_MD_CTX_cleanup(&ctx);
++
++ if (err)
++ return 0;
++diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
++index ea7fefa..d7ea9a5 100644
++--- a/ssl/t1_lib.c
+++++ b/ssl/t1_lib.c
++@@ -2684,6 +2684,17 @@ tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
++
++ EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
++
+++ if (s->hit)
+++ {
+++ static const char kResumptionMagic[] = "Resumption";
+++ EVP_DigestUpdate(md, kResumptionMagic,
+++ sizeof(kResumptionMagic));
+++ if (s->session->original_handshake_hash_len == 0)
+++ return 0;
+++ EVP_DigestUpdate(md, s->session->original_handshake_hash,
+++ s->session->original_handshake_hash_len);
+++ }
+++
++ EVP_MD_CTX_init(&ctx);
++ for (i = 0; i < SSL_MAX_DIGEST; i++)
++ {
++@@ -2698,3 +2709,29 @@ tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
++ return 1;
++ }
++ #endif
+++
+++/* tls1_record_handshake_hashes_for_channel_id records the current handshake
+++ * hashes in |s->session| so that Channel ID resumptions can sign that data. */
+++int tls1_record_handshake_hashes_for_channel_id(SSL *s)
+++ {
+++ int digest_len;
+++ /* This function should never be called for a resumed session because
+++ * the handshake hashes that we wish to record are for the original,
+++ * full handshake. */
+++ if (s->hit)
+++ return -1;
+++ /* It only makes sense to call this function if Channel IDs have been
+++ * negotiated. */
+++ if (!s->s3->tlsext_channel_id_valid)
+++ return -1;
+++
+++ digest_len = tls1_handshake_digest(
+++ s, s->session->original_handshake_hash,
+++ sizeof(s->session->original_handshake_hash));
+++ if (digest_len < 0)
+++ return -1;
+++
+++ s->session->original_handshake_hash_len = digest_len;
+++
+++ return 1;
+++ }
++diff --git a/ssl/tls1.h b/ssl/tls1.h
++index c4f69aa..5559486 100644
++--- a/ssl/tls1.h
+++++ b/ssl/tls1.h
++@@ -255,7 +255,7 @@ extern "C" {
++ #endif
++
++ /* This is not an IANA defined extension number */
++-#define TLSEXT_TYPE_channel_id 30031
+++#define TLSEXT_TYPE_channel_id 30032
++
++ /* NameType value from RFC 3546 */
++ #define TLSEXT_NAMETYPE_host_name 0
+diff -burN android-openssl.orig/ssl/s3_clnt.c android-openssl/ssl/s3_clnt.c
+--- android-openssl.orig/ssl/s3_clnt.c 2014-05-05 16:45:02.785389340 +0200
++++ android-openssl/ssl/s3_clnt.c 2014-05-05 16:46:32.525390565 +0200
+@@ -583,6 +583,18 @@
+ #endif
+ s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
+ }
++ if (s->s3->tlsext_channel_id_valid)
++ {
++ /* This is a non-resumption handshake. If it
++ * involves ChannelID, then record the
++ * handshake hashes at this point in the
++ * session so that any resumption of this
++ * session with ChannelID can sign those
++ * hashes. */
++ ret = tls1_record_handshake_hashes_for_channel_id(s);
++ if (ret <= 0)
++ goto end;
++ }
+ }
+ s->init_num=0;
+ break;
+diff -burN android-openssl.orig/ssl/ssl.h android-openssl/ssl/ssl.h
+--- android-openssl.orig/ssl/ssl.h 2014-05-05 16:45:02.693389339 +0200
++++ android-openssl/ssl/ssl.h 2014-05-05 16:46:32.533390565 +0200
+@@ -544,6 +544,13 @@
+ #ifndef OPENSSL_NO_SRP
+ char *srp_username;
+ #endif
++
++ /* original_handshake_hash contains the handshake hash (either
++ * SHA-1+MD5 or SHA-2, depending on TLS version) for the original, full
++ * handshake that created a session. This is used by Channel IDs during
++ * resumption. */
++ unsigned char original_handshake_hash[EVP_MAX_MD_SIZE];
++ unsigned int original_handshake_hash_len;
+ };
+
+ #endif
+diff -burN android-openssl.orig/ssl/ssl_locl.h android-openssl/ssl/ssl_locl.h
+--- android-openssl.orig/ssl/ssl_locl.h 2014-05-05 16:45:02.785389340 +0200
++++ android-openssl/ssl/ssl_locl.h 2014-05-05 16:46:32.541390565 +0200
+@@ -1071,6 +1071,7 @@
+ int tls1_change_cipher_state(SSL *s, int which);
+ int tls1_setup_key_block(SSL *s);
+ int tls1_enc(SSL *s, int snd);
++int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len);
+ int tls1_final_finish_mac(SSL *s,
+ const char *str, int slen, unsigned char *p);
+ int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
+@@ -1127,6 +1128,7 @@
+ const EVP_MD *tls12_get_hash(unsigned char hash_alg);
+
+ int tls1_channel_id_hash(EVP_MD_CTX *ctx, SSL *s);
++int tls1_record_handshake_hashes_for_channel_id(SSL *s);
+ #endif
+
+ int ssl3_can_cutthrough(const SSL *s);
+diff -burN android-openssl.orig/ssl/t1_enc.c android-openssl/ssl/t1_enc.c
+--- android-openssl.orig/ssl/t1_enc.c 2014-05-05 16:45:02.697389339 +0200
++++ android-openssl/ssl/t1_enc.c 2014-05-05 16:46:32.545390565 +0200
+@@ -890,53 +890,79 @@
+ return((int)ret);
+ }
+
+-int tls1_final_finish_mac(SSL *s,
+- const char *str, int slen, unsigned char *out)
++/* tls1_handshake_digest calculates the current handshake hash and writes it to
++ * |out|, which has space for |out_len| bytes. It returns the number of bytes
++ * written or -1 in the event of an error. This function works on a copy of the
++ * underlying digests so can be called multiple times and prior to the final
++ * update etc. */
++int tls1_handshake_digest(SSL *s, unsigned char *out, size_t out_len)
+ {
+- unsigned int i;
++ const EVP_MD *md;
+ EVP_MD_CTX ctx;
+- unsigned char buf[2*EVP_MAX_MD_SIZE];
+- unsigned char *q,buf2[12];
+- int idx;
++ int i, err = 0, len = 0;
+ long mask;
+- int err=0;
+- const EVP_MD *md;
+-
+- q=buf;
+-
+- if (s->s3->handshake_buffer)
+- if (!ssl3_digest_cached_records(s))
+- return 0;
+
+ EVP_MD_CTX_init(&ctx);
+
+- for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
++ for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++)
+ {
+- if (mask & ssl_get_algorithm2(s))
+- {
+- int hashsize = EVP_MD_size(md);
+- if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
++ int hash_size;
++ unsigned int digest_len;
++ EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];
++
++ if ((mask & ssl_get_algorithm2(s)) == 0)
++ continue;
++
++ hash_size = EVP_MD_size(md);
++ if (!hdgst || hash_size < 0 || (size_t)hash_size > out_len)
+ {
+- /* internal error: 'buf' is too small for this cipersuite! */
+ err = 1;
++ break;
+ }
+- else
++
++ if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
++ !EVP_DigestFinal_ex(&ctx, out, &digest_len) ||
++ digest_len != (unsigned int)hash_size) /* internal error */
+ {
+- EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
+- EVP_DigestFinal_ex(&ctx,q,&i);
+- if (i != (unsigned int)hashsize) /* can't really happen */
+ err = 1;
+- q+=i;
++ break;
+ }
++ out += digest_len;
++ out_len -= digest_len;
++ len += digest_len;
+ }
++
++ EVP_MD_CTX_cleanup(&ctx);
++
++ if (err != 0)
++ return -1;
++ return len;
++ }
++
++int tls1_final_finish_mac(SSL *s,
++ const char *str, int slen, unsigned char *out)
++ {
++ unsigned char buf[2*EVP_MAX_MD_SIZE];
++ unsigned char buf2[12];
++ int err=0;
++ int digests_len;
++
++ if (s->s3->handshake_buffer)
++ if (!ssl3_digest_cached_records(s))
++ return 0;
++
++ digests_len = tls1_handshake_digest(s, buf, sizeof(buf));
++ if (digests_len < 0)
++ {
++ err = 1;
++ digests_len = 0;
+ }
+
+ if (!tls1_PRF(ssl_get_algorithm2(s),
+- str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
++ str,slen, buf, digests_len, NULL,0, NULL,0, NULL,0,
+ s->session->master_key,s->session->master_key_length,
+ out,buf2,sizeof buf2))
+ err = 1;
+- EVP_MD_CTX_cleanup(&ctx);
+
+ if (err)
+ return 0;
+diff -burN android-openssl.orig/ssl/t1_lib.c android-openssl/ssl/t1_lib.c
+--- android-openssl.orig/ssl/t1_lib.c 2014-05-05 16:45:02.789389340 +0200
++++ android-openssl/ssl/t1_lib.c 2014-05-05 16:46:32.549390565 +0200
+@@ -2672,6 +2672,17 @@
+
+ EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
+
++ if (s->hit)
++ {
++ static const char kResumptionMagic[] = "Resumption";
++ EVP_DigestUpdate(md, kResumptionMagic,
++ sizeof(kResumptionMagic));
++ if (s->session->original_handshake_hash_len == 0)
++ return 0;
++ EVP_DigestUpdate(md, s->session->original_handshake_hash,
++ s->session->original_handshake_hash_len);
++ }
++
+ EVP_MD_CTX_init(&ctx);
+ for (i = 0; i < SSL_MAX_DIGEST; i++)
+ {
+@@ -2686,3 +2697,29 @@
+ return 1;
+ }
+ #endif
++
++/* tls1_record_handshake_hashes_for_channel_id records the current handshake
++ * hashes in |s->session| so that Channel ID resumptions can sign that data. */
++int tls1_record_handshake_hashes_for_channel_id(SSL *s)
++ {
++ int digest_len;
++ /* This function should never be called for a resumed session because
++ * the handshake hashes that we wish to record are for the original,
++ * full handshake. */
++ if (s->hit)
++ return -1;
++ /* It only makes sense to call this function if Channel IDs have been
++ * negotiated. */
++ if (!s->s3->tlsext_channel_id_valid)
++ return -1;
++
++ digest_len = tls1_handshake_digest(
++ s, s->session->original_handshake_hash,
++ sizeof(s->session->original_handshake_hash));
++ if (digest_len < 0)
++ return -1;
++
++ s->session->original_handshake_hash_len = digest_len;
++
++ return 1;
++ }
+diff -burN android-openssl.orig/ssl/tls1.h android-openssl/ssl/tls1.h
+--- android-openssl.orig/ssl/tls1.h 2014-05-05 16:45:02.697389339 +0200
++++ android-openssl/ssl/tls1.h 2014-05-05 16:46:32.553390566 +0200
+@@ -249,7 +249,7 @@
+ #endif
+
+ /* This is not an IANA defined extension number */
+-#define TLSEXT_TYPE_channel_id 30031
++#define TLSEXT_TYPE_channel_id 30032
+
+ /* NameType value from RFC 3546 */
+ #define TLSEXT_NAMETYPE_host_name 0
diff --git a/patches.chromium/0015-export_certificate_types.patch b/patches.chromium/0015-export_certificate_types.patch
new file mode 100644
index 0000000..e5c7f76
--- /dev/null
+++ b/patches.chromium/0015-export_certificate_types.patch
@@ -0,0 +1,80 @@
+diff --git android-openssl.orig/include/openssl/ssl.h android-openssl/include/openssl/ssl.h
+index a3944f1..e559608 100644
+--- android-openssl.orig/include/openssl/ssl.h
++++ android-openssl/include/openssl/ssl.h
+@@ -1982,6 +1982,9 @@ STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
+ int SSL_add_client_CA(SSL *ssl,X509 *x);
+ int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x);
+
++void SSL_get_client_certificate_types(const SSL *s, const unsigned char **ctype,
++ size_t *ctype_num);
++
+ void SSL_set_connect_state(SSL *s);
+ void SSL_set_accept_state(SSL *s);
+
+diff --git android-openssl.orig/include/openssl/ssl3.h android-openssl/include/openssl/ssl3.h
+index 899c8a8..019e8d8 100644
+--- android-openssl.orig/include/openssl/ssl3.h
++++ android-openssl/include/openssl/ssl3.h
+@@ -508,7 +508,7 @@ typedef struct ssl3_state_st
+ /* used for certificate requests */
+ int cert_req;
+ int ctype_num;
+- char ctype[SSL3_CT_NUMBER];
++ unsigned char ctype[SSL3_CT_NUMBER];
+ STACK_OF(X509_NAME) *ca_names;
+
+ int use_rsa_tmp;
+diff --git android-openssl.orig/ssl/ssl.h android-openssl/ssl/ssl.h
+index a3944f1..e559608 100644
+--- android-openssl.orig/ssl/ssl.h
++++ android-openssl/ssl/ssl.h
+@@ -1982,6 +1982,9 @@ STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
+ int SSL_add_client_CA(SSL *ssl,X509 *x);
+ int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x);
+
++void SSL_get_client_certificate_types(const SSL *s, const unsigned char **ctype,
++ size_t *ctype_num);
++
+ void SSL_set_connect_state(SSL *s);
+ void SSL_set_accept_state(SSL *s);
+
+diff --git android-openssl.orig/ssl/ssl3.h android-openssl/ssl/ssl3.h
+index 899c8a8..019e8d8 100644
+--- android-openssl.orig/ssl/ssl3.h
++++ android-openssl/ssl/ssl3.h
+@@ -508,7 +508,7 @@ typedef struct ssl3_state_st
+ /* used for certificate requests */
+ int cert_req;
+ int ctype_num;
+- char ctype[SSL3_CT_NUMBER];
++ unsigned char ctype[SSL3_CT_NUMBER];
+ STACK_OF(X509_NAME) *ca_names;
+
+ int use_rsa_tmp;
+diff --git android-openssl.orig/ssl/ssl_cert.c android-openssl/ssl/ssl_cert.c
+index 5123a89..8a61650 100644
+--- android-openssl.orig/ssl/ssl_cert.c
++++ android-openssl/ssl/ssl_cert.c
+@@ -655,6 +655,21 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x)
+ return(add_client_CA(&(ctx->client_CA),x));
+ }
+
++void SSL_get_client_certificate_types(const SSL *s, const unsigned char **ctype,
++ size_t *ctype_num)
++ {
++ if (s->s3 == NULL)
++ {
++ *ctype = NULL;
++ *ctype_num = 0;
++ return;
++ }
++
++ /* This always returns nothing for the server. */
++ *ctype = s->s3->tmp.ctype;
++ *ctype_num = s->s3->tmp.ctype_num;
++ }
++
+ static int xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
+ {
+ return(X509_NAME_cmp(*a,*b));
diff --git a/patches.chromium/0016-send_client_verify_cleanup.patch b/patches.chromium/0016-send_client_verify_cleanup.patch
new file mode 100644
index 0000000..6f728ed
--- /dev/null
+++ b/patches.chromium/0016-send_client_verify_cleanup.patch
@@ -0,0 +1,187 @@
+diff --git android-openssl.orig/ssl/s3_clnt.c android-openssl/ssl/s3_clnt.c
+index d6154c5..2b094c9 100644
+--- android-openssl.orig/ssl/s3_clnt.c
++++ android-openssl/ssl/s3_clnt.c
+@@ -3022,33 +3022,18 @@ int ssl3_send_client_verify(SSL *s)
+ unsigned char *p,*d;
+ unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
+ EVP_PKEY *pkey;
+- EVP_PKEY_CTX *pctx=NULL;
++ EVP_PKEY_CTX *pctx = NULL;
+ EVP_MD_CTX mctx;
+- unsigned u=0;
++ unsigned signature_length = 0;
+ unsigned long n;
+- int j;
+
+ EVP_MD_CTX_init(&mctx);
+
+ if (s->state == SSL3_ST_CW_CERT_VRFY_A)
+ {
+- d=(unsigned char *)s->init_buf->data;
+- p= &(d[4]);
+- pkey=s->cert->key->privatekey;
+-/* Create context from key and test if sha1 is allowed as digest */
+- pctx = EVP_PKEY_CTX_new(pkey,NULL);
+- EVP_PKEY_sign_init(pctx);
+- if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1())>0)
+- {
+- if (TLS1_get_version(s) < TLS1_2_VERSION)
+- s->method->ssl3_enc->cert_verify_mac(s,
+- NID_sha1,
+- &(data[MD5_DIGEST_LENGTH]));
+- }
+- else
+- {
+- ERR_clear_error();
+- }
++ d = (unsigned char *)s->init_buf->data;
++ p = &(d[4]);
++ pkey = s->cert->key->privatekey;
+ /* For TLS v1.2 send signature algorithm and signature
+ * using agreed digest and cached handshake records.
+ */
+@@ -3072,14 +3057,15 @@ int ssl3_send_client_verify(SSL *s)
+ #endif
+ if (!EVP_SignInit_ex(&mctx, md, NULL)
+ || !EVP_SignUpdate(&mctx, hdata, hdatalen)
+- || !EVP_SignFinal(&mctx, p + 2, &u, pkey))
++ || !EVP_SignFinal(&mctx, p + 2,
++ &signature_length, pkey))
+ {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
+ ERR_R_EVP_LIB);
+ goto err;
+ }
+- s2n(u,p);
+- n = u + 4;
++ s2n(signature_length, p);
++ n = signature_length + 4;
+ if (!ssl3_digest_cached_records(s))
+ goto err;
+ }
+@@ -3087,78 +3073,80 @@ int ssl3_send_client_verify(SSL *s)
+ #ifndef OPENSSL_NO_RSA
+ if (pkey->type == EVP_PKEY_RSA)
+ {
++ s->method->ssl3_enc->cert_verify_mac(s, NID_md5, data);
+ s->method->ssl3_enc->cert_verify_mac(s,
+- NID_md5,
+- &(data[0]));
++ NID_sha1, &(data[MD5_DIGEST_LENGTH]));
+ if (RSA_sign(NID_md5_sha1, data,
+- MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
+- &(p[2]), &u, pkey->pkey.rsa) <= 0 )
++ MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
++ &(p[2]), &signature_length, pkey->pkey.rsa) <= 0)
+ {
+- SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB);
++ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_RSA_LIB);
+ goto err;
+ }
+- s2n(u,p);
+- n=u+2;
++ s2n(signature_length, p);
++ n = signature_length + 2;
+ }
+ else
+ #endif
+ #ifndef OPENSSL_NO_DSA
+- if (pkey->type == EVP_PKEY_DSA)
++ if (pkey->type == EVP_PKEY_DSA)
+ {
+- if (!DSA_sign(pkey->save_type,
+- &(data[MD5_DIGEST_LENGTH]),
+- SHA_DIGEST_LENGTH,&(p[2]),
+- (unsigned int *)&j,pkey->pkey.dsa))
++ s->method->ssl3_enc->cert_verify_mac(s, NID_sha1, data);
++ if (!DSA_sign(pkey->save_type, data,
++ SHA_DIGEST_LENGTH, &(p[2]),
++ &signature_length, pkey->pkey.dsa))
+ {
+- SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB);
++ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_DSA_LIB);
+ goto err;
+ }
+- s2n(j,p);
+- n=j+2;
++ s2n(signature_length, p);
++ n = signature_length + 2;
+ }
+ else
+ #endif
+ #ifndef OPENSSL_NO_ECDSA
+- if (pkey->type == EVP_PKEY_EC)
++ if (pkey->type == EVP_PKEY_EC)
+ {
+- if (!ECDSA_sign(pkey->save_type,
+- &(data[MD5_DIGEST_LENGTH]),
+- SHA_DIGEST_LENGTH,&(p[2]),
+- (unsigned int *)&j,pkey->pkey.ec))
++ s->method->ssl3_enc->cert_verify_mac(s, NID_sha1, data);
++ if (!ECDSA_sign(pkey->save_type, data,
++ SHA_DIGEST_LENGTH, &(p[2]),
++ &signature_length, pkey->pkey.ec))
+ {
+- SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
+- ERR_R_ECDSA_LIB);
++ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_ECDSA_LIB);
+ goto err;
+ }
+- s2n(j,p);
+- n=j+2;
++ s2n(signature_length, p);
++ n = signature_length + 2;
+ }
+ else
+ #endif
+ if (pkey->type == NID_id_GostR3410_94 || pkey->type == NID_id_GostR3410_2001)
+- {
+- unsigned char signbuf[64];
+- int i;
+- size_t sigsize=64;
+- s->method->ssl3_enc->cert_verify_mac(s,
+- NID_id_GostR3411_94,
+- data);
+- if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) {
+- SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
+- ERR_R_INTERNAL_ERROR);
+- goto err;
+- }
+- for (i=63,j=0; i>=0; j++, i--) {
+- p[2+j]=signbuf[i];
+- }
+- s2n(j,p);
+- n=j+2;
+- }
++ {
++ unsigned char signbuf[64];
++ int i, j;
++ size_t sigsize=64;
++
++ s->method->ssl3_enc->cert_verify_mac(s,
++ NID_id_GostR3411_94,
++ data);
++ pctx = EVP_PKEY_CTX_new(pkey, NULL);
++ EVP_PKEY_sign_init(pctx);
++ if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) {
++ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,
++ ERR_R_INTERNAL_ERROR);
++ goto err;
++ }
++ for (i=63,j=0; i>=0; j++, i--) {
++ p[2+j]=signbuf[i];
++ }
++ s2n(j,p);
++ n=j+2;
++ }
+ else
+- {
++ {
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR);
+ goto err;
+- }
++ }
+ *(d++)=SSL3_MT_CERTIFICATE_VERIFY;
+ l2n3(n,d);
+