diff options
-rw-r--r-- | openssl/include/openssl/ssl.h | 7 | ||||
-rw-r--r-- | openssl/include/openssl/tls1.h | 2 | ||||
-rw-r--r-- | openssl/patches/new_channelid.patch | 273 | ||||
-rw-r--r-- | openssl/ssl/s3_clnt.c | 12 | ||||
-rw-r--r-- | openssl/ssl/ssl.h | 7 | ||||
-rw-r--r-- | openssl/ssl/ssl_locl.h | 2 | ||||
-rw-r--r-- | openssl/ssl/t1_enc.c | 90 | ||||
-rw-r--r-- | openssl/ssl/t1_lib.c | 37 | ||||
-rw-r--r-- | openssl/ssl/tls1.h | 2 | ||||
-rw-r--r-- | patches.chromium/0014-new_channelid.patch | 537 |
10 files changed, 34 insertions, 935 deletions
diff --git a/openssl/include/openssl/ssl.h b/openssl/include/openssl/ssl.h index fe92ccf..a3944f1 100644 --- a/openssl/include/openssl/ssl.h +++ b/openssl/include/openssl/ssl.h @@ -547,13 +547,6 @@ 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/openssl/include/openssl/tls1.h b/openssl/include/openssl/tls1.h index 5559486..c4f69aa 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 30032 +#define TLSEXT_TYPE_channel_id 30031 /* 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 deleted file mode 100644 index 22a8fdd..0000000 --- a/openssl/patches/new_channelid.patch +++ /dev/null @@ -1,273 +0,0 @@ -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 d6154c5..640df80 100644 --- a/openssl/ssl/s3_clnt.c +++ b/openssl/ssl/s3_clnt.c @@ -583,18 +583,6 @@ 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/openssl/ssl/ssl.h b/openssl/ssl/ssl.h index fe92ccf..a3944f1 100644 --- a/openssl/ssl/ssl.h +++ b/openssl/ssl/ssl.h @@ -547,13 +547,6 @@ 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/openssl/ssl/ssl_locl.h b/openssl/ssl/ssl_locl.h index c975d31..531a291 100644 --- a/openssl/ssl/ssl_locl.h +++ b/openssl/ssl/ssl_locl.h @@ -1102,7 +1102,6 @@ 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); @@ -1159,7 +1158,6 @@ 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 d30ce61..87b7021 100644 --- a/openssl/ssl/t1_enc.c +++ b/openssl/ssl/t1_enc.c @@ -1147,79 +1147,53 @@ 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 buf2[12]; + unsigned char *q,buf2[12]; + int idx; + long mask; int err=0; - int digests_len; + const EVP_MD *md; - if (s->s3->handshake_buffer) + q=buf; + + 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) + EVP_MD_CTX_init(&ctx); + + for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++) { - err = 1; - 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; + } + } } - + if (!tls1_PRF(ssl_get_algorithm2(s), - str,slen, buf, digests_len, NULL,0, NULL,0, NULL,0, + str,slen, buf,(int)(q-buf), 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 d7ea9a5..ea7fefa 100644 --- a/openssl/ssl/t1_lib.c +++ b/openssl/ssl/t1_lib.c @@ -2684,17 +2684,6 @@ 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++) { @@ -2709,29 +2698,3 @@ 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 5559486..c4f69aa 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 30032 +#define TLSEXT_TYPE_channel_id 30031 /* 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 deleted file mode 100644 index 7f607d0..0000000 --- a/patches.chromium/0014-new_channelid.patch +++ /dev/null @@ -1,537 +0,0 @@ -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 |