am 0df67453: am bcc7c845: Merge changes I9abd00af,Id0e75f71
* commit '0df67453b84d23b381e07e0d9c0d121b011ed0d2':
Upgrade to OpenSSL 1.0.1h
Use numbering for patch orders
diff --git a/Apps-config-host.mk b/Apps-config-host.mk
index 37dcb78..5c1604e 100644
--- a/Apps-config-host.mk
+++ b/Apps-config-host.mk
@@ -1,6 +1,6 @@
# Auto-generated - DO NOT EDIT!
# To regenerate, edit openssl.config, then run:
-# ./import_openssl.sh import /path/to/openssl-1.0.1g.tar.gz
+# ./import_openssl.sh import /path/to/openssl-1.0.1h.tar.gz
#
# This script will append to the following variables:
#
diff --git a/Apps-config-target.mk b/Apps-config-target.mk
index bccd250..0c567d4 100644
--- a/Apps-config-target.mk
+++ b/Apps-config-target.mk
@@ -1,6 +1,6 @@
# Auto-generated - DO NOT EDIT!
# To regenerate, edit openssl.config, then run:
-# ./import_openssl.sh import /path/to/openssl-1.0.1g.tar.gz
+# ./import_openssl.sh import /path/to/openssl-1.0.1h.tar.gz
#
# This script will append to the following variables:
#
diff --git a/Crypto-config-host.mk b/Crypto-config-host.mk
index a377fec..988df04 100644
--- a/Crypto-config-host.mk
+++ b/Crypto-config-host.mk
@@ -1,6 +1,6 @@
# Auto-generated - DO NOT EDIT!
# To regenerate, edit openssl.config, then run:
-# ./import_openssl.sh import /path/to/openssl-1.0.1g.tar.gz
+# ./import_openssl.sh import /path/to/openssl-1.0.1h.tar.gz
#
# This script will append to the following variables:
#
diff --git a/Crypto-config-target.mk b/Crypto-config-target.mk
index 919b5ac..ac459d1 100644
--- a/Crypto-config-target.mk
+++ b/Crypto-config-target.mk
@@ -1,6 +1,6 @@
# Auto-generated - DO NOT EDIT!
# To regenerate, edit openssl.config, then run:
-# ./import_openssl.sh import /path/to/openssl-1.0.1g.tar.gz
+# ./import_openssl.sh import /path/to/openssl-1.0.1h.tar.gz
#
# This script will append to the following variables:
#
diff --git a/Crypto-config-trusty.mk b/Crypto-config-trusty.mk
index dc5b12c..5991598 100644
--- a/Crypto-config-trusty.mk
+++ b/Crypto-config-trusty.mk
@@ -1,6 +1,6 @@
# Auto-generated - DO NOT EDIT!
# To regenerate, edit openssl.config, then run:
-# ./import_openssl.sh import /path/to/openssl-1.0.1g.tar.gz
+# ./import_openssl.sh import /path/to/openssl-1.0.1h.tar.gz
#
# This script will append to the following variables:
#
diff --git a/Ssl-config-host.mk b/Ssl-config-host.mk
index 9503548..57ea377 100644
--- a/Ssl-config-host.mk
+++ b/Ssl-config-host.mk
@@ -1,6 +1,6 @@
# Auto-generated - DO NOT EDIT!
# To regenerate, edit openssl.config, then run:
-# ./import_openssl.sh import /path/to/openssl-1.0.1g.tar.gz
+# ./import_openssl.sh import /path/to/openssl-1.0.1h.tar.gz
#
# This script will append to the following variables:
#
diff --git a/Ssl-config-target.mk b/Ssl-config-target.mk
index 2de5a58..b39e329 100644
--- a/Ssl-config-target.mk
+++ b/Ssl-config-target.mk
@@ -1,6 +1,6 @@
# Auto-generated - DO NOT EDIT!
# To regenerate, edit openssl.config, then run:
-# ./import_openssl.sh import /path/to/openssl-1.0.1g.tar.gz
+# ./import_openssl.sh import /path/to/openssl-1.0.1h.tar.gz
#
# This script will append to the following variables:
#
diff --git a/apps/enc.c b/apps/enc.c
index 719acc3..19ea3df 100644
--- a/apps/enc.c
+++ b/apps/enc.c
@@ -331,6 +331,12 @@
setup_engine(bio_err, engine, 0);
#endif
+ if (cipher && EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)
+ {
+ BIO_printf(bio_err, "AEAD ciphers not supported by the enc utility\n");
+ goto end;
+ }
+
if (md && (dgst=EVP_get_digestbyname(md)) == NULL)
{
BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
diff --git a/apps/ocsp.c b/apps/ocsp.c
index 83c5a76..767f12c 100644
--- a/apps/ocsp.c
+++ b/apps/ocsp.c
@@ -127,6 +127,7 @@
ENGINE *e = NULL;
char **args;
char *host = NULL, *port = NULL, *path = "/";
+ char *thost = NULL, *tport = NULL, *tpath = NULL;
char *reqin = NULL, *respin = NULL;
char *reqout = NULL, *respout = NULL;
char *signfile = NULL, *keyfile = NULL;
@@ -204,6 +205,12 @@
}
else if (!strcmp(*args, "-url"))
{
+ if (thost)
+ OPENSSL_free(thost);
+ if (tport)
+ OPENSSL_free(tport);
+ if (tpath)
+ OPENSSL_free(tpath);
if (args[1])
{
args++;
@@ -212,6 +219,9 @@
BIO_printf(bio_err, "Error parsing URL\n");
badarg = 1;
}
+ thost = host;
+ tport = port;
+ tpath = path;
}
else badarg = 1;
}
@@ -920,12 +930,12 @@
sk_X509_pop_free(verify_other, X509_free);
sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
- if (use_ssl != -1)
- {
- OPENSSL_free(host);
- OPENSSL_free(port);
- OPENSSL_free(path);
- }
+ if (thost)
+ OPENSSL_free(thost);
+ if (tport)
+ OPENSSL_free(tport);
+ if (tpath)
+ OPENSSL_free(tpath);
OPENSSL_EXIT(ret);
}
diff --git a/apps/req.c b/apps/req.c
index 5e034a8..d41385d 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -1489,7 +1489,13 @@
#ifdef CHARSET_EBCDIC
ebcdic2ascii(buf, buf, i);
#endif
- if(!req_check_len(i, n_min, n_max)) goto start;
+ if(!req_check_len(i, n_min, n_max))
+ {
+ if (batch || value)
+ return 0;
+ goto start;
+ }
+
if (!X509_NAME_add_entry_by_NID(n,nid, chtype,
(unsigned char *) buf, -1,-1,mval)) goto err;
ret=1;
@@ -1548,7 +1554,12 @@
#ifdef CHARSET_EBCDIC
ebcdic2ascii(buf, buf, i);
#endif
- if(!req_check_len(i, n_min, n_max)) goto start;
+ if(!req_check_len(i, n_min, n_max))
+ {
+ if (batch || value)
+ return 0;
+ goto start;
+ }
if(!X509_REQ_add1_attr_by_NID(req, nid, chtype,
(unsigned char *)buf, -1)) {
diff --git a/apps/s_cb.c b/apps/s_cb.c
index 84c3b44..146a960 100644
--- a/apps/s_cb.c
+++ b/apps/s_cb.c
@@ -747,6 +747,10 @@
break;
#endif
+ case TLSEXT_TYPE_padding:
+ extname = "TLS padding";
+ break;
+
default:
extname = "unknown";
break;
diff --git a/apps/s_socket.c b/apps/s_socket.c
index 380efdb..94eb40f 100644
--- a/apps/s_socket.c
+++ b/apps/s_socket.c
@@ -274,7 +274,7 @@
{
i=0;
i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
- if (i < 0) { perror("keepalive"); return(0); }
+ if (i < 0) { closesocket(s); perror("keepalive"); return(0); }
}
#endif
@@ -450,6 +450,7 @@
if ((*host=(char *)OPENSSL_malloc(strlen(h1->h_name)+1)) == NULL)
{
perror("OPENSSL_malloc");
+ closesocket(ret);
return(0);
}
BUF_strlcpy(*host,h1->h_name,strlen(h1->h_name)+1);
@@ -458,11 +459,13 @@
if (h2 == NULL)
{
BIO_printf(bio_err,"gethostbyname failure\n");
+ closesocket(ret);
return(0);
}
if (h2->h_addrtype != AF_INET)
{
BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
+ closesocket(ret);
return(0);
}
}
diff --git a/apps/smime.c b/apps/smime.c
index c583f8a0..d1fe32d 100644
--- a/apps/smime.c
+++ b/apps/smime.c
@@ -541,8 +541,8 @@
{
if (!cipher)
{
-#ifndef OPENSSL_NO_RC2
- cipher = EVP_rc2_40_cbc();
+#ifndef OPENSSL_NO_DES
+ cipher = EVP_des_ede3_cbc();
#else
BIO_printf(bio_err, "No cipher selected\n");
goto end;
diff --git a/build-config-32.mk b/build-config-32.mk
index 4f7484b..bc2aa44 100644
--- a/build-config-32.mk
+++ b/build-config-32.mk
@@ -1,6 +1,6 @@
# Auto-generated - DO NOT EDIT!
# To regenerate, edit openssl.config, then run:
-# ./import_openssl.sh import /path/to/openssl-1.0.1g.tar.gz
+# ./import_openssl.sh import /path/to/openssl-1.0.1h.tar.gz
#
openssl_cflags_32 := \
-DOPENSSL_THREADS \
diff --git a/build-config-64.mk b/build-config-64.mk
index c0e6f6d..fde3b6a 100644
--- a/build-config-64.mk
+++ b/build-config-64.mk
@@ -1,6 +1,6 @@
# Auto-generated - DO NOT EDIT!
# To regenerate, edit openssl.config, then run:
-# ./import_openssl.sh import /path/to/openssl-1.0.1g.tar.gz
+# ./import_openssl.sh import /path/to/openssl-1.0.1h.tar.gz
#
openssl_cflags_64 := \
-DOPENSSL_THREADS \
diff --git a/build-config-trusty.mk b/build-config-trusty.mk
index e5809a3..4d6fb58 100644
--- a/build-config-trusty.mk
+++ b/build-config-trusty.mk
@@ -1,6 +1,6 @@
# Auto-generated - DO NOT EDIT!
# To regenerate, edit openssl.config, then run:
-# ./import_openssl.sh import /path/to/openssl-1.0.1g.tar.gz
+# ./import_openssl.sh import /path/to/openssl-1.0.1h.tar.gz
#
openssl_cflags_trusty := \
-DL_ENDIAN \
diff --git a/crypto/asn1/a_strnid.c b/crypto/asn1/a_strnid.c
index 2fc48c1..2afd5a4 100644
--- a/crypto/asn1/a_strnid.c
+++ b/crypto/asn1/a_strnid.c
@@ -74,7 +74,7 @@
* certain software (e.g. Netscape) has problems with them.
*/
-static unsigned long global_mask = 0xFFFFFFFFL;
+static unsigned long global_mask = B_ASN1_UTF8STRING;
void ASN1_STRING_set_default_mask(unsigned long mask)
{
diff --git a/crypto/bio/bio.h b/crypto/bio/bio.h
index 05699ab..d05fa22 100644
--- a/crypto/bio/bio.h
+++ b/crypto/bio/bio.h
@@ -266,6 +266,9 @@
#define BIO_RR_CONNECT 0x02
/* Returned from the accept BIO when an accept would have blocked */
#define BIO_RR_ACCEPT 0x03
+/* Returned from the SSL bio when the channel id retrieval code cannot find the
+ * private key. */
+#define BIO_RR_SSL_CHANNEL_ID_LOOKUP 0x04
/* These are passed by the BIO callback */
#define BIO_CB_FREE 0x01
diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c
index 54c012c..d9967e7 100644
--- a/crypto/bio/bss_dgram.c
+++ b/crypto/bio/bss_dgram.c
@@ -1333,7 +1333,7 @@
bio_dgram_sctp_data *data = NULL;
socklen_t sockopt_len = 0;
struct sctp_authkeyid authkeyid;
- struct sctp_authkey *authkey;
+ struct sctp_authkey *authkey = NULL;
data = (bio_dgram_sctp_data *)b->ptr;
@@ -1388,6 +1388,11 @@
/* Add new key */
sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
authkey = OPENSSL_malloc(sockopt_len);
+ if (authkey == NULL)
+ {
+ ret = -1;
+ break;
+ }
memset(authkey, 0x00, sockopt_len);
authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
#ifndef __FreeBSD__
@@ -1399,6 +1404,8 @@
memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, sockopt_len);
+ OPENSSL_free(authkey);
+ authkey = NULL;
if (ret < 0) break;
/* Reset active key */
diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c
index 427b5cf..ee8532c 100644
--- a/crypto/bn/bn_mont.c
+++ b/crypto/bn/bn_mont.c
@@ -478,32 +478,38 @@
BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
const BIGNUM *mod, BN_CTX *ctx)
{
- int got_write_lock = 0;
BN_MONT_CTX *ret;
CRYPTO_r_lock(lock);
- if (!*pmont)
- {
- CRYPTO_r_unlock(lock);
- CRYPTO_w_lock(lock);
- got_write_lock = 1;
-
- if (!*pmont)
- {
- ret = BN_MONT_CTX_new();
- if (ret && !BN_MONT_CTX_set(ret, mod, ctx))
- BN_MONT_CTX_free(ret);
- else
- *pmont = ret;
- }
- }
-
ret = *pmont;
-
- if (got_write_lock)
- CRYPTO_w_unlock(lock);
+ CRYPTO_r_unlock(lock);
+ if (ret)
+ return ret;
+
+ /* We don't want to serialise globally while doing our lazy-init math in
+ * BN_MONT_CTX_set. That punishes threads that are doing independent
+ * things. Instead, punish the case where more than one thread tries to
+ * lazy-init the same 'pmont', by having each do the lazy-init math work
+ * independently and only use the one from the thread that wins the race
+ * (the losers throw away the work they've done). */
+ ret = BN_MONT_CTX_new();
+ if (!ret)
+ return NULL;
+ if (!BN_MONT_CTX_set(ret, mod, ctx))
+ {
+ BN_MONT_CTX_free(ret);
+ return NULL;
+ }
+
+ /* The locked compare-and-set, after the local work is done. */
+ CRYPTO_w_lock(lock);
+ if (*pmont)
+ {
+ BN_MONT_CTX_free(ret);
+ ret = *pmont;
+ }
else
- CRYPTO_r_unlock(lock);
-
+ *pmont = ret;
+ CRYPTO_w_unlock(lock);
return ret;
}
diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c
index be20b1c..add00bf 100644
--- a/crypto/cms/cms_env.c
+++ b/crypto/cms/cms_env.c
@@ -185,6 +185,8 @@
if (flags & CMS_USE_KEYID)
{
ktri->version = 2;
+ if (env->version < 2)
+ env->version = 2;
type = CMS_RECIPINFO_KEYIDENTIFIER;
}
else
diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c
index 77fbd13..51dd33a 100644
--- a/crypto/cms/cms_sd.c
+++ b/crypto/cms/cms_sd.c
@@ -158,8 +158,8 @@
if (sd->version < 3)
sd->version = 3;
}
- else
- sd->version = 1;
+ else if (si->version < 1)
+ si->version = 1;
}
if (sd->version < 1)
diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c
index 8c56e3a..1af9f3a 100644
--- a/crypto/cms/cms_smime.c
+++ b/crypto/cms/cms_smime.c
@@ -611,7 +611,7 @@
STACK_OF(CMS_RecipientInfo) *ris;
CMS_RecipientInfo *ri;
int i, r;
- int debug = 0;
+ int debug = 0, ri_match = 0;
ris = CMS_get0_RecipientInfos(cms);
if (ris)
debug = cms->d.envelopedData->encryptedContentInfo->debug;
@@ -620,6 +620,7 @@
ri = sk_CMS_RecipientInfo_value(ris, i);
if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS)
continue;
+ ri_match = 1;
/* If we have a cert try matching RecipientInfo
* otherwise try them all.
*/
@@ -655,7 +656,7 @@
}
}
/* If no cert and not debugging always return success */
- if (!cert && !debug)
+ if (ri_match && !cert && !debug)
{
ERR_clear_error();
return 1;
diff --git a/crypto/dso/dso_dlfcn.c b/crypto/dso/dso_dlfcn.c
index 5f22548..4a56aac 100644
--- a/crypto/dso/dso_dlfcn.c
+++ b/crypto/dso/dso_dlfcn.c
@@ -464,7 +464,7 @@
return len;
}
- ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
+ ERR_add_error_data(2, "dlfcn_pathbyaddr(): ", dlerror());
#endif
return -1;
}
diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
index 0ce4524..f715a23 100644
--- a/crypto/ec/ec_ameth.c
+++ b/crypto/ec/ec_ameth.c
@@ -352,6 +352,7 @@
EC_KEY_set_enc_flags(ec_key, old_flags);
OPENSSL_free(ep);
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
+ return 0;
}
/* restore old encoding flags */
EC_KEY_set_enc_flags(ec_key, old_flags);
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c
index 145807b..e94f34e 100644
--- a/crypto/ec/ec_asn1.c
+++ b/crypto/ec/ec_asn1.c
@@ -1435,8 +1435,11 @@
*out, buf_len, NULL))
{
ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
- OPENSSL_free(*out);
- *out = NULL;
+ if (new_buffer)
+ {
+ OPENSSL_free(*out);
+ *out = NULL;
+ }
return 0;
}
if (!new_buffer)
diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h
index 6f714c7..dae9148 100644
--- a/crypto/ec/ec_lcl.h
+++ b/crypto/ec/ec_lcl.h
@@ -405,7 +405,7 @@
int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
-#ifndef OPENSSL_EC_NISTP_64_GCC_128
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
/* method functions in ecp_nistp224.c */
int ec_GFp_nistp224_group_init(EC_GROUP *group);
int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *n, BN_CTX *);
diff --git a/crypto/evp/bio_b64.c b/crypto/evp/bio_b64.c
index ac6d441..16863fe 100644
--- a/crypto/evp/bio_b64.c
+++ b/crypto/evp/bio_b64.c
@@ -226,6 +226,7 @@
else if (ctx->start)
{
q=p=(unsigned char *)ctx->tmp;
+ num = 0;
for (j=0; j<i; j++)
{
if (*(q++) != '\n') continue;
diff --git a/crypto/evp/encode.c b/crypto/evp/encode.c
index 28546a8..4654bdc 100644
--- a/crypto/evp/encode.c
+++ b/crypto/evp/encode.c
@@ -324,6 +324,7 @@
v=EVP_DecodeBlock(out,d,n);
n=0;
if (v < 0) { rv=0; goto end; }
+ if (eof > v) { rv=-1; goto end; }
ret+=(v-eof);
}
else
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index bd1977d..8ee53c1 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -202,7 +202,7 @@
EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey)
{
- CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+ CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
return pkey;
}
diff --git a/crypto/opensslv.h b/crypto/opensslv.h
index ebe7180..c3b6ace 100644
--- a/crypto/opensslv.h
+++ b/crypto/opensslv.h
@@ -25,11 +25,11 @@
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta)
*/
-#define OPENSSL_VERSION_NUMBER 0x1000107fL
+#define OPENSSL_VERSION_NUMBER 0x1000108fL
#ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1g-fips 7 Apr 2014"
+#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1h-fips 5 Jun 2014"
#else
-#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1g 7 Apr 2014"
+#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1h 5 Jun 2014"
#endif
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
diff --git a/crypto/pkcs12/p12_crt.c b/crypto/pkcs12/p12_crt.c
index a34915d..35e8a4a 100644
--- a/crypto/pkcs12/p12_crt.c
+++ b/crypto/pkcs12/p12_crt.c
@@ -96,7 +96,11 @@
nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
else
#endif
+#ifdef OPENSSL_NO_RC2
+ nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+#else
nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
+#endif
}
if (!nid_key)
nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
@@ -286,7 +290,11 @@
free_safes = 0;
if (nid_safe == 0)
+#ifdef OPENSSL_NO_RC2
+ nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+#else
nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
+#endif
if (nid_safe == -1)
p7 = PKCS12_pack_p7data(bags);
diff --git a/crypto/pkcs12/p12_kiss.c b/crypto/pkcs12/p12_kiss.c
index 206b1b0..c9b7ab6 100644
--- a/crypto/pkcs12/p12_kiss.c
+++ b/crypto/pkcs12/p12_kiss.c
@@ -269,7 +269,7 @@
int len, r;
unsigned char *data;
len = ASN1_STRING_to_UTF8(&data, fname);
- if(len > 0) {
+ if(len >= 0) {
r = X509_alias_set1(x509, data, len);
OPENSSL_free(data);
if (!r)
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
index 77fda3b..d91aa11 100644
--- a/crypto/pkcs7/pk7_doit.c
+++ b/crypto/pkcs7/pk7_doit.c
@@ -440,6 +440,11 @@
{
case NID_pkcs7_signed:
data_body=PKCS7_get_octet_string(p7->d.sign->contents);
+ if (!PKCS7_is_detached(p7) && data_body == NULL)
+ {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_INVALID_SIGNED_DATA_TYPE);
+ goto err;
+ }
md_sk=p7->d.sign->md_algs;
break;
case NID_pkcs7_signedAndEnveloped:
@@ -928,6 +933,7 @@
if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0)
goto err;
OPENSSL_free(abuf);
+ abuf = NULL;
if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
goto err;
abuf = OPENSSL_malloc(siglen);
diff --git a/crypto/pkcs7/pkcs7.h b/crypto/pkcs7/pkcs7.h
index e4d4431..04f6037 100644
--- a/crypto/pkcs7/pkcs7.h
+++ b/crypto/pkcs7/pkcs7.h
@@ -453,6 +453,7 @@
#define PKCS7_R_ERROR_SETTING_CIPHER 121
#define PKCS7_R_INVALID_MIME_TYPE 131
#define PKCS7_R_INVALID_NULL_POINTER 143
+#define PKCS7_R_INVALID_SIGNED_DATA_TYPE 155
#define PKCS7_R_MIME_NO_CONTENT_TYPE 132
#define PKCS7_R_MIME_PARSE_ERROR 133
#define PKCS7_R_MIME_SIG_PARSE_ERROR 134
diff --git a/crypto/pkcs7/pkcs7err.c b/crypto/pkcs7/pkcs7err.c
index d0af32a..f3db08e 100644
--- a/crypto/pkcs7/pkcs7err.c
+++ b/crypto/pkcs7/pkcs7err.c
@@ -1,6 +1,6 @@
/* crypto/pkcs7/pkcs7err.c */
/* ====================================================================
- * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -130,6 +130,7 @@
{ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER),"error setting cipher"},
{ERR_REASON(PKCS7_R_INVALID_MIME_TYPE) ,"invalid mime type"},
{ERR_REASON(PKCS7_R_INVALID_NULL_POINTER),"invalid null pointer"},
+{ERR_REASON(PKCS7_R_INVALID_SIGNED_DATA_TYPE),"invalid signed data type"},
{ERR_REASON(PKCS7_R_MIME_NO_CONTENT_TYPE),"mime no content type"},
{ERR_REASON(PKCS7_R_MIME_PARSE_ERROR) ,"mime parse error"},
{ERR_REASON(PKCS7_R_MIME_SIG_PARSE_ERROR),"mime sig parse error"},
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index 5a2062f..4c8ecd9 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -358,7 +358,7 @@
if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0)
goto err;
}
- else if (BIO_puts(bp, "0x14 (default)") <= 0)
+ else if (BIO_puts(bp, "14 (default)") <= 0)
goto err;
BIO_puts(bp, "\n");
diff --git a/crypto/srp/srp_vfy.c b/crypto/srp/srp_vfy.c
index 4a3d13e..fdca19f 100644
--- a/crypto/srp/srp_vfy.c
+++ b/crypto/srp/srp_vfy.c
@@ -93,6 +93,9 @@
else a[i] = loc - b64table;
++i;
}
+ /* if nothing valid to process we have a zero length response */
+ if (i == 0)
+ return 0;
size = i;
i = size - 1;
j = size;
diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c
index ad68865..f59bfc1 100644
--- a/crypto/x509v3/v3_purp.c
+++ b/crypto/x509v3/v3_purp.c
@@ -389,8 +389,8 @@
/* Handle proxy certificates */
if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
if (x->ex_flags & EXFLAG_CA
- || X509_get_ext_by_NID(x, NID_subject_alt_name, 0) >= 0
- || X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 0) {
+ || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
+ || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
x->ex_flags |= EXFLAG_INVALID;
}
if (pci->pcPathLengthConstraint) {
@@ -670,7 +670,7 @@
return 0;
/* Extended Key Usage MUST be critical */
- i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, 0);
+ i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, -1);
if (i_ext >= 0)
{
X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
diff --git a/import_openssl.sh b/import_openssl.sh
index 02d2ab1..4ae7e33 100755
--- a/import_openssl.sh
+++ b/import_openssl.sh
@@ -610,12 +610,13 @@
cd $dir
# Apply appropriate patches
- for i in $OPENSSL_PATCHES; do
- if [ ! "$skip_patch" = "patches/$i" ]; then
+ patches=(../patches/[0-9][0-9][0-9][0-9]-*.patch)
+ for i in "${patches[@]}"; do
+ if [[ $skip_patch != ${i##*/} ]]; then
echo "Applying patch $i"
- patch -p1 < ../patches/$i || die "Could not apply patches/$i. Fix source and run: $0 regenerate patches/$i"
+ patch -p1 < $i || die "Could not apply $i. Fix source and run: $0 regenerate patches/${i##*/}"
else
- echo "Skiping patch $i"
+ echo "Skiping patch ${i##*/}"
fi
done
diff --git a/include/openssl/bio.h b/include/openssl/bio.h
index 05699ab..d05fa22 100644
--- a/include/openssl/bio.h
+++ b/include/openssl/bio.h
@@ -266,6 +266,9 @@
#define BIO_RR_CONNECT 0x02
/* Returned from the accept BIO when an accept would have blocked */
#define BIO_RR_ACCEPT 0x03
+/* Returned from the SSL bio when the channel id retrieval code cannot find the
+ * private key. */
+#define BIO_RR_SSL_CHANNEL_ID_LOOKUP 0x04
/* These are passed by the BIO callback */
#define BIO_CB_FREE 0x01
diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h
index ebe7180..c3b6ace 100644
--- a/include/openssl/opensslv.h
+++ b/include/openssl/opensslv.h
@@ -25,11 +25,11 @@
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta)
*/
-#define OPENSSL_VERSION_NUMBER 0x1000107fL
+#define OPENSSL_VERSION_NUMBER 0x1000108fL
#ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1g-fips 7 Apr 2014"
+#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1h-fips 5 Jun 2014"
#else
-#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1g 7 Apr 2014"
+#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1h 5 Jun 2014"
#endif
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
diff --git a/include/openssl/pkcs7.h b/include/openssl/pkcs7.h
index e4d4431..04f6037 100644
--- a/include/openssl/pkcs7.h
+++ b/include/openssl/pkcs7.h
@@ -453,6 +453,7 @@
#define PKCS7_R_ERROR_SETTING_CIPHER 121
#define PKCS7_R_INVALID_MIME_TYPE 131
#define PKCS7_R_INVALID_NULL_POINTER 143
+#define PKCS7_R_INVALID_SIGNED_DATA_TYPE 155
#define PKCS7_R_MIME_NO_CONTENT_TYPE 132
#define PKCS7_R_MIME_PARSE_ERROR 133
#define PKCS7_R_MIME_SIG_PARSE_ERROR 134
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 54b0eb6..06bb90f 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -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
@@ -553,7 +560,7 @@
/* Allow initial connection to servers that don't support RI */
#define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L
#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L
-#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x00000010L
+#define SSL_OP_TLSEXT_PADDING 0x00000010L
#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L
#define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040L
#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x00000080L
@@ -562,6 +569,8 @@
/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */
#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0
+/* Refers to ancient SSLREF and SSLv2, retained for compatibility */
+#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x0
/* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS is vestigial. Previously it disabled the
* insertion of empty records in CBC mode, but the empty records were commonly
@@ -648,12 +657,14 @@
* TLS only.) "Released" buffers are put onto a free-list in the context
* or just freed (depending on the context's setting for freelist_max_len). */
#define SSL_MODE_RELEASE_BUFFERS 0x00000010L
+
/* Send the current time in the Random fields of the ClientHello and
* ServerHello records for compatibility with hypothetical implementations
* that require it.
*/
#define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
#define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
+
/* When set, clients may send application data before receipt of CCS
* and Finished. This mode enables full-handshakes to 'complete' in
* one RTT. */
@@ -866,6 +877,9 @@
/* get client cert callback */
int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+ /* get channel id callback */
+ void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey);
+
/* cookie generate callback */
int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie,
unsigned int *cookie_len);
@@ -1028,6 +1042,10 @@
/* If true, a client will advertise the Channel ID extension and a
* server will echo it. */
char tlsext_channel_id_enabled;
+ /* tlsext_channel_id_enabled_new is a hack to support both old and new
+ * ChannelID signatures. It indicates that a client should advertise the
+ * new ChannelID extension number. */
+ char tlsext_channel_id_enabled_new;
/* The client's Channel ID private key. */
EVP_PKEY *tlsext_channel_id_private;
#endif
@@ -1086,6 +1104,8 @@
void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val);
void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey));
+void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey);
#ifndef OPENSSL_NO_ENGINE
int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
#endif
@@ -1162,12 +1182,14 @@
#define SSL_WRITING 2
#define SSL_READING 3
#define SSL_X509_LOOKUP 4
+#define SSL_CHANNEL_ID_LOOKUP 5
/* These will only be used when doing non-blocking IO */
#define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING)
#define SSL_want_read(s) (SSL_want(s) == SSL_READING)
#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING)
#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
+#define SSL_want_channel_id_lookup(s) (SSL_want(s) == SSL_CHANNEL_ID_LOOKUP)
#define SSL_MAC_FLAG_READ_MAC_STREAM 1
#define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
@@ -1602,6 +1624,7 @@
#define SSL_ERROR_ZERO_RETURN 6
#define SSL_ERROR_WANT_CONNECT 7
#define SSL_ERROR_WANT_ACCEPT 8
+#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP 9
#define SSL_CTRL_NEED_TMP_RSA 1
#define SSL_CTRL_SET_TMP_RSA 2
@@ -1739,10 +1762,11 @@
#define SSL_set_tmp_ecdh(ssl,ecdh) \
SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
-/* SSL_enable_tls_channel_id configures a TLS server to accept TLS client
- * IDs from clients. Returns 1 on success. */
-#define SSL_enable_tls_channel_id(ctx) \
- SSL_ctrl(ctx,SSL_CTRL_CHANNEL_ID,0,NULL)
+/* SSL_enable_tls_channel_id either configures a TLS server to accept TLS client
+ * IDs from clients, or configure a client to send TLS client IDs to server.
+ * Returns 1 on success. */
+#define SSL_enable_tls_channel_id(s) \
+ SSL_ctrl(s,SSL_CTRL_CHANNEL_ID,0,NULL)
/* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to
* compatible servers. private_key must be a P-256 EVP_PKEY*. Returns 1 on
* success. */
@@ -1792,7 +1816,6 @@
char * SSL_CIPHER_get_version(const SSL_CIPHER *c);
const char * SSL_CIPHER_get_name(const SSL_CIPHER *c);
unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c);
-const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher);
int SSL_get_fd(const SSL *s);
int SSL_get_rfd(const SSL *s);
@@ -2707,7 +2730,6 @@
#define SSL_R_WRONG_VERSION_NUMBER 267
#define SSL_R_X509_LIB 268
#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269
-#define SSL_R_UNEXPECTED_CCS 388
#ifdef __cplusplus
}
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index f205f73..83d59bf 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -388,9 +388,6 @@
#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008
#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010
#define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020
-/* SSL3_FLAGS_CCS_OK indicates that a ChangeCipherSpec record is acceptable at
- * this point in the handshake. If this flag is not set then received CCS
- * records will cause a fatal error for the connection. */
#define SSL3_FLAGS_CCS_OK 0x0080
/* SSL3_FLAGS_SGC_RESTART_DONE is set when we
@@ -558,6 +555,11 @@
* for Channel IDs and that tlsext_channel_id will be valid after the
* handshake. */
char tlsext_channel_id_valid;
+ /* tlsext_channel_id_new means that the updated Channel ID extension
+ * was negotiated. This is a temporary hack in the code to support both
+ * forms of Channel ID extension while we transition to the new format,
+ * which fixed a security issue. */
+ char tlsext_channel_id_new;
/* For a server:
* If |tlsext_channel_id_valid| is true, then this contains the
* verified Channel ID from the client: a P256 point, (x,y), where
@@ -678,11 +680,11 @@
#define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT)
-#define SSL3_ST_SR_POST_CLIENT_CERT (0x1BF|SSL_ST_ACCEPT)
#ifndef OPENSSL_NO_NEXTPROTONEG
#define SSL3_ST_SR_NEXT_PROTO_A (0x210|SSL_ST_ACCEPT)
#define SSL3_ST_SR_NEXT_PROTO_B (0x211|SSL_ST_ACCEPT)
#endif
+#define SSL3_ST_SR_POST_CLIENT_CERT (0x1BF|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CHANNEL_ID_A (0x220|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CHANNEL_ID_B (0x221|SSL_ST_ACCEPT)
#define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT)
diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
index ec8948d..6652089 100644
--- a/include/openssl/tls1.h
+++ b/include/openssl/tls1.h
@@ -259,6 +259,7 @@
/* This is not an IANA defined extension number */
#define TLSEXT_TYPE_channel_id 30031
+#define TLSEXT_TYPE_channel_id_new 30032
/* NameType value from RFC 3546 */
#define TLSEXT_NAMETYPE_host_name 0
diff --git a/openssl.config b/openssl.config
index aa02870..d44b0bb 100644
--- a/openssl.config
+++ b/openssl.config
@@ -94,7 +94,6 @@
README.ENGINE \
apps/CA.com \
apps/Makefile \
-apps/Makefile.save \
apps/install-apps.com \
apps/makeapps.com \
apps/openssl-vms.cnf \
@@ -104,14 +103,10 @@
config \
crypto/LPdir_vms.c \
crypto/Makefile \
-crypto/Makefile.save \
crypto/aes/Makefile \
-crypto/aes/Makefile.save \
crypto/asn1/Makefile \
-crypto/asn1/Makefile.save \
crypto/bf/INSTALL \
crypto/bf/Makefile \
-crypto/bf/Makefile.save \
crypto/bf/README \
crypto/bf/VERSION \
crypto/bf/asm/readme \
@@ -121,117 +116,78 @@
crypto/bf/bfspeed.c \
crypto/bf/bftest.c \
crypto/bio/Makefile \
-crypto/bio/Makefile.save \
crypto/bio/bss_rtcp.c \
crypto/bn/Makefile \
-crypto/bn/Makefile.save \
crypto/bn/asm/vms.mar \
crypto/bn/bn_x931p.c \
crypto/bn/vms-helper.c \
crypto/buffer/Makefile \
-crypto/buffer/Makefile.save \
crypto/cmac/Makefile \
-crypto/cmac/Makefile.save \
crypto/cms/Makefile \
-crypto/cms/Makefile.save \
crypto/comp/Makefile \
-crypto/comp/Makefile.save \
crypto/conf/Makefile \
-crypto/conf/Makefile.save \
crypto/crypto-lib.com \
crypto/des/Makefile \
-crypto/des/Makefile.save \
crypto/des/des-lib.com \
crypto/dh/Makefile \
-crypto/dh/Makefile.save \
crypto/dh/dh_prn.c \
crypto/dsa/Makefile \
-crypto/dsa/Makefile.save \
crypto/dso/Makefile \
-crypto/dso/Makefile.save \
crypto/dso/dso_beos.c \
crypto/dso/dso_vms.c \
crypto/dso/dso_win32.c \
crypto/ec/Makefile \
-crypto/ec/Makefile.save \
crypto/ec/ecp_nistp224.c \
crypto/ec/ecp_nistp256.c \
crypto/ec/ecp_nistp521.c \
crypto/ec/ecp_nistputil.c \
crypto/ecdh/Makefile \
-crypto/ecdh/Makefile.save \
crypto/ecdsa/Makefile \
-crypto/ecdsa/Makefile.save \
crypto/engine/Makefile \
-crypto/engine/Makefile.save \
crypto/engine/eng_rdrand.c \
crypto/engine/eng_rsax.c \
crypto/err/Makefile \
-crypto/err/Makefile.save \
crypto/evp/Makefile \
-crypto/evp/Makefile.save \
crypto/evp/evp_fips.c \
crypto/evp/m_md2.c \
crypto/evp/m_sha.c \
crypto/fips_err.h \
crypto/fips_ers.c \
crypto/hmac/Makefile \
-crypto/hmac/Makefile.save \
crypto/install-crypto.com \
crypto/jpake/Makefile \
crypto/krb5/Makefile \
-crypto/krb5/Makefile.save \
crypto/lhash/Makefile \
-crypto/lhash/Makefile.save \
crypto/md4/Makefile \
-crypto/md4/Makefile.save \
crypto/md5/Makefile \
-crypto/md5/Makefile.save \
crypto/mdc2/Makefile \
-crypto/mdc2/Makefile.save \
crypto/modes/Makefile \
-crypto/modes/Makefile.save \
crypto/modes/cts128.c \
crypto/modes/modes.h \
crypto/o_fips.c \
crypto/objects/Makefile \
-crypto/objects/Makefile.save \
crypto/ocsp/Makefile \
-crypto/ocsp/Makefile.save \
crypto/pem/Makefile \
-crypto/pem/Makefile.save \
crypto/pkcs12/Makefile \
-crypto/pkcs12/Makefile.save \
crypto/pkcs7/Makefile \
-crypto/pkcs7/Makefile.save \
crypto/pkcs7/bio_pk7.c \
crypto/ppccap.c \
crypto/pqueue/Makefile \
-crypto/pqueue/Makefile.save \
crypto/rand/Makefile \
-crypto/rand/Makefile.save \
crypto/rand/rand_vms.c \
crypto/rc2/Makefile \
-crypto/rc2/Makefile.save \
crypto/rc4/Makefile \
-crypto/rc4/Makefile.save \
crypto/ripemd/Makefile \
-crypto/ripemd/Makefile.save \
crypto/rsa/Makefile \
-crypto/rsa/Makefile.save \
crypto/sha/Makefile \
-crypto/sha/Makefile.save \
crypto/sha/sha_one.c \
crypto/srp/Makefile \
-crypto/srp/Makefile.save \
crypto/srp/srptest.c \
crypto/stack/Makefile \
-crypto/stack/Makefile.save \
crypto/store/Makefile \
crypto/threads/pthreads-vms.com \
crypto/threads/win32.bat \
crypto/ts/Makefile \
-crypto/ts/Makefile.save \
crypto/ts/ts.h \
crypto/ts/ts_asn1.c \
crypto/ts/ts_conf.c \
@@ -244,14 +200,10 @@
crypto/ts/ts_rsp_verify.c \
crypto/ts/ts_verify_ctx.c \
crypto/txt_db/Makefile \
-crypto/txt_db/Makefile.save \
crypto/ui/Makefile \
-crypto/ui/Makefile.save \
crypto/vms_rms.h
crypto/x509/Makefile \
-crypto/x509/Makefile.save \
crypto/x509v3/Makefile \
-crypto/x509v3/Makefile.save \
include/openssl/camellia.h \
include/openssl/cast.h \
include/openssl/idea.h \
@@ -263,7 +215,7 @@
openssl.doxy \
openssl.spec \
ssl/Makefile \
-ssl/Makefile.save \
+ssl/heartbeat_test.c \
ssl/install-ssl.com \
ssl/ssl-lib.com \
ssl/ssl_task.c \
@@ -1082,23 +1034,4 @@
apps/x509.c \
"
-OPENSSL_PATCHES="\
-progs.patch \
-handshake_cutthrough.patch \
-jsse.patch \
-channelid.patch \
-eng_dyn_dirs.patch \
-fix_clang_build.patch \
-tls12_digests.patch \
-alpn.patch \
-cbc_record_splitting.patch \
-dsa_nonce.patch \
-ecdhe_psk.patch \
-wincrypt.patch \
-tls_psk_hint.patch \
-arm_asm.patch \
-psk_client_callback_128_byte_id_bug.patch \
-early_ccs.patch \
-"
-
source ./openssl.trusty.config
diff --git a/openssl.version b/openssl.version
index 2e84991..ab2e62b 100644
--- a/openssl.version
+++ b/openssl.version
@@ -1 +1 @@
-OPENSSL_VERSION=1.0.1g
+OPENSSL_VERSION=1.0.1h
diff --git a/patches/progs.patch b/patches/0001-progs.patch
similarity index 100%
rename from patches/progs.patch
rename to patches/0001-progs.patch
diff --git a/patches/handshake_cutthrough.patch b/patches/0002-handshake_cutthrough.patch
similarity index 78%
rename from patches/handshake_cutthrough.patch
rename to patches/0002-handshake_cutthrough.patch
index f05a10f..f68fd6f 100644
--- a/patches/handshake_cutthrough.patch
+++ b/patches/0002-handshake_cutthrough.patch
@@ -1,4 +1,4 @@
-From d0e735d01271055f09bc4a1be034253e6e3c2dee Mon Sep 17 00:00:00 2001
+From 4c654523c703645f8b517389b6da537c5a9e5168 Mon Sep 17 00:00:00 2001
From: Adam Langley <agl@chromium.org>
Date: Thu, 24 Jan 2013 16:22:07 -0500
Subject: [PATCH] handshake_cutthrough
@@ -9,14 +9,15 @@
performing full-handshakes.
---
apps/s_client.c | 13 +++++++++++++
- ssl/s3_clnt.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++------
+ ssl/s3_clnt.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++------
ssl/s3_lib.c | 15 ++++++++++++++-
- ssl/ssl.h | 8 +++++++-
+ ssl/ssl.h | 10 +++++++++-
ssl/ssl3.h | 1 +
- ssl/ssl_lib.c | 13 +++++++++++++
+ ssl/ssl_lib.c | 42 ++++++++++++++++++++++++++++++++++++++++++
+ ssl/ssl_locl.h | 2 ++
ssl/ssltest.c | 12 ++++++++++++
test/testssl | 3 +++
- 8 files changed, 110 insertions(+), 8 deletions(-)
+ 9 files changed, 144 insertions(+), 8 deletions(-)
diff --git a/apps/s_client.c b/apps/s_client.c
index 3ba6605..791e277 100644
@@ -64,35 +65,23 @@
if (cipher != NULL)
if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
-index 344e2eb..c3bf18a 100644
+index a6b3c01..3d3fd64 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
-@@ -215,6 +215,24 @@ int ssl3_connect(SSL *s)
+@@ -215,6 +215,12 @@ int ssl3_connect(SSL *s)
}
#endif
-+// BEGIN android-added
-+#if 0
-+/* Send app data in separate packet, otherwise, some particular site
-+ * (only one site so far) closes the socket. http://b/2511073
-+ * Note: there is a very small chance that two TCP packets
-+ * could be arriving at server combined into a single TCP packet,
-+ * then trigger that site to break. We haven't encounter that though.
-+ */
-+// END android-added
+ if (SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
+ {
+ /* Send app data along with CCS/Finished */
+ s->s3->flags |= SSL3_FLAGS_DELAY_CLIENT_FINISHED;
+ }
+
-+// BEGIN android-added
-+#endif
-+// END android-added
for (;;)
{
state=s->state;
-@@ -526,14 +532,31 @@ int ssl3_connect(SSL *s)
+@@ -526,14 +532,32 @@ int ssl3_connect(SSL *s)
}
else
{
@@ -100,7 +89,8 @@
- /* Allow NewSessionTicket if ticket expected */
- if (s->tlsext_ticket_expected)
- s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
-+ if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) && SSL_get_cipher_bits(s, NULL) >= 128
++ if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
++ && ssl3_can_cutthrough(s)
+ && s->s3->previous_server_finished_len == 0 /* no cutthrough on renegotiation (would complicate the state machine) */
+ )
+ {
@@ -130,7 +120,7 @@
}
s->init_num=0;
break;
-@@ -581,6 +604,24 @@ int ssl3_connect(SSL *s)
+@@ -581,6 +605,24 @@ int ssl3_connect(SSL *s)
s->state=s->s3->tmp.next_state;
break;
@@ -156,10 +146,10 @@
/* clean a few things up */
ssl3_cleanup_key_block(s);
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
-index e7c5dcb..0d77c40 100644
+index c4ef273..1865c70 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
-@@ -4199,9 +4199,22 @@ int ssl3_write(SSL *s, const void *buf, int len)
+@@ -4211,9 +4211,22 @@ int ssl3_write(SSL *s, const void *buf, int len)
static int ssl3_read_internal(SSL *s, void *buf, int len, int peek)
{
@@ -184,21 +174,30 @@
s->s3->in_read_app_data=1;
ret=s->method->ssl_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len,peek);
diff --git a/ssl/ssl.h b/ssl/ssl.h
-index f9c9049..f2af98c 100644
+index 1f255c3..3e31fb5 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
-@@ -649,6 +649,10 @@ struct ssl_session_st
- */
+@@ -644,6 +644,7 @@ struct ssl_session_st
+ * TLS only.) "Released" buffers are put onto a free-list in the context
+ * or just freed (depending on the context's setting for freelist_max_len). */
+ #define SSL_MODE_RELEASE_BUFFERS 0x00000010L
++
+ /* Send the current time in the Random fields of the ClientHello and
+ * ServerHello records for compatibility with hypothetical implementations
+ * that require it.
+@@ -651,6 +652,11 @@ struct ssl_session_st
#define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
#define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
+
+/* When set, clients may send application data before receipt of CCS
+ * and Finished. This mode enables full-handshakes to 'complete' in
+ * one RTT. */
+#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000080L
-
++
/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
* they cannot be used to clear bits. */
-@@ -1415,10 +1419,12 @@ extern "C" {
+
+@@ -1424,10 +1430,12 @@ extern "C" {
/* Is the SSL_connection established? */
#define SSL_get_state(a) SSL_state(a)
#define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK)
@@ -213,10 +212,10 @@
/* The following 2 states are kept in ssl->rstate when reads fail,
* you should not need these */
diff --git a/ssl/ssl3.h b/ssl/ssl3.h
-index 247e88c..bd0d764 100644
+index cb8b249..9a61b71 100644
--- a/ssl/ssl3.h
+++ b/ssl/ssl3.h
-@@ -547,6 +547,7 @@ typedef struct ssl3_state_st
+@@ -556,6 +556,7 @@ typedef struct ssl3_state_st
/*client */
/* extra state */
#define SSL3_ST_CW_FLUSH (0x100|SSL_ST_CONNECT)
@@ -225,10 +224,10 @@
#define DTLS1_SCTP_ST_CW_WRITE_SOCK (0x310|SSL_ST_CONNECT)
#define DTLS1_SCTP_ST_CR_READ_SOCK (0x320|SSL_ST_CONNECT)
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
-index 14d143d..a56e6ef 100644
+index 6dbc3c1..7892928 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
-@@ -3225,6 +3225,19 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con
+@@ -3225,6 +3225,48 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con
SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
}
@@ -239,17 +238,59 @@
+ s->version >= SSL3_VERSION &&
+ s->s3->in_read_app_data == 0 && /* cutthrough only applies to write() */
+ (SSL_get_mode((SSL*)s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) && /* cutthrough enabled */
-+ SSL_get_cipher_bits(s, NULL) >= 128 && /* strong cipher choosen */
++ ssl3_can_cutthrough(s) && /* cutthrough allowed */
+ s->s3->previous_server_finished_len == 0 && /* not a renegotiation handshake */
+ (s->state == SSL3_ST_CR_SESSION_TICKET_A || /* ready to write app-data*/
+ s->state == SSL3_ST_CR_FINISHED_A));
+ }
+
++int ssl3_can_cutthrough(const SSL *s)
++ {
++ const SSL_CIPHER *c;
++
++ /* require a strong enough cipher */
++ if (SSL_get_cipher_bits(s, NULL) < 128)
++ return 0;
++
++ /* require ALPN or NPN extension */
++ if (!s->s3->alpn_selected
++#ifndef OPENSSL_NO_NEXTPROTONEG
++ && !s->s3->next_proto_neg_seen
++#endif
++ )
++ {
++ return 0;
++ }
++
++ /* require a forward-secret cipher */
++ c = SSL_get_current_cipher(s);
++ if (!c || (c->algorithm_mkey != SSL_kEDH &&
++ c->algorithm_mkey != SSL_kEECDH))
++ {
++ return 0;
++ }
++
++ return 1;
++ }
++
/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
* vairable, freeing EVP_MD_CTX previously stored in that variable, if
* any. If EVP_MD pointer is passed, initializes ctx with this md
+diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
+index e485907..3b1d644 100644
+--- a/ssl/ssl_locl.h
++++ b/ssl/ssl_locl.h
+@@ -1126,6 +1126,8 @@ int tls12_get_sigid(const EVP_PKEY *pk);
+ const EVP_MD *tls12_get_hash(unsigned char hash_alg);
+
+ #endif
++
++int ssl3_can_cutthrough(const SSL *s);
+ EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ;
+ void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
+ int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
diff --git a/ssl/ssltest.c b/ssl/ssltest.c
-index 316bbb0..91169bb 100644
+index 4f80be8..28fa223 100644
--- a/ssl/ssltest.c
+++ b/ssl/ssltest.c
@@ -369,6 +369,7 @@ static void sv_usage(void)
@@ -279,7 +320,7 @@
else
{
fprintf(stderr,"unknown option %s\n",*argv);
-@@ -900,6 +906,12 @@ bad:
+@@ -906,6 +912,12 @@ bad:
SSL_CTX_set_cipher_list(c_ctx,cipher);
SSL_CTX_set_cipher_list(s_ctx,cipher);
}
@@ -307,5 +348,5 @@
$ssltest -bio_pair -ssl2 $extra || exit 1
--
-1.8.2.1
+1.9.1.423.g4596e3a
diff --git a/patches/jsse.patch b/patches/0003-jsse.patch
similarity index 100%
rename from patches/jsse.patch
rename to patches/0003-jsse.patch
diff --git a/patches/0004-channelid.patch b/patches/0004-channelid.patch
new file mode 100644
index 0000000..3b9ec8a
--- /dev/null
+++ b/patches/0004-channelid.patch
@@ -0,0 +1,1462 @@
+diff --git a/crypto/bio/bio.h b/crypto/bio/bio.h
+index 05699ab..d05fa22 100644
+--- a/crypto/bio/bio.h
++++ b/crypto/bio/bio.h
+@@ -266,6 +266,9 @@ void BIO_clear_flags(BIO *b, int flags);
+ #define BIO_RR_CONNECT 0x02
+ /* Returned from the accept BIO when an accept would have blocked */
+ #define BIO_RR_ACCEPT 0x03
++/* Returned from the SSL bio when the channel id retrieval code cannot find the
++ * private key. */
++#define BIO_RR_SSL_CHANNEL_ID_LOOKUP 0x04
+
+ /* These are passed by the BIO callback */
+ #define BIO_CB_FREE 0x01
+diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h
+index ea4bed9..5f18d4b 100644
+--- a/crypto/evp/evp.h
++++ b/crypto/evp/evp.h
+@@ -921,6 +921,7 @@ struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
+ #endif
+
+ EVP_PKEY * EVP_PKEY_new(void);
++EVP_PKEY * EVP_PKEY_dup(EVP_PKEY *pkey);
+ void EVP_PKEY_free(EVP_PKEY *pkey);
+
+ EVP_PKEY * d2i_PublicKey(int type,EVP_PKEY **a, const unsigned char **pp,
+diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
+index a0e14a3..65a4440 100644
+--- a/crypto/evp/p_lib.c
++++ b/crypto/evp/p_lib.c
+@@ -200,6 +200,12 @@ EVP_PKEY *EVP_PKEY_new(void)
+ return(ret);
+ }
+
++EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey)
++ {
++ CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
++ return pkey;
++ }
++
+ /* Setup a public key ASN1 method and ENGINE from a NID or a string.
+ * If pkey is NULL just return 1 or 0 if the algorithm exists.
+ */
+diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c
+index e9552ca..06a13de 100644
+--- a/ssl/bio_ssl.c
++++ b/ssl/bio_ssl.c
+@@ -206,6 +206,10 @@ static int ssl_read(BIO *b, char *out, int outl)
+ BIO_set_retry_special(b);
+ retry_reason=BIO_RR_SSL_X509_LOOKUP;
+ break;
++ case SSL_ERROR_WANT_CHANNEL_ID_LOOKUP:
++ BIO_set_retry_special(b);
++ retry_reason=BIO_RR_SSL_CHANNEL_ID_LOOKUP;
++ break;
+ case SSL_ERROR_WANT_ACCEPT:
+ BIO_set_retry_special(b);
+ retry_reason=BIO_RR_ACCEPT;
+@@ -280,6 +284,10 @@ static int ssl_write(BIO *b, const char *out, int outl)
+ BIO_set_retry_special(b);
+ retry_reason=BIO_RR_SSL_X509_LOOKUP;
+ break;
++ case SSL_ERROR_WANT_CHANNEL_ID_LOOKUP:
++ BIO_set_retry_special(b);
++ retry_reason=BIO_RR_SSL_CHANNEL_ID_LOOKUP;
++ break;
+ case SSL_ERROR_WANT_CONNECT:
+ BIO_set_retry_special(b);
+ retry_reason=BIO_RR_CONNECT;
+diff --git a/ssl/s3_both.c b/ssl/s3_both.c
+index 53b9390..c0dac70 100644
+--- a/ssl/s3_both.c
++++ b/ssl/s3_both.c
+@@ -554,7 +554,8 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
+ #endif
+
+ /* Feed this message into MAC computation. */
+- ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
++ if (*((unsigned char*) s->init_buf->data) != SSL3_MT_ENCRYPTED_EXTENSIONS)
++ ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg);
+ *ok=1;
+diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
+index 3d3fd64..7e0c4d5 100644
+--- a/ssl/s3_clnt.c
++++ b/ssl/s3_clnt.c
+@@ -465,13 +465,14 @@ int ssl3_connect(SSL *s)
+ SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
+ if (ret <= 0) goto end;
+
+-#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
+ s->state=SSL3_ST_CW_FINISHED_A;
+-#else
++#if !defined(OPENSSL_NO_TLSEXT)
++ if (s->s3->tlsext_channel_id_valid)
++ s->state=SSL3_ST_CW_CHANNEL_ID_A;
++# if !defined(OPENSSL_NO_NEXTPROTONEG)
+ if (s->s3->next_proto_neg_seen)
+ s->state=SSL3_ST_CW_NEXT_PROTO_A;
+- else
+- s->state=SSL3_ST_CW_FINISHED_A;
++# endif
+ #endif
+ s->init_num=0;
+
+@@ -505,6 +506,18 @@ int ssl3_connect(SSL *s)
+ case SSL3_ST_CW_NEXT_PROTO_B:
+ ret=ssl3_send_next_proto(s);
+ if (ret <= 0) goto end;
++ if (s->s3->tlsext_channel_id_valid)
++ s->state=SSL3_ST_CW_CHANNEL_ID_A;
++ else
++ s->state=SSL3_ST_CW_FINISHED_A;
++ break;
++#endif
++
++#if !defined(OPENSSL_NO_TLSEXT)
++ case SSL3_ST_CW_CHANNEL_ID_A:
++ case SSL3_ST_CW_CHANNEL_ID_B:
++ ret=ssl3_send_channel_id(s);
++ if (ret <= 0) goto end;
+ s->state=SSL3_ST_CW_FINISHED_A;
+ break;
+ #endif
+@@ -532,6 +545,18 @@ int ssl3_connect(SSL *s)
+ }
+ else
+ {
++ /* 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. */
++ if (s->s3->tlsext_channel_id_new)
++ {
++ ret = tls1_record_handshake_hashes_for_channel_id(s);
++ if (ret <= 0)
++ goto end;
++ }
+ if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
+ && ssl3_can_cutthrough(s)
+ && s->s3->previous_server_finished_len == 0 /* no cutthrough on renegotiation (would complicate the state machine) */
+@@ -3338,7 +3363,8 @@ err:
+ return(0);
+ }
+
+-#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
++#if !defined(OPENSSL_NO_TLSEXT)
++# if !defined(OPENSSL_NO_NEXTPROTONEG)
+ int ssl3_send_next_proto(SSL *s)
+ {
+ unsigned int len, padding_len;
+@@ -3362,7 +3388,135 @@ int ssl3_send_next_proto(SSL *s)
+
+ return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+ }
+-#endif /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
++# endif /* !OPENSSL_NO_NEXTPROTONEG */
++
++int ssl3_send_channel_id(SSL *s)
++ {
++ unsigned char *d;
++ int ret = -1, public_key_len;
++ EVP_MD_CTX md_ctx;
++ size_t sig_len;
++ ECDSA_SIG *sig = NULL;
++ unsigned char *public_key = NULL, *derp, *der_sig = NULL;
++
++ if (s->state != SSL3_ST_CW_CHANNEL_ID_A)
++ return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
++
++ if (!s->tlsext_channel_id_private && s->ctx->channel_id_cb)
++ {
++ EVP_PKEY *key = NULL;
++ s->ctx->channel_id_cb(s, &key);
++ if (key != NULL)
++ {
++ s->tlsext_channel_id_private = key;
++ }
++ }
++ if (!s->tlsext_channel_id_private)
++ {
++ s->rwstate=SSL_CHANNEL_ID_LOOKUP;
++ return (-1);
++ }
++ s->rwstate=SSL_NOTHING;
++
++ d = (unsigned char *)s->init_buf->data;
++ *(d++)=SSL3_MT_ENCRYPTED_EXTENSIONS;
++ l2n3(2 + 2 + TLSEXT_CHANNEL_ID_SIZE, d);
++ if (s->s3->tlsext_channel_id_new)
++ s2n(TLSEXT_TYPE_channel_id_new, d);
++ else
++ s2n(TLSEXT_TYPE_channel_id, d);
++ s2n(TLSEXT_CHANNEL_ID_SIZE, d);
++
++ EVP_MD_CTX_init(&md_ctx);
++
++ public_key_len = i2d_PublicKey(s->tlsext_channel_id_private, NULL);
++ if (public_key_len <= 0)
++ {
++ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY);
++ goto err;
++ }
++ /* i2d_PublicKey will produce an ANSI X9.62 public key which, for a
++ * P-256 key, is 0x04 (meaning uncompressed) followed by the x and y
++ * field elements as 32-byte, big-endian numbers. */
++ if (public_key_len != 65)
++ {
++ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_CHANNEL_ID_NOT_P256);
++ goto err;
++ }
++ public_key = OPENSSL_malloc(public_key_len);
++ if (!public_key)
++ {
++ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,ERR_R_MALLOC_FAILURE);
++ goto err;
++ }
++
++ derp = public_key;
++ i2d_PublicKey(s->tlsext_channel_id_private, &derp);
++
++ if (EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL,
++ s->tlsext_channel_id_private) != 1)
++ {
++ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_EVP_DIGESTSIGNINIT_FAILED);
++ goto err;
++ }
++
++ if (!tls1_channel_id_hash(&md_ctx, s))
++ goto err;
++
++ if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len))
++ {
++ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
++ goto err;
++ }
++
++ der_sig = OPENSSL_malloc(sig_len);
++ if (!der_sig)
++ {
++ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,ERR_R_MALLOC_FAILURE);
++ goto err;
++ }
++
++ if (!EVP_DigestSignFinal(&md_ctx, der_sig, &sig_len))
++ {
++ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
++ goto err;
++ }
++
++ derp = der_sig;
++ sig = d2i_ECDSA_SIG(NULL, (const unsigned char**) &derp, sig_len);
++ if (sig == NULL)
++ {
++ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_D2I_ECDSA_SIG);
++ goto err;
++ }
++
++ /* The first byte of public_key will be 0x4, denoting an uncompressed key. */
++ memcpy(d, public_key + 1, 64);
++ d += 64;
++ memset(d, 0, 2 * 32);
++ BN_bn2bin(sig->r, d + 32 - BN_num_bytes(sig->r));
++ d += 32;
++ BN_bn2bin(sig->s, d + 32 - BN_num_bytes(sig->s));
++ d += 32;
++
++ s->state = SSL3_ST_CW_CHANNEL_ID_B;
++ s->init_num = 4 + 2 + 2 + TLSEXT_CHANNEL_ID_SIZE;
++ s->init_off = 0;
++
++ ret = ssl3_do_write(s, SSL3_RT_HANDSHAKE);
++
++err:
++ EVP_MD_CTX_cleanup(&md_ctx);
++ if (public_key)
++ OPENSSL_free(public_key);
++ if (der_sig)
++ OPENSSL_free(der_sig);
++ if (sig)
++ ECDSA_SIG_free(sig);
++
++ return ret;
++ }
++#endif /* !OPENSSL_NO_TLSEXT */
+
+ /* Check to see if handshake is full or resumed. Usually this is just a
+ * case of checking to see if a cache hit has occurred. In the case of
+diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
+index 1865c70..f801923 100644
+--- a/ssl/s3_lib.c
++++ b/ssl/s3_lib.c
+@@ -2951,6 +2951,11 @@ int ssl3_new(SSL *s)
+ #ifndef OPENSSL_NO_SRP
+ SSL_SRP_CTX_init(s);
+ #endif
++#if !defined(OPENSSL_NO_TLSEXT)
++ s->tlsext_channel_id_enabled = s->ctx->tlsext_channel_id_enabled;
++ if (s->ctx->tlsext_channel_id_private)
++ s->tlsext_channel_id_private = EVP_PKEY_dup(s->ctx->tlsext_channel_id_private);
++#endif
+ s->method->ssl_clear(s);
+ return(1);
+ err:
+@@ -3079,6 +3084,10 @@ void ssl3_clear(SSL *s)
+ s->next_proto_negotiated_len = 0;
+ }
+ #endif
++
++#if !defined(OPENSSL_NO_TLSEXT)
++ s->s3->tlsext_channel_id_valid = 0;
++#endif
+ }
+
+ #ifndef OPENSSL_NO_SRP
+@@ -3353,6 +3362,33 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
+ ret = 1;
+ break;
+ #endif
++ case SSL_CTRL_CHANNEL_ID:
++ s->tlsext_channel_id_enabled = 1;
++ ret = 1;
++ break;
++
++ case SSL_CTRL_SET_CHANNEL_ID:
++ if (s->server)
++ break;
++ s->tlsext_channel_id_enabled = 1;
++ if (EVP_PKEY_bits(parg) != 256)
++ {
++ SSLerr(SSL_F_SSL3_CTRL,SSL_R_CHANNEL_ID_NOT_P256);
++ break;
++ }
++ if (s->tlsext_channel_id_private)
++ EVP_PKEY_free(s->tlsext_channel_id_private);
++ s->tlsext_channel_id_private = EVP_PKEY_dup((EVP_PKEY*) parg);
++ ret = 1;
++ break;
++
++ case SSL_CTRL_GET_CHANNEL_ID:
++ if (!s->server)
++ break;
++ if (!s->s3->tlsext_channel_id_valid)
++ break;
++ memcpy(parg, s->s3->tlsext_channel_id, larg < 64 ? larg : 64);
++ return 64;
+
+ #endif /* !OPENSSL_NO_TLSEXT */
+ default:
+@@ -3574,6 +3610,12 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
+ }
+ return 1;
+ }
++ case SSL_CTRL_CHANNEL_ID:
++ /* must be called on a server */
++ if (ctx->method->ssl_accept == ssl_undefined_function)
++ return 0;
++ ctx->tlsext_channel_id_enabled=1;
++ return 1;
+
+ #ifdef TLSEXT_TYPE_opaque_prf_input
+ case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG:
+@@ -3642,6 +3684,18 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
+ }
+ break;
+
++ case SSL_CTRL_SET_CHANNEL_ID:
++ ctx->tlsext_channel_id_enabled = 1;
++ if (EVP_PKEY_bits(parg) != 256)
++ {
++ SSLerr(SSL_F_SSL3_CTX_CTRL,SSL_R_CHANNEL_ID_NOT_P256);
++ break;
++ }
++ if (ctx->tlsext_channel_id_private)
++ EVP_PKEY_free(ctx->tlsext_channel_id_private);
++ ctx->tlsext_channel_id_private = EVP_PKEY_dup((EVP_PKEY*) parg);
++ break;
++
+ default:
+ return(0);
+ }
+diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
+index 323b260..6824ef6 100644
+--- a/ssl/s3_srvr.c
++++ b/ssl/s3_srvr.c
+@@ -157,8 +157,11 @@
+ #include <openssl/buffer.h>
+ #include <openssl/rand.h>
+ #include <openssl/objects.h>
++#include <openssl/ec.h>
++#include <openssl/ecdsa.h>
+ #include <openssl/evp.h>
+ #include <openssl/hmac.h>
++#include <openssl/sha.h>
+ #include <openssl/x509.h>
+ #ifndef OPENSSL_NO_DH
+ #include <openssl/dh.h>
+@@ -615,15 +618,8 @@ int ssl3_accept(SSL *s)
+ * the client uses its key from the certificate
+ * for key exchange.
+ */
+-#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
+- s->state=SSL3_ST_SR_FINISHED_A;
+-#else
+- if (s->s3->next_proto_neg_seen)
+- s->state=SSL3_ST_SR_NEXT_PROTO_A;
+- else
+- s->state=SSL3_ST_SR_FINISHED_A;
+-#endif
+ s->init_num = 0;
++ s->state=SSL3_ST_SR_POST_CLIENT_CERT;
+ }
+ else if (TLS1_get_version(s) >= TLS1_2_VERSION)
+ {
+@@ -683,16 +679,28 @@ int ssl3_accept(SSL *s)
+ ret=ssl3_get_cert_verify(s);
+ if (ret <= 0) goto end;
+
+-#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
+- s->state=SSL3_ST_SR_FINISHED_A;
+-#else
+- if (s->s3->next_proto_neg_seen)
++ s->state=SSL3_ST_SR_POST_CLIENT_CERT;
++ s->init_num=0;
++ break;
++
++ case SSL3_ST_SR_POST_CLIENT_CERT: {
++ char next_proto_neg = 0;
++ char channel_id = 0;
++#if !defined(OPENSSL_NO_TLSEXT)
++# if !defined(OPENSSL_NO_NEXTPROTONEG)
++ next_proto_neg = s->s3->next_proto_neg_seen;
++# endif
++ channel_id = s->s3->tlsext_channel_id_valid;
++#endif
++
++ if (next_proto_neg)
+ s->state=SSL3_ST_SR_NEXT_PROTO_A;
++ else if (channel_id)
++ s->state=SSL3_ST_SR_CHANNEL_ID_A;
+ else
+ s->state=SSL3_ST_SR_FINISHED_A;
+-#endif
+- s->init_num=0;
+ break;
++ }
+
+ #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ case SSL3_ST_SR_NEXT_PROTO_A:
+@@ -700,6 +708,19 @@ int ssl3_accept(SSL *s)
+ ret=ssl3_get_next_proto(s);
+ if (ret <= 0) goto end;
+ s->init_num = 0;
++ if (s->s3->tlsext_channel_id_valid)
++ s->state=SSL3_ST_SR_CHANNEL_ID_A;
++ else
++ s->state=SSL3_ST_SR_FINISHED_A;
++ break;
++#endif
++
++#if !defined(OPENSSL_NO_TLSEXT)
++ case SSL3_ST_SR_CHANNEL_ID_A:
++ case SSL3_ST_SR_CHANNEL_ID_B:
++ ret=ssl3_get_channel_id(s);
++ if (ret <= 0) goto end;
++ s->init_num = 0;
+ s->state=SSL3_ST_SR_FINISHED_A;
+ break;
+ #endif
+@@ -717,6 +738,15 @@ int ssl3_accept(SSL *s)
+ #endif
+ else
+ s->state=SSL3_ST_SW_CHANGE_A;
++ /* If this is a full handshake with ChannelID then
++ * record the hashshake hashes in |s->session| in case
++ * we need them to verify a ChannelID signature on a
++ * resumption of this session in the future. */
++ if (!s->hit && s->s3->tlsext_channel_id_new)
++ {
++ ret = tls1_record_handshake_hashes_for_channel_id(s);
++ if (ret <= 0) goto end;
++ }
+ s->init_num=0;
+ break;
+
+@@ -771,19 +801,7 @@ int ssl3_accept(SSL *s)
+ if (ret <= 0) goto end;
+ s->state=SSL3_ST_SW_FLUSH;
+ if (s->hit)
+- {
+-#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
+- s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
+-#else
+- if (s->s3->next_proto_neg_seen)
+- {
+- s->s3->flags |= SSL3_FLAGS_CCS_OK;
+- s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
+- }
+- else
+- s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
+-#endif
+- }
++ s->s3->tmp.next_state=SSL3_ST_SR_POST_CLIENT_CERT;
+ else
+ s->s3->tmp.next_state=SSL_ST_OK;
+ s->init_num=0;
+@@ -1466,6 +1487,22 @@ int ssl3_send_server_hello(SSL *s)
+
+ if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
+ {
++ /* We only accept ChannelIDs on connections with ECDHE in order
++ * to avoid a known attack while we fix ChannelID itself. */
++ if (s->s3 &&
++ s->s3->tlsext_channel_id_valid &&
++ (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kEECDH) == 0)
++ s->s3->tlsext_channel_id_valid = 0;
++
++ /* If this is a resumption and the original handshake didn't
++ * support ChannelID then we didn't record the original
++ * handshake hashes in the session and so cannot resume with
++ * ChannelIDs. */
++ if (s->hit &&
++ s->s3->tlsext_channel_id_new &&
++ s->session->original_handshake_hash_len == 0)
++ s->s3->tlsext_channel_id_valid = 0;
++
+ buf=(unsigned char *)s->init_buf->data;
+ #ifdef OPENSSL_NO_TLSEXT
+ p=s->s3->server_random;
+@@ -3632,4 +3669,145 @@ int ssl3_get_next_proto(SSL *s)
+ return 1;
+ }
+ # endif
++
++/* ssl3_get_channel_id reads and verifies a ClientID handshake message. */
++int ssl3_get_channel_id(SSL *s)
++ {
++ int ret = -1, ok;
++ long n;
++ const unsigned char *p;
++ unsigned short extension_type, extension_len;
++ EC_GROUP* p256 = NULL;
++ EC_KEY* key = NULL;
++ EC_POINT* point = NULL;
++ ECDSA_SIG sig;
++ BIGNUM x, y;
++ unsigned short expected_extension_type;
++
++ if (s->state == SSL3_ST_SR_CHANNEL_ID_A && s->init_num == 0)
++ {
++ /* The first time that we're called we take the current
++ * handshake hash and store it. */
++ EVP_MD_CTX md_ctx;
++ unsigned int len;
++
++ EVP_MD_CTX_init(&md_ctx);
++ EVP_DigestInit_ex(&md_ctx, EVP_sha256(), NULL);
++ if (!tls1_channel_id_hash(&md_ctx, s))
++ return -1;
++ len = sizeof(s->s3->tlsext_channel_id);
++ EVP_DigestFinal(&md_ctx, s->s3->tlsext_channel_id, &len);
++ EVP_MD_CTX_cleanup(&md_ctx);
++ }
++
++ n = s->method->ssl_get_message(s,
++ SSL3_ST_SR_CHANNEL_ID_A,
++ SSL3_ST_SR_CHANNEL_ID_B,
++ SSL3_MT_ENCRYPTED_EXTENSIONS,
++ 2 + 2 + TLSEXT_CHANNEL_ID_SIZE,
++ &ok);
++
++ if (!ok)
++ return((int)n);
++
++ ssl3_finish_mac(s, (unsigned char*)s->init_buf->data, s->init_num + 4);
++
++ /* s->state doesn't reflect whether ChangeCipherSpec has been received
++ * in this handshake, but s->s3->change_cipher_spec does (will be reset
++ * by ssl3_get_finished). */
++ if (!s->s3->change_cipher_spec)
++ {
++ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS);
++ return -1;
++ }
++
++ if (n != 2 + 2 + TLSEXT_CHANNEL_ID_SIZE)
++ {
++ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_INVALID_MESSAGE);
++ return -1;
++ }
++
++ p = (unsigned char *)s->init_msg;
++
++ /* The payload looks like:
++ * uint16 extension_type
++ * uint16 extension_len;
++ * uint8 x[32];
++ * uint8 y[32];
++ * uint8 r[32];
++ * uint8 s[32];
++ */
++ n2s(p, extension_type);
++ n2s(p, extension_len);
++
++ expected_extension_type = TLSEXT_TYPE_channel_id;
++ if (s->s3->tlsext_channel_id_new)
++ expected_extension_type = TLSEXT_TYPE_channel_id_new;
++
++ if (extension_type != expected_extension_type ||
++ extension_len != TLSEXT_CHANNEL_ID_SIZE)
++ {
++ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_INVALID_MESSAGE);
++ return -1;
++ }
++
++ p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
++ if (!p256)
++ {
++ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_NO_P256_SUPPORT);
++ return -1;
++ }
++
++ BN_init(&x);
++ BN_init(&y);
++ sig.r = BN_new();
++ sig.s = BN_new();
++
++ if (BN_bin2bn(p + 0, 32, &x) == NULL ||
++ BN_bin2bn(p + 32, 32, &y) == NULL ||
++ BN_bin2bn(p + 64, 32, sig.r) == NULL ||
++ BN_bin2bn(p + 96, 32, sig.s) == NULL)
++ goto err;
++
++ point = EC_POINT_new(p256);
++ if (!point ||
++ !EC_POINT_set_affine_coordinates_GFp(p256, point, &x, &y, NULL))
++ goto err;
++
++ key = EC_KEY_new();
++ if (!key ||
++ !EC_KEY_set_group(key, p256) ||
++ !EC_KEY_set_public_key(key, point))
++ goto err;
++
++ /* We stored the handshake hash in |tlsext_channel_id| the first time
++ * that we were called. */
++ switch (ECDSA_do_verify(s->s3->tlsext_channel_id, SHA256_DIGEST_LENGTH, &sig, key)) {
++ case 1:
++ break;
++ case 0:
++ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_CHANNEL_ID_SIGNATURE_INVALID);
++ s->s3->tlsext_channel_id_valid = 0;
++ goto err;
++ default:
++ s->s3->tlsext_channel_id_valid = 0;
++ goto err;
++ }
++
++ memcpy(s->s3->tlsext_channel_id, p, 64);
++ ret = 1;
++
++err:
++ BN_free(&x);
++ BN_free(&y);
++ BN_free(sig.r);
++ BN_free(sig.s);
++ if (key)
++ EC_KEY_free(key);
++ if (point)
++ EC_POINT_free(point);
++ if (p256)
++ EC_GROUP_free(p256);
++ return ret;
++ }
+ #endif
+diff --git a/ssl/ssl.h b/ssl/ssl.h
+index 944aea6..e50b8f0 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
+@@ -862,6 +869,9 @@ struct ssl_ctx_st
+ /* get client cert callback */
+ int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+
++ /* get channel id callback */
++ void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey);
++
+ /* cookie generate callback */
+ int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie,
+ unsigned int *cookie_len);
+@@ -999,6 +1009,16 @@ struct ssl_ctx_st
+ # endif
+ /* SRTP profiles we are willing to do from RFC 5764 */
+ STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
++
++ /* If true, a client will advertise the Channel ID extension and a
++ * server will echo it. */
++ char tlsext_channel_id_enabled;
++ /* tlsext_channel_id_enabled_new is a hack to support both old and new
++ * ChannelID signatures. It indicates that a client should advertise the
++ * new ChannelID extension number. */
++ char tlsext_channel_id_enabled_new;
++ /* The client's Channel ID private key. */
++ EVP_PKEY *tlsext_channel_id_private;
+ #endif
+ };
+
+@@ -1040,6 +1060,10 @@ LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
+ SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL)
+ #define SSL_CTX_sess_cache_full(ctx) \
+ SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL)
++/* SSL_CTX_enable_tls_channel_id configures a TLS server to accept TLS client
++ * IDs from clients. Returns 1 on success. */
++#define SSL_CTX_enable_tls_channel_id(ctx) \
++ SSL_CTX_ctrl(ctx,SSL_CTRL_CHANNEL_ID,0,NULL)
+
+ void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess));
+ int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, SSL_SESSION *sess);
+@@ -1056,6 +1080,8 @@ void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*cb)(const SSL *ssl,int type,
+ void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val);
+ void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
+ int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
++void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey));
++void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey);
+ #ifndef OPENSSL_NO_ENGINE
+ int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
+ #endif
+@@ -1117,5 +1143,6 @@ const char *SSL_get_psk_identity(const SSL *s);
+ #define SSL_WRITING 2
+ #define SSL_READING 3
+ #define SSL_X509_LOOKUP 4
++#define SSL_CHANNEL_ID_LOOKUP 5
+
+ /* These will only be used when doing non-blocking IO */
+@@ -1124,5 +1151,6 @@ const char *SSL_get_psk_identity(const SSL *s);
+ #define SSL_want_read(s) (SSL_want(s) == SSL_READING)
+ #define SSL_want_write(s) (SSL_want(s) == SSL_WRITING)
+ #define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
++#define SSL_want_channel_id_lookup(s) (SSL_want(s) == SSL_CHANNEL_ID_LOOKUP)
+
+ #define SSL_MAC_FLAG_READ_MAC_STREAM 1
+@@ -1373,6 +1401,13 @@ struct ssl_st
+ */
+ unsigned int tlsext_hb_pending; /* Indicates if a HeartbeatRequest is in flight */
+ unsigned int tlsext_hb_seq; /* HeartbeatRequest sequence number */
++
++ /* Copied from the SSL_CTX. For a server, means that we'll accept
++ * Channel IDs from clients. For a client, means that we'll advertise
++ * support. */
++ char tlsext_channel_id_enabled;
++ /* The client's Channel ID private key. */
++ EVP_PKEY *tlsext_channel_id_private;
+ #else
+ #define session_ctx ctx
+ #endif /* OPENSSL_NO_TLSEXT */
+@@ -1543,5 +1578,6 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
+ #define SSL_ERROR_ZERO_RETURN 6
+ #define SSL_ERROR_WANT_CONNECT 7
+ #define SSL_ERROR_WANT_ACCEPT 8
++#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP 9
+
+ #define SSL_CTRL_NEED_TMP_RSA 1
+@@ -1631,6 +1667,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
+ #define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING 86
+ #define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87
+ #endif
++#define SSL_CTRL_CHANNEL_ID 88
++#define SSL_CTRL_GET_CHANNEL_ID 89
++#define SSL_CTRL_SET_CHANNEL_ID 90
+ #endif
+
+ #define DTLS_CTRL_GET_TIMEOUT 73
+@@ -1678,6 +1717,26 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
+ #define SSL_set_tmp_ecdh(ssl,ecdh) \
+ SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+
++/* SSL_enable_tls_channel_id either configures a TLS server to accept TLS client
++ * IDs from clients, or configure a client to send TLS client IDs to server.
++ * Returns 1 on success. */
++#define SSL_enable_tls_channel_id(s) \
++ SSL_ctrl(s,SSL_CTRL_CHANNEL_ID,0,NULL)
++/* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to
++ * compatible servers. private_key must be a P-256 EVP_PKEY*. Returns 1 on
++ * success. */
++#define SSL_set1_tls_channel_id(s, private_key) \
++ SSL_ctrl(s,SSL_CTRL_SET_CHANNEL_ID,0,(void*)private_key)
++#define SSL_CTX_set1_tls_channel_id(ctx, private_key) \
++ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHANNEL_ID,0,(void*)private_key)
++/* SSL_get_tls_channel_id gets the client's TLS Channel ID from a server SSL*
++ * and copies up to the first |channel_id_len| bytes into |channel_id|. The
++ * Channel ID consists of the client's P-256 public key as an (x,y) pair where
++ * each is a 32-byte, big-endian field element. Returns 0 if the client didn't
++ * offer a Channel ID and the length of the complete Channel ID otherwise. */
++#define SSL_get_tls_channel_id(ctx, channel_id, channel_id_len) \
++ SSL_ctrl(ctx,SSL_CTRL_GET_CHANNEL_ID,channel_id_len,(void*)channel_id)
++
+ #define SSL_CTX_add_extra_chain_cert(ctx,x509) \
+ SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
+ #define SSL_CTX_get_extra_chain_certs(ctx,px509) \
+@@ -2176,6 +2235,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135
+ #define SSL_F_SSL3_GET_CERT_STATUS 289
+ #define SSL_F_SSL3_GET_CERT_VERIFY 136
++#define SSL_F_SSL3_GET_CHANNEL_ID 317
+ #define SSL_F_SSL3_GET_CLIENT_CERTIFICATE 137
+ #define SSL_F_SSL3_GET_CLIENT_HELLO 138
+ #define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE 139
+@@ -2195,6 +2255,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_F_SSL3_READ_BYTES 148
+ #define SSL_F_SSL3_READ_N 149
+ #define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST 150
++#define SSL_F_SSL3_SEND_CHANNEL_ID 318
+ #define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE 151
+ #define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE 152
+ #define SSL_F_SSL3_SEND_CLIENT_VERIFY 153
+@@ -2361,12 +2422,15 @@ void ERR_load_SSL_strings(void);
+ #define SSL_R_BIO_NOT_SET 128
+ #define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129
+ #define SSL_R_BN_LIB 130
++#define SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY 376
+ #define SSL_R_CA_DN_LENGTH_MISMATCH 131
+ #define SSL_R_CA_DN_TOO_LONG 132
+ #define SSL_R_CCS_RECEIVED_EARLY 133
+ #define SSL_R_CERTIFICATE_VERIFY_FAILED 134
+ #define SSL_R_CERT_LENGTH_MISMATCH 135
+ #define SSL_R_CHALLENGE_IS_DIFFERENT 136
++#define SSL_R_CHANNEL_ID_NOT_P256 375
++#define SSL_R_CHANNEL_ID_SIGNATURE_INVALID 371
+ #define SSL_R_CIPHER_CODE_WRONG_LENGTH 137
+ #define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138
+ #define SSL_R_CIPHER_TABLE_SRC_ERROR 139
+@@ -2379,6 +2443,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_R_CONNECTION_ID_IS_DIFFERENT 143
+ #define SSL_R_CONNECTION_TYPE_NOT_SET 144
+ #define SSL_R_COOKIE_MISMATCH 308
++#define SSL_R_D2I_ECDSA_SIG 379
+ #define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145
+ #define SSL_R_DATA_LENGTH_TOO_LONG 146
+ #define SSL_R_DECRYPTION_FAILED 147
+@@ -2396,9 +2461,12 @@ void ERR_load_SSL_strings(void);
+ #define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150
+ #define SSL_R_ERROR_GENERATING_TMP_RSA_KEY 282
+ #define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151
++#define SSL_R_EVP_DIGESTSIGNFINAL_FAILED 377
++#define SSL_R_EVP_DIGESTSIGNINIT_FAILED 378
+ #define SSL_R_EXCESSIVE_MESSAGE_SIZE 152
+ #define SSL_R_EXTRA_DATA_IN_MESSAGE 153
+ #define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154
++#define SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS 372
+ #define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 355
+ #define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 356
+ #define SSL_R_HTTPS_PROXY_REQUEST 155
+@@ -2408,6 +2476,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_R_INVALID_CHALLENGE_LENGTH 158
+ #define SSL_R_INVALID_COMMAND 280
+ #define SSL_R_INVALID_COMPRESSION_ALGORITHM 341
++#define SSL_R_INVALID_MESSAGE 374
+ #define SSL_R_INVALID_PURPOSE 278
+ #define SSL_R_INVALID_SRP_USERNAME 357
+ #define SSL_R_INVALID_STATUS_RESPONSE 328
+@@ -2462,6 +2531,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_R_NO_COMPRESSION_SPECIFIED 187
+ #define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330
+ #define SSL_R_NO_METHOD_SPECIFIED 188
++#define SSL_R_NO_P256_SUPPORT 373
+ #define SSL_R_NO_PRIVATEKEY 189
+ #define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190
+ #define SSL_R_NO_PROTOCOLS_AVAILABLE 191
+diff --git a/ssl/ssl3.h b/ssl/ssl3.h
+index cf81de0..8502628 100644
+--- a/ssl/ssl3.h
++++ b/ssl/ssl3.h
+@@ -548,6 +548,22 @@ typedef struct ssl3_state_st
+ char is_probably_safari;
+ #endif /* !OPENSSL_NO_EC */
+ #endif /* !OPENSSL_NO_TLSEXT */
++
++ /* In a client, this means that the server supported Channel ID and that
++ * a Channel ID was sent. In a server it means that we echoed support
++ * for Channel IDs and that tlsext_channel_id will be valid after the
++ * handshake. */
++ char tlsext_channel_id_valid;
++ /* tlsext_channel_id_new means that the updated Channel ID extension
++ * was negotiated. This is a temporary hack in the code to support both
++ * forms of Channel ID extension while we transition to the new format,
++ * which fixed a security issue. */
++ char tlsext_channel_id_new;
++ /* For a server:
++ * If |tlsext_channel_id_valid| is true, then this contains the
++ * verified Channel ID from the client: a P256 point, (x,y), where
++ * each are big-endian values. */
++ unsigned char tlsext_channel_id[64];
+ } SSL3_STATE;
+
+ #endif
+@@ -592,6 +608,8 @@ typedef struct ssl3_state_st
+ #define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT)
+ #define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT)
+ #endif
++#define SSL3_ST_CW_CHANNEL_ID_A (0x210|SSL_ST_CONNECT)
++#define SSL3_ST_CW_CHANNEL_ID_B (0x211|SSL_ST_CONNECT)
+ #define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT)
+ #define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT)
+ /* read from server */
+@@ -646,6 +664,9 @@ typedef struct ssl3_state_st
+ #define SSL3_ST_SR_NEXT_PROTO_A (0x210|SSL_ST_ACCEPT)
+ #define SSL3_ST_SR_NEXT_PROTO_B (0x211|SSL_ST_ACCEPT)
+ #endif
++#define SSL3_ST_SR_POST_CLIENT_CERT (0x1BF|SSL_ST_ACCEPT)
++#define SSL3_ST_SR_CHANNEL_ID_A (0x220|SSL_ST_ACCEPT)
++#define SSL3_ST_SR_CHANNEL_ID_B (0x221|SSL_ST_ACCEPT)
+ #define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT)
+ #define SSL3_ST_SR_FINISHED_B (0x1C1|SSL_ST_ACCEPT)
+ /* write to client */
+@@ -673,6 +694,7 @@ typedef struct ssl3_state_st
+ #ifndef OPENSSL_NO_NEXTPROTONEG
+ #define SSL3_MT_NEXT_PROTO 67
+ #endif
++#define SSL3_MT_ENCRYPTED_EXTENSIONS 203
+ #define DTLS1_MT_HELLO_VERIFY_REQUEST 3
+
+
+diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
+index 8bda011..e579e7c 100644
+--- a/ssl/ssl_asn1.c
++++ b/ssl/ssl_asn1.c
+@@ -118,11 +118,12 @@ typedef struct ssl_session_asn1_st
+ ASN1_OCTET_STRING srp_username;
+ #endif /* OPENSSL_NO_SRP */
++ ASN1_OCTET_STRING original_handshake_hash;
+ } SSL_SESSION_ASN1;
+
+ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
+ {
+ #define LSIZE2 (sizeof(long)*2)
+- int v1=0,v2=0,v3=0,v4=0,v5=0,v7=0,v8=0;
++ int v1=0,v2=0,v3=0,v4=0,v5=0,v7=0,v8=0,v14=0;
+ unsigned char buf[4],ibuf1[LSIZE2],ibuf2[LSIZE2];
+ unsigned char ibuf3[LSIZE2],ibuf4[LSIZE2],ibuf5[LSIZE2];
+ #ifndef OPENSSL_NO_TLSEXT
+@@ -280,4 +281,11 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
+ }
++
++ if (in->original_handshake_hash_len > 0)
++ {
++ a.original_handshake_hash.length = in->original_handshake_hash_len;
++ a.original_handshake_hash.type = V_ASN1_OCTET_STRING;
++ a.original_handshake_hash.data = in->original_handshake_hash;
++ }
+ #endif /* OPENSSL_NO_PSK */
+ #ifndef OPENSSL_NO_SRP
+ if (in->srp_username)
+@@ -335,4 +343,6 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
+ #endif /* OPENSSL_NO_SRP */
++ if (in->original_handshake_hash_len > 0)
++ M_ASN1_I2D_len_EXP_opt(&(a.original_handshake_hash),i2d_ASN1_OCTET_STRING,14,v14);
+
+ M_ASN1_I2D_seq_total();
+
+@@ -385,4 +395,6 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
+ #endif /* OPENSSL_NO_SRP */
++ if (in->original_handshake_hash_len > 0)
++ M_ASN1_I2D_put_EXP_opt(&(a.original_handshake_hash),i2d_ASN1_OCTET_STRING,14,v14);
+ M_ASN1_I2D_finish();
+ }
+
+@@ -661,5 +673,16 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
+ os.data = NULL;
+ }
+
++ os.length=0;
++ os.data=NULL;
++ M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,14);
++ if (os.data && os.length < (int)sizeof(ret->original_handshake_hash))
++ {
++ memcpy(ret->original_handshake_hash, os.data, os.length);
++ ret->original_handshake_hash_len = os.length;
++ OPENSSL_free(os.data);
++ os.data = NULL;
++ }
++
+ M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION);
+ }
+diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
+index 370fb57..b3eee4d 100644
+--- a/ssl/ssl_err.c
++++ b/ssl/ssl_err.c
+@@ -151,6 +151,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
+ {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST), "SSL3_GET_CERTIFICATE_REQUEST"},
+ {ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS), "SSL3_GET_CERT_STATUS"},
+ {ERR_FUNC(SSL_F_SSL3_GET_CERT_VERIFY), "SSL3_GET_CERT_VERIFY"},
++{ERR_FUNC(SSL_F_SSL3_GET_CHANNEL_ID), "SSL3_GET_CHANNEL_ID"},
+ {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_CERTIFICATE), "SSL3_GET_CLIENT_CERTIFICATE"},
+ {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_HELLO), "SSL3_GET_CLIENT_HELLO"},
+ {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE), "SSL3_GET_CLIENT_KEY_EXCHANGE"},
+@@ -170,6 +171,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
+ {ERR_FUNC(SSL_F_SSL3_READ_BYTES), "SSL3_READ_BYTES"},
+ {ERR_FUNC(SSL_F_SSL3_READ_N), "SSL3_READ_N"},
+ {ERR_FUNC(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST), "SSL3_SEND_CERTIFICATE_REQUEST"},
++{ERR_FUNC(SSL_F_SSL3_SEND_CHANNEL_ID), "SSL3_SEND_CHANNEL_ID"},
+ {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE), "SSL3_SEND_CLIENT_CERTIFICATE"},
+ {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE), "SSL3_SEND_CLIENT_KEY_EXCHANGE"},
+ {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_VERIFY), "SSL3_SEND_CLIENT_VERIFY"},
+@@ -339,12 +341,15 @@ static ERR_STRING_DATA SSL_str_reasons[]=
+ {ERR_REASON(SSL_R_BIO_NOT_SET) ,"bio not set"},
+ {ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG),"block cipher pad is wrong"},
+ {ERR_REASON(SSL_R_BN_LIB) ,"bn lib"},
++{ERR_REASON(SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY),"cannot serialize public key"},
+ {ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH) ,"ca dn length mismatch"},
+ {ERR_REASON(SSL_R_CA_DN_TOO_LONG) ,"ca dn too long"},
+ {ERR_REASON(SSL_R_CCS_RECEIVED_EARLY) ,"ccs received early"},
+ {ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED),"certificate verify failed"},
+ {ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH) ,"cert length mismatch"},
+ {ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT),"challenge is different"},
++{ERR_REASON(SSL_R_CHANNEL_ID_NOT_P256) ,"channel id not p256"},
++{ERR_REASON(SSL_R_CHANNEL_ID_SIGNATURE_INVALID),"Channel ID signature invalid"},
+ {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher code wrong length"},
+ {ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),"cipher or hash unavailable"},
+ {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher table src error"},
+@@ -357,6 +362,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
+ {ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT),"connection id is different"},
+ {ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET),"connection type not set"},
+ {ERR_REASON(SSL_R_COOKIE_MISMATCH) ,"cookie mismatch"},
++{ERR_REASON(SSL_R_D2I_ECDSA_SIG) ,"d2i ecdsa sig"},
+ {ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED),"data between ccs and finished"},
+ {ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG) ,"data length too long"},
+ {ERR_REASON(SSL_R_DECRYPTION_FAILED) ,"decryption failed"},
+@@ -374,9 +380,12 @@ static ERR_STRING_DATA SSL_str_reasons[]=
+ {ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG),"encrypted length too long"},
+ {ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY),"error generating tmp rsa key"},
+ {ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST),"error in received cipher list"},
++{ERR_REASON(SSL_R_EVP_DIGESTSIGNFINAL_FAILED),"evp digestsignfinal failed"},
++{ERR_REASON(SSL_R_EVP_DIGESTSIGNINIT_FAILED),"evp digestsigninit failed"},
+ {ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE),"excessive message size"},
+ {ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE) ,"extra data in message"},
+ {ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS),"got a fin before a ccs"},
++{ERR_REASON(SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS),"got Channel ID before a ccs"},
+ {ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS),"got next proto before a ccs"},
+ {ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION),"got next proto without seeing extension"},
+ {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) ,"https proxy request"},
+@@ -386,6 +395,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
+ {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
+ {ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"},
+ {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"},
++{ERR_REASON(SSL_R_INVALID_MESSAGE) ,"invalid message"},
+ {ERR_REASON(SSL_R_INVALID_PURPOSE) ,"invalid purpose"},
+ {ERR_REASON(SSL_R_INVALID_SRP_USERNAME) ,"invalid srp username"},
+ {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE),"invalid status response"},
+@@ -440,6 +450,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
+ {ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED),"no compression specified"},
+ {ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER),"Peer haven't sent GOST certificate, required for selected ciphersuite"},
+ {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED) ,"no method specified"},
++{ERR_REASON(SSL_R_NO_P256_SUPPORT) ,"no p256 support"},
+ {ERR_REASON(SSL_R_NO_PRIVATEKEY) ,"no privatekey"},
+ {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED),"no private key assigned"},
+ {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE),"no protocols available"},
+diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
+index 123f925..6938267 100644
+--- a/ssl/ssl_lib.c
++++ b/ssl/ssl_lib.c
+@@ -562,6 +562,8 @@ void SSL_free(SSL *s)
+ sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
+ if (s->tlsext_ocsp_resp)
+ OPENSSL_free(s->tlsext_ocsp_resp);
++ if (s->tlsext_channel_id_private)
++ EVP_PKEY_free(s->tlsext_channel_id_private);
+ #endif
+
+ if (s->client_CA != NULL)
+@@ -1952,6 +1954,11 @@ void SSL_CTX_free(SSL_CTX *a)
+ ssl_buf_freelist_free(a->rbuf_freelist);
+ #endif
+
++#ifndef OPENSSL_NO_TLSEXT
++ if (a->tlsext_channel_id_private)
++ EVP_PKEY_free(a->tlsext_channel_id_private);
++#endif
++
+ OPENSSL_free(a);
+ }
+
+@@ -2504,6 +2511,10 @@ int SSL_get_error(const SSL *s,int i)
+ {
+ return(SSL_ERROR_WANT_X509_LOOKUP);
+ }
++ if ((i < 0) && SSL_want_channel_id_lookup(s))
++ {
++ return(SSL_ERROR_WANT_CHANNEL_ID_LOOKUP);
++ }
+
+ if (i == 0)
+ {
+diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
+index fcc6d80..3ce3d60 100644
+--- a/ssl/ssl_locl.h
++++ b/ssl/ssl_locl.h
+@@ -378,6 +378,7 @@
+ * (currently this also goes into algorithm2) */
+ #define TLS1_STREAM_MAC 0x04
+
++#define TLSEXT_CHANNEL_ID_SIZE 128
+
+
+ /*
+@@ -1008,6 +1009,7 @@ int ssl3_check_cert_and_algorithm(SSL *s);
+ int ssl3_check_finished(SSL *s);
+ # ifndef OPENSSL_NO_NEXTPROTONEG
+ int ssl3_send_next_proto(SSL *s);
++int ssl3_send_channel_id(SSL *s);
+ # endif
+ #endif
+
+@@ -1030,6 +1032,7 @@ int ssl3_get_cert_verify(SSL *s);
+ #ifndef OPENSSL_NO_NEXTPROTONEG
+ int ssl3_get_next_proto(SSL *s);
+ #endif
++int ssl3_get_channel_id(SSL *s);
+
+ int dtls1_send_hello_request(SSL *s);
+ int dtls1_send_server_hello(SSL *s);
+@@ -1072,6 +1075,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);
+@@ -1127,6 +1131,8 @@ int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
+ 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/ssl_sess.c b/ssl/ssl_sess.c
+index 2a378c3..dd3b4a6 100644
+--- a/ssl/ssl_sess.c
++++ b/ssl/ssl_sess.c
+@@ -1151,6 +1151,17 @@ int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL * ssl, X509 ** x509 , EVP_PK
+ return ctx->client_cert_cb;
+ }
+
++void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx,
++ void (*cb)(SSL *ssl, EVP_PKEY **pkey))
++ {
++ ctx->channel_id_cb=cb;
++ }
++
++void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL * ssl, EVP_PKEY **pkey)
++ {
++ return ctx->channel_id_cb;
++ }
++
+ #ifndef OPENSSL_NO_ENGINE
+ int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e)
+ {
+diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
+index 0c4cdde..f396674 100644
+--- a/ssl/t1_enc.c
++++ b/ssl/t1_enc.c
+@@ -895,54 +895,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);
+- EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx];
+- if (!hdgst || hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
+- {
+- /* internal error: 'buf' is too small for this cipersuite! */
+- err = 1;
+- }
+- else
+- {
+- if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
+- !EVP_DigestFinal_ex(&ctx,q,&i) ||
+- (i != (unsigned int)hashsize))
+- err = 1;
+- q+=hashsize;
+- }
+- }
++ 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 bddffd9..1a56a97 100644
+--- a/ssl/t1_lib.c
++++ b/ssl/t1_lib.c
+@@ -641,6 +641,19 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
+ }
+ #endif
+
++ if (s->tlsext_channel_id_enabled)
++ {
++ /* The client advertises an emtpy extension to indicate its
++ * support for Channel ID. */
++ if (limit - ret - 4 < 0)
++ return NULL;
++ if (s->ctx->tlsext_channel_id_enabled_new)
++ s2n(TLSEXT_TYPE_channel_id_new,ret);
++ else
++ s2n(TLSEXT_TYPE_channel_id,ret);
++ s2n(0,ret);
++ }
++
+ #ifndef OPENSSL_NO_SRTP
+ if(SSL_get_srtp_profiles(s))
+ {
+@@ -881,6 +894,19 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
+ }
+ #endif
+
++ /* If the client advertised support for Channel ID, and we have it
++ * enabled, then we want to echo it back. */
++ if (s->s3->tlsext_channel_id_valid)
++ {
++ if (limit - ret - 4 < 0)
++ return NULL;
++ if (s->s3->tlsext_channel_id_new)
++ s2n(TLSEXT_TYPE_channel_id_new,ret);
++ else
++ s2n(TLSEXT_TYPE_channel_id,ret);
++ s2n(0,ret);
++ }
++
+ if ((extdatalen = ret-p-2)== 0)
+ return p;
+
+@@ -1442,6 +1468,16 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
+ }
+ #endif
+
++ else if (type == TLSEXT_TYPE_channel_id && s->tlsext_channel_id_enabled)
++ s->s3->tlsext_channel_id_valid = 1;
++
++ else if (type == TLSEXT_TYPE_channel_id_new &&
++ s->tlsext_channel_id_enabled)
++ {
++ s->s3->tlsext_channel_id_valid = 1;
++ s->s3->tlsext_channel_id_new = 1;
++ }
++
+ /* session ticket processed earlier */
+ #ifndef OPENSSL_NO_SRTP
+ else if (type == TLSEXT_TYPE_use_srtp)
+@@ -1672,6 +1708,15 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
+ s->s3->next_proto_neg_seen = 1;
+ }
+ #endif
++ else if (type == TLSEXT_TYPE_channel_id)
++ s->s3->tlsext_channel_id_valid = 1;
++
++ else if (type == TLSEXT_TYPE_channel_id_new)
++ {
++ s->s3->tlsext_channel_id_valid = 1;
++ s->s3->tlsext_channel_id_new = 1;
++ }
++
+ else if (type == TLSEXT_TYPE_renegotiate)
+ {
+ if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
+@@ -2727,3 +2772,74 @@ tls1_heartbeat(SSL *s)
+ return ret;
+ }
+ #endif
++
++#if !defined(OPENSSL_NO_TLSEXT)
++/* tls1_channel_id_hash calculates the signed data for a Channel ID on the given
++ * SSL connection and writes it to |md|.
++ */
++int
++tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
++ {
++ EVP_MD_CTX ctx;
++ unsigned char temp_digest[EVP_MAX_MD_SIZE];
++ unsigned temp_digest_len;
++ int i;
++ static const char kClientIDMagic[] = "TLS Channel ID signature";
++
++ if (s->s3->handshake_buffer)
++ if (!ssl3_digest_cached_records(s))
++ return 0;
++
++ EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
++
++ if (s->hit && s->s3->tlsext_channel_id_new)
++ {
++ 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++)
++ {
++ if (s->s3->handshake_dgst[i] == NULL)
++ continue;
++ EVP_MD_CTX_copy_ex(&ctx, s->s3->handshake_dgst[i]);
++ EVP_DigestFinal_ex(&ctx, temp_digest, &temp_digest_len);
++ EVP_DigestUpdate(md, temp_digest, temp_digest_len);
++ }
++ EVP_MD_CTX_cleanup(&ctx);
++
++ 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_new)
++ 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 c992091..12f2f21 100644
+--- a/ssl/tls1.h
++++ b/ssl/tls1.h
+@@ -254,6 +254,10 @@ extern "C" {
+ #define TLSEXT_TYPE_next_proto_neg 13172
+ #endif
+
++/* This is not an IANA defined extension number */
++#define TLSEXT_TYPE_channel_id 30031
++#define TLSEXT_TYPE_channel_id_new 30032
++
+ /* NameType value from RFC 3546 */
+ #define TLSEXT_NAMETYPE_host_name 0
+ /* status request value from RFC 3546 */
+--
+1.9.1.423.g4596e3a
+
diff --git a/patches/eng_dyn_dirs.patch b/patches/0005-eng_dyn_dirs.patch
similarity index 100%
rename from patches/eng_dyn_dirs.patch
rename to patches/0005-eng_dyn_dirs.patch
diff --git a/patches/fix_clang_build.patch b/patches/0006-fix_clang_build.patch
similarity index 100%
rename from patches/fix_clang_build.patch
rename to patches/0006-fix_clang_build.patch
diff --git a/patches/tls12_digests.patch b/patches/0007-tls12_digests.patch
similarity index 100%
rename from patches/tls12_digests.patch
rename to patches/0007-tls12_digests.patch
diff --git a/patches/alpn.patch b/patches/0008-alpn.patch
similarity index 100%
rename from patches/alpn.patch
rename to patches/0008-alpn.patch
diff --git a/patches/cbc_record_splitting.patch b/patches/0009-cbc_record_splitting.patch
similarity index 100%
rename from patches/cbc_record_splitting.patch
rename to patches/0009-cbc_record_splitting.patch
diff --git a/patches/dsa_nonce.patch b/patches/0010-dsa_nonce.patch
similarity index 100%
rename from patches/dsa_nonce.patch
rename to patches/0010-dsa_nonce.patch
diff --git a/patches/ecdhe_psk.patch b/patches/0011-ecdhe_psk.patch
similarity index 90%
rename from patches/ecdhe_psk.patch
rename to patches/0011-ecdhe_psk.patch
index 6ff2d16..f2d3d8b 100644
--- a/patches/ecdhe_psk.patch
+++ b/patches/0011-ecdhe_psk.patch
@@ -1,4 +1,4 @@
-From 8f48440b360cfe1672acdb67bc1253b30562bffd Mon Sep 17 00:00:00 2001
+From 1d43b892d27915843e5714d96de269672b5b35db Mon Sep 17 00:00:00 2001
From: Adam Langley <agl@chromium.org>
Date: Thu, 14 Nov 2013 16:12:01 -0500
Subject: Implement ECDHE-PSK-WITH-AES.
@@ -7,15 +7,16 @@
* TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256, and
* TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384.
---
- ssl/s3_clnt.c | 358 +++++++++++++++++++++----------------
+ ssl/s3_clnt.c | 360 ++++++++++++++++++++++----------------
+ ssl/s3_enc.c | 2 +-
ssl/s3_lib.c | 38 +++++-
- ssl/s3_srvr.c | 554 ++++++++++++++++++++++++++++++++--------------------------
+ ssl/s3_srvr.c | 541 ++++++++++++++++++++++++++++++++--------------------------
ssl/ssl_lib.c | 2 +-
- ssl/tls1.h | 11 ++
- 5 files changed, 583 insertions(+), 400 deletions(-)
+ ssl/tls1.h | 8 +
+ 6 files changed, 555 insertions(+), 396 deletions(-)
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
-index a3df502..67edeaa 100644
+index 8f3740f..3672cce 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -333,9 +333,10 @@ int ssl3_connect(SSL *s)
@@ -31,7 +32,7 @@
{
ret=ssl3_get_server_certificate(s);
if (ret <= 0) goto end;
-@@ -1365,7 +1366,7 @@ int ssl3_get_key_exchange(SSL *s)
+@@ -1368,7 +1369,7 @@ int ssl3_get_key_exchange(SSL *s)
omitted if no identity hint is sent. Set
session->sess_cert anyway to avoid problems
later.*/
@@ -40,7 +41,7 @@
{
s->session->sess_cert=ssl_sess_cert_new();
if (s->ctx->psk_identity_hint)
-@@ -1413,52 +1414,56 @@ int ssl3_get_key_exchange(SSL *s)
+@@ -1416,52 +1417,56 @@ int ssl3_get_key_exchange(SSL *s)
EVP_MD_CTX_init(&md_ctx);
#ifndef OPENSSL_NO_PSK
@@ -130,7 +131,7 @@
{
n2s(p,i);
param_len=i+2;
-@@ -1535,10 +1540,9 @@ int ssl3_get_key_exchange(SSL *s)
+@@ -1538,10 +1543,9 @@ int ssl3_get_key_exchange(SSL *s)
pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509);
#endif
}
@@ -142,7 +143,7 @@
{
if ((rsa=RSA_new()) == NULL)
{
-@@ -1587,9 +1591,6 @@ int ssl3_get_key_exchange(SSL *s)
+@@ -1590,9 +1594,6 @@ int ssl3_get_key_exchange(SSL *s)
s->session->sess_cert->peer_rsa_tmp=rsa;
rsa=NULL;
}
@@ -152,7 +153,7 @@
#endif
#ifndef OPENSSL_NO_DH
else if (alg_k & SSL_kEDH)
-@@ -1770,14 +1771,14 @@ int ssl3_get_key_exchange(SSL *s)
+@@ -1773,14 +1774,14 @@ int ssl3_get_key_exchange(SSL *s)
EC_POINT_free(srvr_ecpoint);
srvr_ecpoint = NULL;
}
@@ -170,7 +171,7 @@
/* p points to the next byte, there are 'n' bytes left */
-@@ -1882,8 +1883,9 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
+@@ -1885,8 +1886,9 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
}
else
{
@@ -182,15 +183,18 @@
{
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
goto err;
-@@ -2285,6 +2287,7 @@ int ssl3_send_client_key_exchange(SSL *s)
+@@ -2286,8 +2288,9 @@ int ssl3_get_server_done(SSL *s)
+ int ssl3_send_client_key_exchange(SSL *s)
+ {
unsigned char *p,*d;
- int n;
+- int n;
++ int n = 0;
unsigned long alg_k;
+ unsigned long alg_a;
#ifndef OPENSSL_NO_RSA
unsigned char *q;
EVP_PKEY *pkey=NULL;
-@@ -2299,7 +2302,11 @@ int ssl3_send_client_key_exchange(SSL *s)
+@@ -2302,7 +2305,11 @@ int ssl3_send_client_key_exchange(SSL *s)
unsigned char *encodedPoint = NULL;
int encoded_pt_len = 0;
BN_CTX * bn_ctx = NULL;
@@ -203,7 +207,7 @@
if (s->state == SSL3_ST_CW_KEY_EXCH_A)
{
-@@ -2307,7 +2314,96 @@ int ssl3_send_client_key_exchange(SSL *s)
+@@ -2310,7 +2317,96 @@ int ssl3_send_client_key_exchange(SSL *s)
p= &(d[4]);
alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
@@ -300,7 +304,7 @@
/* Fool emacs indentation */
if (0) {}
#ifndef OPENSSL_NO_RSA
-@@ -2568,14 +2664,19 @@ int ssl3_send_client_key_exchange(SSL *s)
+@@ -2571,14 +2667,19 @@ int ssl3_send_client_key_exchange(SSL *s)
/* perhaps clean things up a bit EAY EAY EAY EAY*/
}
#endif
@@ -320,9 +324,9 @@
+ unsigned int i;
+#endif
- /* Did we send out the client's
- * ECDH share for use in premaster
-@@ -2696,15 +2797,41 @@ int ssl3_send_client_key_exchange(SSL *s)
+ if (s->session->sess_cert == NULL)
+ {
+@@ -2706,15 +2807,41 @@ int ssl3_send_client_key_exchange(SSL *s)
goto err;
}
@@ -372,7 +376,7 @@
{
/* Send empty client key exch message */
n = 0;
-@@ -2732,29 +2859,42 @@ int ssl3_send_client_key_exchange(SSL *s)
+@@ -2742,29 +2869,42 @@ int ssl3_send_client_key_exchange(SSL *s)
}
/* Encode the public key */
@@ -424,7 +428,7 @@
{
/* GOST key exchange message creation */
EVP_PKEY_CTX *pkey_ctx;
-@@ -2877,89 +3017,7 @@ int ssl3_send_client_key_exchange(SSL *s)
+@@ -2887,89 +3027,7 @@ int ssl3_send_client_key_exchange(SSL *s)
}
}
#endif
@@ -511,11 +515,11 @@
- }
-#endif
- else
-+ else if (!(alg_k & SSL_kPSK))
++ else if (!(alg_k & SSL_kPSK) || ((alg_k & SSL_kPSK) && !(alg_a & SSL_aPSK)))
{
ssl3_send_alert(s, SSL3_AL_FATAL,
SSL_AD_HANDSHAKE_FAILURE);
-@@ -3264,7 +3322,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
+@@ -3274,7 +3332,7 @@ int ssl3_check_cert_and_algorithm(SSL *s)
alg_a=s->s3->tmp.new_cipher->algorithm_auth;
/* we don't have a certificate */
@@ -524,11 +528,24 @@
return(1);
sc=s->session->sess_cert;
+diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
+index 6358e1b..0dac7e7 100644
+--- a/ssl/s3_enc.c
++++ b/ssl/s3_enc.c
+@@ -734,7 +734,7 @@ int n_ssl3_mac(SSL *ssl, unsigned char *md, int send)
+ }
+
+ t=EVP_MD_CTX_size(hash);
+- if (t < 0)
++ if (t < 0 || t > 20)
+ return -1;
+ md_size=t;
+ npad=(48/md_size)*md_size;
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
-index 1d87ac5..d060a05 100644
+index 1d87ac5..77244d3 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
-@@ -2851,6 +2851,42 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
+@@ -2827,6 +2827,42 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
256,
},
@@ -571,7 +588,7 @@
#endif /* OPENSSL_NO_ECDH */
-@@ -3979,7 +4032,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
+@@ -3979,7 +3999,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
#endif /* OPENSSL_NO_KRB5 */
#ifndef OPENSSL_NO_PSK
/* with PSK there must be server callback set */
@@ -581,7 +598,7 @@
#endif /* OPENSSL_NO_PSK */
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
-index 2586751..2d67a15 100644
+index 9335eda..fe70124 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -217,6 +217,7 @@ int ssl3_accept(SSL *s)
@@ -630,7 +647,7 @@
#endif
#ifndef OPENSSL_NO_SRP
/* SRP: send ServerKeyExchange */
-@@ -1656,7 +1662,8 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -1658,7 +1664,8 @@ int ssl3_send_server_key_exchange(SSL *s)
const EVP_MD *md = NULL;
unsigned char *p,*d;
int al,i;
@@ -640,7 +657,7 @@
int n;
CERT *cert;
BIGNUM *r[4];
-@@ -1667,15 +1674,25 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -1669,15 +1676,25 @@ int ssl3_send_server_key_exchange(SSL *s)
EVP_MD_CTX_init(&md_ctx);
if (s->state == SSL3_ST_SW_KEY_EXCH_A)
{
@@ -668,7 +685,7 @@
{
rsa=cert->rsa_tmp;
if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL))
-@@ -1702,10 +1719,9 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -1704,10 +1721,9 @@ int ssl3_send_server_key_exchange(SSL *s)
r[1]=rsa->e;
s->s3->tmp.use_rsa_tmp=1;
}
@@ -680,7 +697,7 @@
{
dhp=cert->dh_tmp;
if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
-@@ -1758,10 +1774,9 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -1760,10 +1776,9 @@ int ssl3_send_server_key_exchange(SSL *s)
r[1]=dh->g;
r[2]=dh->pub_key;
}
@@ -692,7 +709,7 @@
{
const EC_GROUP *group;
-@@ -1874,7 +1889,7 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -1876,7 +1891,7 @@ int ssl3_send_server_key_exchange(SSL *s)
* to encode the entire ServerECDHParams
* structure.
*/
@@ -701,7 +718,7 @@
/* We'll generate the serverKeyExchange message
* explicitly so we can set these to NULLs
-@@ -1884,18 +1899,9 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -1886,18 +1901,9 @@ int ssl3_send_server_key_exchange(SSL *s)
r[2]=NULL;
r[3]=NULL;
}
@@ -721,7 +738,7 @@
{
if ((s->srp_ctx.N == NULL) ||
(s->srp_ctx.g == NULL) ||
-@@ -1910,8 +1916,8 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -1912,8 +1918,8 @@ int ssl3_send_server_key_exchange(SSL *s)
r[2]=s->srp_ctx.s;
r[3]=s->srp_ctx.B;
}
@@ -731,7 +748,7 @@
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
-@@ -1921,15 +1927,16 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -1923,15 +1929,16 @@ int ssl3_send_server_key_exchange(SSL *s)
{
nr[i]=BN_num_bytes(r[i]);
#ifndef OPENSSL_NO_SRP
@@ -751,7 +768,7 @@
{
if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher,&md))
== NULL)
-@@ -1956,7 +1963,7 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -1958,7 +1965,7 @@ int ssl3_send_server_key_exchange(SSL *s)
for (i=0; i < 4 && r[i] != NULL; i++)
{
#ifndef OPENSSL_NO_SRP
@@ -760,7 +777,7 @@
{
*p = nr[i];
p++;
-@@ -1968,8 +1975,32 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -1970,8 +1977,32 @@ int ssl3_send_server_key_exchange(SSL *s)
p+=nr[i];
}
@@ -794,7 +811,7 @@
{
/* XXX: For now, we only support named (not generic) curves.
* In this situation, the serverKeyExchange message has:
-@@ -1992,17 +2023,7 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -1994,17 +2025,7 @@ int ssl3_send_server_key_exchange(SSL *s)
encodedPoint = NULL;
p += encodedlen;
}
@@ -813,7 +830,7 @@
/* not anonymous */
if (pkey != NULL)
-@@ -2039,7 +2060,7 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -2041,7 +2062,7 @@ int ssl3_send_server_key_exchange(SSL *s)
n+=u+2;
}
else
@@ -822,7 +839,7 @@
if (md)
{
/* For TLS1.2 and later send signature
-@@ -2208,6 +2229,7 @@ int ssl3_get_client_key_exchange(SSL *s)
+@@ -2215,6 +2236,7 @@ int ssl3_get_client_key_exchange(SSL *s)
int i,al,ok;
long n;
unsigned long alg_k;
@@ -830,7 +847,7 @@
unsigned char *p;
#ifndef OPENSSL_NO_RSA
RSA *rsa=NULL;
-@@ -2225,7 +2247,11 @@ int ssl3_get_client_key_exchange(SSL *s)
+@@ -2232,7 +2254,11 @@ int ssl3_get_client_key_exchange(SSL *s)
EC_KEY *srvr_ecdh = NULL;
EVP_PKEY *clnt_pub_pkey = NULL;
EC_POINT *clnt_ecpoint = NULL;
@@ -843,7 +860,7 @@
#endif
n=s->method->ssl_get_message(s,
-@@ -2239,7 +2265,106 @@ int ssl3_get_client_key_exchange(SSL *s)
+@@ -2246,7 +2272,106 @@ int ssl3_get_client_key_exchange(SSL *s)
p=(unsigned char *)s->init_msg;
alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
@@ -950,7 +967,7 @@
#ifndef OPENSSL_NO_RSA
if (alg_k & SSL_kRSA)
{
-@@ -2403,10 +2528,9 @@ int ssl3_get_client_key_exchange(SSL *s)
+@@ -2410,10 +2535,9 @@ int ssl3_get_client_key_exchange(SSL *s)
p,sizeof(rand_premaster_secret));
OPENSSL_cleanse(p,sizeof(rand_premaster_secret));
}
@@ -962,7 +979,7 @@
{
n2s(p,i);
if (n != i+2)
-@@ -2467,10 +2591,9 @@ int ssl3_get_client_key_exchange(SSL *s)
+@@ -2474,10 +2598,9 @@ int ssl3_get_client_key_exchange(SSL *s)
s->session->master_key,p,i);
OPENSSL_cleanse(p,i);
}
@@ -974,7 +991,7 @@
{
krb5_error_code krb5rc;
krb5_data enc_ticket;
-@@ -2659,17 +2782,20 @@ int ssl3_get_client_key_exchange(SSL *s)
+@@ -2666,17 +2789,20 @@ int ssl3_get_client_key_exchange(SSL *s)
** if (s->kssl_ctx) s->kssl_ctx = NULL;
*/
}
@@ -998,7 +1015,7 @@
/* initialize structures for server's ECDH key pair */
if ((srvr_ecdh = EC_KEY_new()) == NULL)
-@@ -2765,7 +2891,7 @@ int ssl3_get_client_key_exchange(SSL *s)
+@@ -2772,7 +2898,7 @@ int ssl3_get_client_key_exchange(SSL *s)
}
/* Get encoded point length */
@@ -1007,7 +1024,7 @@
p += 1;
if (n != 1 + i)
{
-@@ -2807,223 +2933,155 @@ int ssl3_get_client_key_exchange(SSL *s)
+@@ -2814,214 +2940,145 @@ int ssl3_get_client_key_exchange(SSL *s)
EC_KEY_free(srvr_ecdh);
BN_CTX_free(bn_ctx);
EC_KEY_free(s->s3->tmp.ecdh);
@@ -1135,26 +1152,14 @@
+ OPENSSL_free(pre_ms);
}
- else
+-#endif
+-#ifndef OPENSSL_NO_SRP
+- if (alg_k & SSL_kSRP)
+#endif /* OPENSSL_NO_PSK */
+ if (!(alg_a & SSL_aPSK))
-+ {
-+ /* Compute the master secret */
-+ s->session->master_key_length = s->method->ssl3_enc \
-+ -> generate_master_secret(s,
-+ s->session->master_key, p, i);
-+ }
-+
-+ OPENSSL_cleanse(p, i);
-+ }
- #endif
- #ifndef OPENSSL_NO_SRP
-- if (alg_k & SSL_kSRP)
-- {
+ {
- int param_len;
-+ else if (alg_k & SSL_kSRP)
-+ {
-+ int param_len;
-
+-
- n2s(p,i);
- param_len=i+2;
- if (param_len > n)
@@ -1177,6 +1182,26 @@
- ERR_R_MALLOC_FAILURE);
- goto err;
- }
++ /* Compute the master secret */
++ s->session->master_key_length = s->method->ssl3_enc \
++ -> generate_master_secret(s,
++ s->session->master_key, p, i);
++ }
+
+- if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0)
+- {
+- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+- goto err;
+- }
++ OPENSSL_cleanse(p, i);
++ }
++#endif
++#ifndef OPENSSL_NO_SRP
++ else if (alg_k & SSL_kSRP)
++ {
++ int param_len;
+
+- p+=i;
+ n2s(p,i);
+ param_len=i+2;
+ if (param_len > n)
@@ -1198,77 +1223,19 @@
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
-+ }
-
-- if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0)
-- {
-- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
-- goto err;
-- }
-+ if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0)
-+ {
-+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
-+ goto err;
-+ }
-
-- p+=i;
-+ p+=i;
-+ }
-+#endif /* OPENSSL_NO_SRP */
-+ else if (alg_k & SSL_kGOST)
-+ {
-+ int ret = 0;
-+ EVP_PKEY_CTX *pkey_ctx;
-+ EVP_PKEY *client_pub_pkey = NULL, *pk = NULL;
-+ unsigned char premaster_secret[32], *start;
-+ size_t outlen=32, inlen;
-+ unsigned long alg_a;
-+
-+ /* Get our certificate private key*/
-+ alg_a = s->s3->tmp.new_cipher->algorithm_auth;
-+ if (alg_a & SSL_aGOST94)
-+ pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey;
-+ else if (alg_a & SSL_aGOST01)
-+ pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
-+
-+ pkey_ctx = EVP_PKEY_CTX_new(pk,NULL);
-+ EVP_PKEY_decrypt_init(pkey_ctx);
-+ /* If client certificate is present and is of the same type, maybe
-+ * use it for key exchange. Don't mind errors from
-+ * EVP_PKEY_derive_set_peer, because it is completely valid to use
-+ * a client certificate for authorization only. */
-+ client_pub_pkey = X509_get_pubkey(s->session->peer);
-+ if (client_pub_pkey)
-+ {
-+ if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0)
-+ ERR_clear_error();
-+ }
-+ /* Decrypt session key */
-+ if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED)))
-+ {
-+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
-+ goto gerr;
-+ }
-+ if (p[1] == 0x81)
-+ {
-+ start = p+3;
-+ inlen = p[2];
-+ }
-+ else if (p[1] < 0x80)
-+ {
-+ start = p+2;
-+ inlen = p[1];
}
- else
+- else
-#endif /* OPENSSL_NO_SRP */
- if (alg_k & SSL_kGOST)
- {
+- {
- int ret = 0;
- EVP_PKEY_CTX *pkey_ctx;
- EVP_PKEY *client_pub_pkey = NULL, *pk = NULL;
- unsigned char premaster_secret[32], *start;
- size_t outlen=32, inlen;
- unsigned long alg_a;
+- int Ttag, Tclass;
+- long Tlen;
-
- /* Get our certificate private key*/
- alg_a = s->s3->tmp.new_cipher->algorithm_auth;
@@ -1276,7 +1243,7 @@
- pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey;
- else if (alg_a & SSL_aGOST01)
- pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
--
+
- pkey_ctx = EVP_PKEY_CTX_new(pk,NULL);
- EVP_PKEY_decrypt_init(pkey_ctx);
- /* If client certificate is present and is of the same type, maybe
@@ -1290,31 +1257,21 @@
- ERR_clear_error();
- }
- /* Decrypt session key */
-- if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED)))
+- if (ASN1_get_object((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, n) != V_ASN1_CONSTRUCTED ||
+- Ttag != V_ASN1_SEQUENCE ||
+- Tclass != V_ASN1_UNIVERSAL)
- {
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
- goto gerr;
- }
-- if (p[1] == 0x81)
-- {
-- start = p+3;
-- inlen = p[2];
-- }
-- else if (p[1] < 0x80)
-- {
-- start = p+2;
-- inlen = p[1];
-- }
-- else
-- {
-- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
-- goto gerr;
-- }
+- start = p;
+- inlen = Tlen;
- if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0)
-+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
-+ goto gerr;
++ if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0)
++ {
++ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
++ goto err;
+ }
-+ if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0)
- {
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
@@ -1336,6 +1293,50 @@
- return ret;
- else
- goto err;
++ p+=i;
++ }
++#endif /* OPENSSL_NO_SRP */
++ else if (alg_k & SSL_kGOST)
++ {
++ int ret = 0;
++ EVP_PKEY_CTX *pkey_ctx;
++ EVP_PKEY *client_pub_pkey = NULL, *pk = NULL;
++ unsigned char premaster_secret[32], *start;
++ size_t outlen=32, inlen;
++ unsigned long alg_a;
++ int Ttag, Tclass;
++ long Tlen;
++
++ /* Get our certificate private key*/
++ alg_a = s->s3->tmp.new_cipher->algorithm_auth;
++ if (alg_a & SSL_aGOST94)
++ pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey;
++ else if (alg_a & SSL_aGOST01)
++ pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
++
++ pkey_ctx = EVP_PKEY_CTX_new(pk,NULL);
++ EVP_PKEY_decrypt_init(pkey_ctx);
++ /* If client certificate is present and is of the same type, maybe
++ * use it for key exchange. Don't mind errors from
++ * EVP_PKEY_derive_set_peer, because it is completely valid to use
++ * a client certificate for authorization only. */
++ client_pub_pkey = X509_get_pubkey(s->session->peer);
++ if (client_pub_pkey)
++ {
++ if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0)
++ ERR_clear_error();
++ }
++ /* Decrypt session key */
++ if (ASN1_get_object((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, n) != V_ASN1_CONSTRUCTED ||
++ Ttag != V_ASN1_SEQUENCE ||
++ Tclass != V_ASN1_UNIVERSAL)
++ {
++ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
++ goto gerr;
++ }
++ start = p;
++ inlen = Tlen;
++ if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0)
+ {
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
+ goto gerr;
@@ -1362,10 +1363,10 @@
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
-index ec54418..48fb9ef 100644
+index 0fda4ca..6c57d2a 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
-@@ -1420,7 +1420,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
+@@ -1424,7 +1424,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
#endif /* OPENSSL_NO_KRB5 */
#ifndef OPENSSL_NO_PSK
/* with PSK there must be client callback set */
@@ -1400,6 +1401,5 @@
#define TLS_CT_RSA_SIGN 1
#define TLS_CT_DSS_SIGN 2
#define TLS_CT_RSA_FIXED_DH 3
---
-1.9.1.423.g4596e3a
+2.0.0.526.g5318336
diff --git a/patches/wincrypt.patch b/patches/0012-wincrypt.patch
similarity index 100%
rename from patches/wincrypt.patch
rename to patches/0012-wincrypt.patch
diff --git a/patches/tls_psk_hint.patch b/patches/0013-tls_psk_hint.patch
similarity index 93%
rename from patches/tls_psk_hint.patch
rename to patches/0013-tls_psk_hint.patch
index 0fc4322..4746b78 100644
--- a/patches/tls_psk_hint.patch
+++ b/patches/0013-tls_psk_hint.patch
@@ -1,4 +1,4 @@
-From bcba3efc4c4276f8f7437c078d125756537aa790 Mon Sep 17 00:00:00 2001
+From 9c14752f8872401de413fb46a96146b0d6bf926e Mon Sep 17 00:00:00 2001
From: Alex Klyubin <klyubin@google.com>
Date: Tue, 8 Apr 2014 16:02:24 -0700
Subject: tls_psk_hint
@@ -84,7 +84,7 @@
OPENSSL_free(s->session->psk_identity);
s->session->psk_identity = BUF_strdup(identity);
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
-index 9975e20..09f4762 100644
+index 1384ab0..c181db6 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -471,7 +471,7 @@ int dtls1_accept(SSL *s)
@@ -105,7 +105,7 @@
}
else
#endif /* !OPENSSL_NO_PSK */
-@@ -1364,9 +1364,9 @@ int dtls1_send_server_key_exchange(SSL *s)
+@@ -1365,9 +1365,9 @@ int dtls1_send_server_key_exchange(SSL *s)
if (type & SSL_kPSK)
{
/* copy PSK identity hint */
@@ -119,10 +119,10 @@
#endif
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
-index 34a3342..51556e6 100644
+index 12c3fe8..17367a2 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
-@@ -1372,9 +1372,11 @@ int ssl3_get_key_exchange(SSL *s)
+@@ -1374,9 +1374,11 @@ int ssl3_get_key_exchange(SSL *s)
if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK)
{
s->session->sess_cert=ssl_sess_cert_new();
@@ -137,7 +137,7 @@
}
#endif
s->s3->tmp.reuse_message=1;
-@@ -1424,7 +1426,11 @@ int ssl3_get_key_exchange(SSL *s)
+@@ -1426,7 +1428,11 @@ int ssl3_get_key_exchange(SSL *s)
al=SSL_AD_HANDSHAKE_FAILURE;
n2s(p,i);
param_len=i+2;
@@ -150,7 +150,7 @@
if (i != 0)
{
/* Store PSK identity hint for later use, hint is used
-@@ -1450,10 +1456,8 @@ int ssl3_get_key_exchange(SSL *s)
+@@ -1452,10 +1458,8 @@ int ssl3_get_key_exchange(SSL *s)
* NULL-terminated string. */
memcpy(tmp_id_hint, p, i);
memset(tmp_id_hint+i, 0, PSK_MAX_IDENTITY_LEN+1-i);
@@ -163,7 +163,7 @@
{
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
goto f_err;
-@@ -2336,7 +2340,7 @@ int ssl3_send_client_key_exchange(SSL *s)
+@@ -2338,7 +2342,7 @@ int ssl3_send_client_key_exchange(SSL *s)
goto err;
}
@@ -172,7 +172,7 @@
identity, PSK_MAX_IDENTITY_LEN, psk, sizeof(psk));
if (psk_len > PSK_MAX_PSK_LEN)
{
-@@ -2372,21 +2376,6 @@ int ssl3_send_client_key_exchange(SSL *s)
+@@ -2374,21 +2378,6 @@ int ssl3_send_client_key_exchange(SSL *s)
n += 2;
}
@@ -195,7 +195,7 @@
OPENSSL_free(s->session->psk_identity);
s->session->psk_identity = BUF_strdup(identity);
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
-index 77015e6..fd5c9bc 100644
+index d6f1a35..c360337 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -492,7 +492,7 @@ int ssl3_accept(SSL *s)
@@ -207,7 +207,7 @@
#endif
#ifndef OPENSSL_NO_SRP
/* SRP: send ServerKeyExchange */
-@@ -1700,6 +1700,10 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -1702,6 +1702,10 @@ int ssl3_send_server_key_exchange(SSL *s)
int curve_id = 0;
BN_CTX *bn_ctx = NULL;
#endif
@@ -218,7 +218,7 @@
EVP_PKEY *pkey;
const EVP_MD *md = NULL;
unsigned char *p,*d;
-@@ -1728,9 +1732,12 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -1730,9 +1734,12 @@ int ssl3_send_server_key_exchange(SSL *s)
if (alg_a & SSL_aPSK)
{
/* size for PSK identity hint */
@@ -234,7 +234,7 @@
}
#endif /* !OPENSSL_NO_PSK */
#ifndef OPENSSL_NO_RSA
-@@ -2023,20 +2030,12 @@ int ssl3_send_server_key_exchange(SSL *s)
+@@ -2025,20 +2032,12 @@ int ssl3_send_server_key_exchange(SSL *s)
#ifndef OPENSSL_NO_PSK
if (alg_a & SSL_aPSK)
{
@@ -260,7 +260,7 @@
}
}
#endif /* OPENSSL_NO_PSK */
-@@ -2386,17 +2385,6 @@ int ssl3_get_client_key_exchange(SSL *s)
+@@ -2393,17 +2392,6 @@ int ssl3_get_client_key_exchange(SSL *s)
goto psk_err;
}
@@ -279,10 +279,10 @@
n -= (i + 2);
psk_err = 0;
diff --git a/ssl/ssl.h b/ssl/ssl.h
-index c5675c0..c2fb716 100644
+index a7e1455..f044cd1 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
-@@ -1439,6 +1439,10 @@ struct ssl_st
+@@ -1441,6 +1441,10 @@ struct ssl_st
#endif /* OPENSSL_NO_KRB5 */
#ifndef OPENSSL_NO_PSK
@@ -294,7 +294,7 @@
unsigned int max_identity_len, unsigned char *psk,
unsigned int max_psk_len);
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
-index b8bebb4..e17bb55 100644
+index 3e49cab..cf24292 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -388,6 +388,13 @@ SSL *SSL_new(SSL_CTX *ctx)
@@ -323,7 +323,7 @@
if (s->client_CA != NULL)
sk_X509_NAME_pop_free(s->client_CA,X509_NAME_free);
-@@ -3357,32 +3369,54 @@ int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint)
+@@ -3361,32 +3373,54 @@ int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint)
if (s == NULL)
return 0;
@@ -413,5 +413,5 @@
else
{
--
-1.9.1.423.g4596e3a
+2.0.0.526.g5318336
diff --git a/patches/arm_asm.patch b/patches/0014-arm_asm.patch
similarity index 100%
rename from patches/arm_asm.patch
rename to patches/0014-arm_asm.patch
diff --git a/patches/psk_client_callback_128_byte_id_bug.patch b/patches/0015-psk_client_callback_128_byte_id_bug.patch
similarity index 86%
rename from patches/psk_client_callback_128_byte_id_bug.patch
rename to patches/0015-psk_client_callback_128_byte_id_bug.patch
index 442ffff..3b06e71 100644
--- a/patches/psk_client_callback_128_byte_id_bug.patch
+++ b/patches/0015-psk_client_callback_128_byte_id_bug.patch
@@ -1,4 +1,4 @@
-From 53ed330060d3e9e386cad114fae871b4506adb62 Mon Sep 17 00:00:00 2001
+From c8b1f7ec56704c1116795aec9ca61db654b433bf Mon Sep 17 00:00:00 2001
From: Alex Klyubin <klyubin@google.com>
Date: Mon, 19 May 2014 11:27:33 -0700
Subject: psk_client_callback, 128-byte id bug.
@@ -24,10 +24,10 @@
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
-index 745c41d..84b51e9 100644
+index 03b96e8..0e22afc 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
-@@ -2326,7 +2326,8 @@ int ssl3_send_client_key_exchange(SSL *s)
+@@ -2328,7 +2328,8 @@ int ssl3_send_client_key_exchange(SSL *s)
#ifndef OPENSSL_NO_PSK
if (alg_a & SSL_aPSK)
{
@@ -37,7 +37,7 @@
unsigned char *t = NULL;
unsigned char pre_ms[PSK_MAX_PSK_LEN*2+4];
unsigned int pre_ms_len = 0;
-@@ -2340,8 +2341,9 @@ int ssl3_send_client_key_exchange(SSL *s)
+@@ -2342,8 +2343,9 @@ int ssl3_send_client_key_exchange(SSL *s)
goto err;
}
@@ -48,7 +48,7 @@
if (psk_len > PSK_MAX_PSK_LEN)
{
SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
-@@ -2354,6 +2356,13 @@ int ssl3_send_client_key_exchange(SSL *s)
+@@ -2356,6 +2358,13 @@ int ssl3_send_client_key_exchange(SSL *s)
SSL_R_PSK_IDENTITY_NOT_FOUND);
goto psk_err;
}
@@ -62,7 +62,7 @@
if (!(alg_k & SSL_kEECDH))
{
-@@ -2370,10 +2379,9 @@ int ssl3_send_client_key_exchange(SSL *s)
+@@ -2372,10 +2381,9 @@ int ssl3_send_client_key_exchange(SSL *s)
s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key,
pre_ms, pre_ms_len);
@@ -77,5 +77,5 @@
if (s->session->psk_identity != NULL)
--
-1.9.1.423.g4596e3a
+2.0.0.526.g5318336
diff --git a/patches/channelid.patch b/patches/channelid.patch
deleted file mode 100644
index 4eb025a..0000000
--- a/patches/channelid.patch
+++ /dev/null
@@ -1,983 +0,0 @@
---- openssl-1.0.1e.orig/crypto/evp/evp.h 2013-03-05 18:49:33.183296743 +0000
-+++ openssl-1.0.1e/crypto/evp/evp.h 2013-03-05 18:49:33.373298798 +0000
-@@ -921,6 +921,7 @@ struct ec_key_st *EVP_PKEY_get1_EC_KEY(E
- #endif
-
- EVP_PKEY * EVP_PKEY_new(void);
-+EVP_PKEY * EVP_PKEY_dup(EVP_PKEY *pkey);
- void EVP_PKEY_free(EVP_PKEY *pkey);
-
- EVP_PKEY * d2i_PublicKey(int type,EVP_PKEY **a, const unsigned char **pp,
---- openssl-1.0.1e.orig/crypto/evp/p_lib.c 2013-03-05 18:49:33.183296743 +0000
-+++ openssl-1.0.1e/crypto/evp/p_lib.c 2013-03-05 18:49:33.373298798 +0000
-@@ -200,6 +200,12 @@ EVP_PKEY *EVP_PKEY_new(void)
- return(ret);
- }
-
-+EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey)
-+ {
-+ CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
-+ return pkey;
-+ }
-+
- /* Setup a public key ASN1 method and ENGINE from a NID or a string.
- * If pkey is NULL just return 1 or 0 if the algorithm exists.
- */
---- openssl-1.0.1e.orig/ssl/s3_both.c 2013-03-05 18:49:33.233297282 +0000
-+++ openssl-1.0.1e/ssl/s3_both.c 2013-03-05 18:49:33.413299231 +0000
-@@ -555,7 +555,8 @@ long ssl3_get_message(SSL *s, int st1, i
- #endif
-
- /* Feed this message into MAC computation. */
-- ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
-+ if (*(unsigned char*)s->init_buf->data != SSL3_MT_ENCRYPTED_EXTENSIONS)
-+ ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
- if (s->msg_callback)
- s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg);
- *ok=1;
---- openssl-1.0.1e.orig/ssl/s3_clnt.c 2013-03-05 18:49:33.233297282 +0000
-+++ openssl-1.0.1e/ssl/s3_clnt.c 2013-03-05 18:49:33.413299231 +0000
-@@ -477,13 +477,14 @@ int ssl3_connect(SSL *s)
- SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
- if (ret <= 0) goto end;
-
--#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
- s->state=SSL3_ST_CW_FINISHED_A;
--#else
-+#if !defined(OPENSSL_NO_TLSEXT)
-+ if (s->s3->tlsext_channel_id_valid)
-+ s->state=SSL3_ST_CW_CHANNEL_ID_A;
-+# if !defined(OPENSSL_NO_NEXTPROTONEG)
- if (s->s3->next_proto_neg_seen)
- s->state=SSL3_ST_CW_NEXT_PROTO_A;
-- else
-- s->state=SSL3_ST_CW_FINISHED_A;
-+# endif
- #endif
- s->init_num=0;
-
-@@ -517,6 +518,18 @@ int ssl3_connect(SSL *s)
- case SSL3_ST_CW_NEXT_PROTO_B:
- ret=ssl3_send_next_proto(s);
- if (ret <= 0) goto end;
-+ if (s->s3->tlsext_channel_id_valid)
-+ s->state=SSL3_ST_CW_CHANNEL_ID_A;
-+ else
-+ s->state=SSL3_ST_CW_FINISHED_A;
-+ break;
-+#endif
-+
-+#if !defined(OPENSSL_NO_TLSEXT)
-+ case SSL3_ST_CW_CHANNEL_ID_A:
-+ case SSL3_ST_CW_CHANNEL_ID_B:
-+ ret=ssl3_send_channel_id(s);
-+ if (ret <= 0) goto end;
- s->state=SSL3_ST_CW_FINISHED_A;
- break;
- #endif
-@@ -3362,7 +3375,8 @@ err:
- return(0);
- }
-
--#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-+#if !defined(OPENSSL_NO_TLSEXT)
-+# if !defined(OPENSSL_NO_NEXTPROTONEG)
- int ssl3_send_next_proto(SSL *s)
- {
- unsigned int len, padding_len;
-@@ -3386,7 +3400,116 @@ int ssl3_send_next_proto(SSL *s)
-
- return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
- }
--#endif /* !OPENSSL_NO_TLSEXT && !OPENSSL_NO_NEXTPROTONEG */
-+# endif /* !OPENSSL_NO_NEXTPROTONEG */
-+
-+int ssl3_send_channel_id(SSL *s)
-+ {
-+ unsigned char *d;
-+ int ret = -1, public_key_len;
-+ EVP_MD_CTX md_ctx;
-+ size_t sig_len;
-+ ECDSA_SIG *sig = NULL;
-+ unsigned char *public_key = NULL, *derp, *der_sig = NULL;
-+
-+ if (s->state != SSL3_ST_CW_CHANNEL_ID_A)
-+ return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
-+
-+ d = (unsigned char *)s->init_buf->data;
-+ *(d++)=SSL3_MT_ENCRYPTED_EXTENSIONS;
-+ l2n3(2 + 2 + TLSEXT_CHANNEL_ID_SIZE, d);
-+ s2n(TLSEXT_TYPE_channel_id, d);
-+ s2n(TLSEXT_CHANNEL_ID_SIZE, d);
-+
-+ EVP_MD_CTX_init(&md_ctx);
-+
-+ public_key_len = i2d_PublicKey(s->tlsext_channel_id_private, NULL);
-+ if (public_key_len <= 0)
-+ {
-+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY);
-+ goto err;
-+ }
-+ // i2d_PublicKey will produce an ANSI X9.62 public key which, for a
-+ // P-256 key, is 0x04 (meaning uncompressed) followed by the x and y
-+ // field elements as 32-byte, big-endian numbers.
-+ if (public_key_len != 65)
-+ {
-+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_CHANNEL_ID_NOT_P256);
-+ goto err;
-+ }
-+ public_key = OPENSSL_malloc(public_key_len);
-+ if (!public_key)
-+ {
-+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ derp = public_key;
-+ i2d_PublicKey(s->tlsext_channel_id_private, &derp);
-+
-+ if (EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL,
-+ s->tlsext_channel_id_private) != 1)
-+ {
-+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_EVP_DIGESTSIGNINIT_FAILED);
-+ goto err;
-+ }
-+
-+ if (!tls1_channel_id_hash(&md_ctx, s))
-+ goto err;
-+
-+ if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len))
-+ {
-+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
-+ goto err;
-+ }
-+
-+ der_sig = OPENSSL_malloc(sig_len);
-+ if (!der_sig)
-+ {
-+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,ERR_R_MALLOC_FAILURE);
-+ goto err;
-+ }
-+
-+ if (!EVP_DigestSignFinal(&md_ctx, der_sig, &sig_len))
-+ {
-+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
-+ goto err;
-+ }
-+
-+ derp = der_sig;
-+ sig = d2i_ECDSA_SIG(NULL, (const unsigned char**)&derp, sig_len);
-+ if (sig == NULL)
-+ {
-+ SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_D2I_ECDSA_SIG);
-+ goto err;
-+ }
-+
-+ // The first byte of public_key will be 0x4, denoting an uncompressed key.
-+ memcpy(d, public_key + 1, 64);
-+ d += 64;
-+ memset(d, 0, 2 * 32);
-+ BN_bn2bin(sig->r, d + 32 - BN_num_bytes(sig->r));
-+ d += 32;
-+ BN_bn2bin(sig->s, d + 32 - BN_num_bytes(sig->s));
-+ d += 32;
-+
-+ s->state = SSL3_ST_CW_CHANNEL_ID_B;
-+ s->init_num = 4 + 2 + 2 + TLSEXT_CHANNEL_ID_SIZE;
-+ s->init_off = 0;
-+
-+ ret = ssl3_do_write(s, SSL3_RT_HANDSHAKE);
-+
-+err:
-+ EVP_MD_CTX_cleanup(&md_ctx);
-+ if (public_key)
-+ OPENSSL_free(public_key);
-+ if (der_sig)
-+ OPENSSL_free(der_sig);
-+ if (sig)
-+ ECDSA_SIG_free(sig);
-+
-+ return ret;
-+ }
-+#endif /* !OPENSSL_NO_TLSEXT */
-
- /* Check to see if handshake is full or resumed. Usually this is just a
- * case of checking to see if a cache hit has occurred. In the case of
---- openssl-1.0.1e.orig/ssl/s3_lib.c 2013-03-05 18:49:33.223297173 +0000
-+++ openssl-1.0.1e/ssl/s3_lib.c 2013-03-05 18:49:33.413299231 +0000
-@@ -2951,6 +2951,11 @@ int ssl3_new(SSL *s)
- #ifndef OPENSSL_NO_SRP
- SSL_SRP_CTX_init(s);
- #endif
-+#if !defined(OPENSSL_NO_TLSEXT)
-+ s->tlsext_channel_id_enabled = s->ctx->tlsext_channel_id_enabled;
-+ if (s->ctx->tlsext_channel_id_private)
-+ s->tlsext_channel_id_private = EVP_PKEY_dup(s->ctx->tlsext_channel_id_private);
-+#endif
- s->method->ssl_clear(s);
- return(1);
- err:
-@@ -3074,6 +3079,10 @@ void ssl3_clear(SSL *s)
- s->next_proto_negotiated_len = 0;
- }
- #endif
-+
-+#if !defined(OPENSSL_NO_TLSEXT)
-+ s->s3->tlsext_channel_id_valid = 0;
-+#endif
- }
-
- #ifndef OPENSSL_NO_SRP
-@@ -3348,6 +3357,35 @@ long ssl3_ctrl(SSL *s, int cmd, long lar
- ret = 1;
- break;
- #endif
-+ case SSL_CTRL_CHANNEL_ID:
-+ if (!s->server)
-+ break;
-+ s->tlsext_channel_id_enabled = 1;
-+ ret = 1;
-+ break;
-+
-+ case SSL_CTRL_SET_CHANNEL_ID:
-+ if (s->server)
-+ break;
-+ s->tlsext_channel_id_enabled = 1;
-+ if (EVP_PKEY_bits(parg) != 256)
-+ {
-+ SSLerr(SSL_F_SSL3_CTRL,SSL_R_CHANNEL_ID_NOT_P256);
-+ break;
-+ }
-+ if (s->tlsext_channel_id_private)
-+ EVP_PKEY_free(s->tlsext_channel_id_private);
-+ s->tlsext_channel_id_private = (EVP_PKEY*) parg;
-+ ret = 1;
-+ break;
-+
-+ case SSL_CTRL_GET_CHANNEL_ID:
-+ if (!s->server)
-+ break;
-+ if (!s->s3->tlsext_channel_id_valid)
-+ break;
-+ memcpy(parg, s->s3->tlsext_channel_id, larg < 64 ? larg : 64);
-+ return 64;
-
- #endif /* !OPENSSL_NO_TLSEXT */
- default:
-@@ -3569,6 +3607,12 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd
- }
- return 1;
- }
-+ case SSL_CTRL_CHANNEL_ID:
-+ /* must be called on a server */
-+ if (ctx->method->ssl_accept == ssl_undefined_function)
-+ return 0;
-+ ctx->tlsext_channel_id_enabled=1;
-+ return 1;
-
- #ifdef TLSEXT_TYPE_opaque_prf_input
- case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG:
-@@ -3637,6 +3681,18 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd
- }
- break;
-
-+ case SSL_CTRL_SET_CHANNEL_ID:
-+ ctx->tlsext_channel_id_enabled = 1;
-+ if (EVP_PKEY_bits(parg) != 256)
-+ {
-+ SSLerr(SSL_F_SSL3_CTX_CTRL,SSL_R_CHANNEL_ID_NOT_P256);
-+ break;
-+ }
-+ if (ctx->tlsext_channel_id_private)
-+ EVP_PKEY_free(ctx->tlsext_channel_id_private);
-+ ctx->tlsext_channel_id_private = (EVP_PKEY*) parg;
-+ break;
-+
- default:
- return(0);
- }
---- openssl-1.0.1e.orig/ssl/s3_srvr.c 2013-03-05 18:49:33.233297282 +0000
-+++ openssl-1.0.1e/ssl/s3_srvr.c 2013-03-05 18:49:33.413299231 +0000
-@@ -157,8 +157,11 @@
- #include <openssl/buffer.h>
- #include <openssl/rand.h>
- #include <openssl/objects.h>
-+#include <openssl/ec.h>
-+#include <openssl/ecdsa.h>
- #include <openssl/evp.h>
- #include <openssl/hmac.h>
-+#include <openssl/sha.h>
- #include <openssl/x509.h>
- #ifndef OPENSSL_NO_DH
- #include <openssl/dh.h>
-@@ -609,15 +612,8 @@ int ssl3_accept(SSL *s)
- * the client uses its key from the certificate
- * for key exchange.
- */
--#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
-- s->state=SSL3_ST_SR_FINISHED_A;
--#else
-- if (s->s3->next_proto_neg_seen)
-- s->state=SSL3_ST_SR_NEXT_PROTO_A;
-- else
-- s->state=SSL3_ST_SR_FINISHED_A;
--#endif
- s->init_num = 0;
-+ s->state=SSL3_ST_SR_POST_CLIENT_CERT;
- }
- else if (TLS1_get_version(s) >= TLS1_2_VERSION)
- {
-@@ -677,16 +673,28 @@ int ssl3_accept(SSL *s)
- ret=ssl3_get_cert_verify(s);
- if (ret <= 0) goto end;
-
--#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
-- s->state=SSL3_ST_SR_FINISHED_A;
--#else
-- if (s->s3->next_proto_neg_seen)
-+ s->state=SSL3_ST_SR_POST_CLIENT_CERT;
-+ s->init_num=0;
-+ break;
-+
-+ case SSL3_ST_SR_POST_CLIENT_CERT: {
-+ char next_proto_neg = 0;
-+ char channel_id = 0;
-+#if !defined(OPENSSL_NO_TLSEXT)
-+# if !defined(OPENSSL_NO_NEXTPROTONEG)
-+ next_proto_neg = s->s3->next_proto_neg_seen;
-+# endif
-+ channel_id = s->s3->tlsext_channel_id_valid;
-+#endif
-+
-+ if (next_proto_neg)
- s->state=SSL3_ST_SR_NEXT_PROTO_A;
-+ else if (channel_id)
-+ s->state=SSL3_ST_SR_CHANNEL_ID_A;
- else
- s->state=SSL3_ST_SR_FINISHED_A;
--#endif
-- s->init_num=0;
- break;
-+ }
-
- #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
- case SSL3_ST_SR_NEXT_PROTO_A:
-@@ -694,6 +702,19 @@ int ssl3_accept(SSL *s)
- ret=ssl3_get_next_proto(s);
- if (ret <= 0) goto end;
- s->init_num = 0;
-+ if (s->s3->tlsext_channel_id_valid)
-+ s->state=SSL3_ST_SR_CHANNEL_ID_A;
-+ else
-+ s->state=SSL3_ST_SR_FINISHED_A;
-+ break;
-+#endif
-+
-+#if !defined(OPENSSL_NO_TLSEXT)
-+ case SSL3_ST_SR_CHANNEL_ID_A:
-+ case SSL3_ST_SR_CHANNEL_ID_B:
-+ ret=ssl3_get_channel_id(s);
-+ if (ret <= 0) goto end;
-+ s->init_num = 0;
- s->state=SSL3_ST_SR_FINISHED_A;
- break;
- #endif
-@@ -765,16 +786,7 @@ int ssl3_accept(SSL *s)
- if (ret <= 0) goto end;
- s->state=SSL3_ST_SW_FLUSH;
- if (s->hit)
-- {
--#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
-- s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
--#else
-- if (s->s3->next_proto_neg_seen)
-- s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
-- else
-- s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
--#endif
-- }
-+ s->s3->tmp.next_state=SSL3_ST_SR_POST_CLIENT_CERT;
- else
- s->s3->tmp.next_state=SSL_ST_OK;
- s->init_num=0;
-@@ -3610,4 +3622,140 @@ int ssl3_get_next_proto(SSL *s)
- return 1;
- }
- # endif
-+
-+/* ssl3_get_channel_id reads and verifies a ClientID handshake message. */
-+int ssl3_get_channel_id(SSL *s)
-+ {
-+ int ret = -1, ok;
-+ long n;
-+ const unsigned char *p;
-+ unsigned short extension_type, extension_len;
-+ EC_GROUP* p256 = NULL;
-+ EC_KEY* key = NULL;
-+ EC_POINT* point = NULL;
-+ ECDSA_SIG sig;
-+ BIGNUM x, y;
-+
-+ if (s->state == SSL3_ST_SR_CHANNEL_ID_A && s->init_num == 0)
-+ {
-+ /* The first time that we're called we take the current
-+ * handshake hash and store it. */
-+ EVP_MD_CTX md_ctx;
-+ unsigned int len;
-+
-+ EVP_MD_CTX_init(&md_ctx);
-+ EVP_DigestInit_ex(&md_ctx, EVP_sha256(), NULL);
-+ if (!tls1_channel_id_hash(&md_ctx, s))
-+ return -1;
-+ len = sizeof(s->s3->tlsext_channel_id);
-+ EVP_DigestFinal(&md_ctx, s->s3->tlsext_channel_id, &len);
-+ EVP_MD_CTX_cleanup(&md_ctx);
-+ }
-+
-+ n = s->method->ssl_get_message(s,
-+ SSL3_ST_SR_CHANNEL_ID_A,
-+ SSL3_ST_SR_CHANNEL_ID_B,
-+ SSL3_MT_ENCRYPTED_EXTENSIONS,
-+ 2 + 2 + TLSEXT_CHANNEL_ID_SIZE,
-+ &ok);
-+
-+ if (!ok)
-+ return((int)n);
-+
-+ ssl3_finish_mac(s, (unsigned char*)s->init_buf->data, s->init_num + 4);
-+
-+ /* s->state doesn't reflect whether ChangeCipherSpec has been received
-+ * in this handshake, but s->s3->change_cipher_spec does (will be reset
-+ * by ssl3_get_finished). */
-+ if (!s->s3->change_cipher_spec)
-+ {
-+ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS);
-+ return -1;
-+ }
-+
-+ if (n != 2 + 2 + TLSEXT_CHANNEL_ID_SIZE)
-+ {
-+ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_INVALID_MESSAGE);
-+ return -1;
-+ }
-+
-+ p = (unsigned char *)s->init_msg;
-+
-+ /* The payload looks like:
-+ * uint16 extension_type
-+ * uint16 extension_len;
-+ * uint8 x[32];
-+ * uint8 y[32];
-+ * uint8 r[32];
-+ * uint8 s[32];
-+ */
-+ n2s(p, extension_type);
-+ n2s(p, extension_len);
-+
-+ if (extension_type != TLSEXT_TYPE_channel_id ||
-+ extension_len != TLSEXT_CHANNEL_ID_SIZE)
-+ {
-+ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_INVALID_MESSAGE);
-+ return -1;
-+ }
-+
-+ p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
-+ if (!p256)
-+ {
-+ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_NO_P256_SUPPORT);
-+ return -1;
-+ }
-+
-+ BN_init(&x);
-+ BN_init(&y);
-+ sig.r = BN_new();
-+ sig.s = BN_new();
-+
-+ if (BN_bin2bn(p + 0, 32, &x) == NULL ||
-+ BN_bin2bn(p + 32, 32, &y) == NULL ||
-+ BN_bin2bn(p + 64, 32, sig.r) == NULL ||
-+ BN_bin2bn(p + 96, 32, sig.s) == NULL)
-+ goto err;
-+
-+ point = EC_POINT_new(p256);
-+ if (!point ||
-+ !EC_POINT_set_affine_coordinates_GFp(p256, point, &x, &y, NULL))
-+ goto err;
-+
-+ key = EC_KEY_new();
-+ if (!key ||
-+ !EC_KEY_set_group(key, p256) ||
-+ !EC_KEY_set_public_key(key, point))
-+ goto err;
-+
-+ /* We stored the handshake hash in |tlsext_channel_id| the first time
-+ * that we were called. */
-+ switch (ECDSA_do_verify(s->s3->tlsext_channel_id, SHA256_DIGEST_LENGTH, &sig, key)) {
-+ case 1:
-+ break;
-+ case 0:
-+ SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_CHANNEL_ID_SIGNATURE_INVALID);
-+ s->s3->tlsext_channel_id_valid = 0;
-+ goto err;
-+ default:
-+ s->s3->tlsext_channel_id_valid = 0;
-+ goto err;
-+ }
-+
-+ memcpy(s->s3->tlsext_channel_id, p, 64);
-+ ret = 1;
-+
-+err:
-+ BN_free(&x);
-+ BN_free(&y);
-+ BN_free(sig.r);
-+ BN_free(sig.s);
-+ if (key)
-+ EC_KEY_free(key);
-+ if (point)
-+ EC_POINT_free(point);
-+ if (p256)
-+ EC_GROUP_free(p256);
-+ return ret;
-+ }
- #endif
---- openssl-1.0.1e.orig/ssl/ssl.h 2013-03-05 18:49:33.233297282 +0000
-+++ openssl-1.0.1e/ssl/ssl.h 2013-03-05 18:49:33.413299231 +0000
-@@ -981,6 +981,12 @@ struct ssl_ctx_st
- # endif
- /* SRTP profiles we are willing to do from RFC 5764 */
- STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
-+
-+ /* If true, a client will advertise the Channel ID extension and a
-+ * server will echo it. */
-+ char tlsext_channel_id_enabled;
-+ /* The client's Channel ID private key. */
-+ EVP_PKEY *tlsext_channel_id_private;
- #endif
- };
-
-@@ -1022,6 +1028,10 @@ LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(
- SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL)
- #define SSL_CTX_sess_cache_full(ctx) \
- SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL)
-+/* SSL_CTX_enable_tls_channel_id configures a TLS server to accept TLS client
-+ * IDs from clients. Returns 1 on success. */
-+#define SSL_CTX_enable_tls_channel_id(ctx) \
-+ SSL_CTX_ctrl(ctx,SSL_CTRL_CHANNEL_ID,0,NULL)
-
- void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess));
- int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, SSL_SESSION *sess);
-@@ -1348,6 +1358,13 @@ struct ssl_st
- */
- unsigned int tlsext_hb_pending; /* Indicates if a HeartbeatRequest is in flight */
- unsigned int tlsext_hb_seq; /* HeartbeatRequest sequence number */
-+
-+ /* Copied from the SSL_CTX. For a server, means that we'll accept
-+ * Channel IDs from clients. For a client, means that we'll advertise
-+ * support. */
-+ char tlsext_channel_id_enabled;
-+ /* The client's Channel ID private key. */
-+ EVP_PKEY *tlsext_channel_id_private;
- #else
- #define session_ctx ctx
- #endif /* OPENSSL_NO_TLSEXT */
-@@ -1605,6 +1622,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
- #define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING 86
- #define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87
- #endif
-+#define SSL_CTRL_CHANNEL_ID 88
-+#define SSL_CTRL_GET_CHANNEL_ID 89
-+#define SSL_CTRL_SET_CHANNEL_ID 90
- #endif
-
- #define DTLS_CTRL_GET_TIMEOUT 73
-@@ -1652,6 +1672,25 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
- #define SSL_set_tmp_ecdh(ssl,ecdh) \
- SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
-
-+/* SSL_enable_tls_channel_id configures a TLS server to accept TLS client
-+ * IDs from clients. Returns 1 on success. */
-+#define SSL_enable_tls_channel_id(ctx) \
-+ SSL_ctrl(ctx,SSL_CTRL_CHANNEL_ID,0,NULL)
-+/* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to
-+ * compatible servers. private_key must be a P-256 EVP_PKEY*. Returns 1 on
-+ * success. */
-+#define SSL_set1_tls_channel_id(s, private_key) \
-+ SSL_ctrl(s,SSL_CTRL_SET_CHANNEL_ID,0,(void*)private_key)
-+#define SSL_CTX_set1_tls_channel_id(ctx, private_key) \
-+ SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHANNEL_ID,0,(void*)private_key)
-+/* SSL_get_tls_channel_id gets the client's TLS Channel ID from a server SSL*
-+ * and copies up to the first |channel_id_len| bytes into |channel_id|. The
-+ * Channel ID consists of the client's P-256 public key as an (x,y) pair where
-+ * each is a 32-byte, big-endian field element. Returns 0 if the client didn't
-+ * offer a Channel ID and the length of the complete Channel ID otherwise. */
-+#define SSL_get_tls_channel_id(ctx, channel_id, channel_id_len) \
-+ SSL_ctrl(ctx,SSL_CTRL_GET_CHANNEL_ID,channel_id_len,(void*)channel_id)
-+
- #define SSL_CTX_add_extra_chain_cert(ctx,x509) \
- SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
- #define SSL_CTX_get_extra_chain_certs(ctx,px509) \
-@@ -1686,6 +1725,7 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER
- char * SSL_CIPHER_get_version(const SSL_CIPHER *c);
- const char * SSL_CIPHER_get_name(const SSL_CIPHER *c);
- unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c);
-+const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher);
-
- int SSL_get_fd(const SSL *s);
- int SSL_get_rfd(const SSL *s);
-@@ -2149,6 +2189,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135
- #define SSL_F_SSL3_GET_CERT_STATUS 289
- #define SSL_F_SSL3_GET_CERT_VERIFY 136
-+#define SSL_F_SSL3_GET_CHANNEL_ID 317
- #define SSL_F_SSL3_GET_CLIENT_CERTIFICATE 137
- #define SSL_F_SSL3_GET_CLIENT_HELLO 138
- #define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE 139
-@@ -2168,6 +2209,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_F_SSL3_READ_BYTES 148
- #define SSL_F_SSL3_READ_N 149
- #define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST 150
-+#define SSL_F_SSL3_SEND_CHANNEL_ID 318
- #define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE 151
- #define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE 152
- #define SSL_F_SSL3_SEND_CLIENT_VERIFY 153
-@@ -2335,12 +2377,15 @@ void ERR_load_SSL_strings(void);
- #define SSL_R_BIO_NOT_SET 128
- #define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129
- #define SSL_R_BN_LIB 130
-+#define SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY 376
- #define SSL_R_CA_DN_LENGTH_MISMATCH 131
- #define SSL_R_CA_DN_TOO_LONG 132
- #define SSL_R_CCS_RECEIVED_EARLY 133
- #define SSL_R_CERTIFICATE_VERIFY_FAILED 134
- #define SSL_R_CERT_LENGTH_MISMATCH 135
- #define SSL_R_CHALLENGE_IS_DIFFERENT 136
-+#define SSL_R_CHANNEL_ID_NOT_P256 375
-+#define SSL_R_CHANNEL_ID_SIGNATURE_INVALID 371
- #define SSL_R_CIPHER_CODE_WRONG_LENGTH 137
- #define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138
- #define SSL_R_CIPHER_TABLE_SRC_ERROR 139
-@@ -2353,6 +2398,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_R_CONNECTION_ID_IS_DIFFERENT 143
- #define SSL_R_CONNECTION_TYPE_NOT_SET 144
- #define SSL_R_COOKIE_MISMATCH 308
-+#define SSL_R_D2I_ECDSA_SIG 379
- #define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145
- #define SSL_R_DATA_LENGTH_TOO_LONG 146
- #define SSL_R_DECRYPTION_FAILED 147
-@@ -2370,9 +2416,12 @@ void ERR_load_SSL_strings(void);
- #define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150
- #define SSL_R_ERROR_GENERATING_TMP_RSA_KEY 282
- #define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151
-+#define SSL_R_EVP_DIGESTSIGNFINAL_FAILED 377
-+#define SSL_R_EVP_DIGESTSIGNINIT_FAILED 378
- #define SSL_R_EXCESSIVE_MESSAGE_SIZE 152
- #define SSL_R_EXTRA_DATA_IN_MESSAGE 153
- #define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154
-+#define SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS 372
- #define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 355
- #define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 356
- #define SSL_R_HTTPS_PROXY_REQUEST 155
-@@ -2382,6 +2431,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_R_INVALID_CHALLENGE_LENGTH 158
- #define SSL_R_INVALID_COMMAND 280
- #define SSL_R_INVALID_COMPRESSION_ALGORITHM 341
-+#define SSL_R_INVALID_MESSAGE 374
- #define SSL_R_INVALID_PURPOSE 278
- #define SSL_R_INVALID_SRP_USERNAME 357
- #define SSL_R_INVALID_STATUS_RESPONSE 328
-@@ -2436,6 +2486,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_R_NO_COMPRESSION_SPECIFIED 187
- #define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330
- #define SSL_R_NO_METHOD_SPECIFIED 188
-+#define SSL_R_NO_P256_SUPPORT 373
- #define SSL_R_NO_PRIVATEKEY 189
- #define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190
- #define SSL_R_NO_PROTOCOLS_AVAILABLE 191
---- openssl-1.0.1e.orig/ssl/ssl3.h 2013-03-05 18:49:33.223297173 +0000
-+++ openssl-1.0.1e/ssl/ssl3.h 2013-03-05 18:49:33.413299231 +0000
-@@ -539,6 +539,17 @@ typedef struct ssl3_state_st
- char is_probably_safari;
- #endif /* !OPENSSL_NO_EC */
- #endif /* !OPENSSL_NO_TLSEXT */
-+
-+ /* In a client, this means that the server supported Channel ID and that
-+ * a Channel ID was sent. In a server it means that we echoed support
-+ * for Channel IDs and that tlsext_channel_id will be valid after the
-+ * handshake. */
-+ char tlsext_channel_id_valid;
-+ /* For a server:
-+ * If |tlsext_channel_id_valid| is true, then this contains the
-+ * verified Channel ID from the client: a P256 point, (x,y), where
-+ * each are big-endian values. */
-+ unsigned char tlsext_channel_id[64];
- } SSL3_STATE;
-
- #endif
-@@ -583,6 +594,8 @@ typedef struct ssl3_state_st
- #define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT)
- #define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT)
- #endif
-+#define SSL3_ST_CW_CHANNEL_ID_A (0x210|SSL_ST_CONNECT)
-+#define SSL3_ST_CW_CHANNEL_ID_B (0x211|SSL_ST_CONNECT)
- #define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT)
- #define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT)
- /* read from server */
-@@ -632,10 +645,13 @@ typedef struct ssl3_state_st
- #define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT)
- #define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT)
- #define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT)
-+#define SSL3_ST_SR_POST_CLIENT_CERT (0x1BF|SSL_ST_ACCEPT)
- #ifndef OPENSSL_NO_NEXTPROTONEG
- #define SSL3_ST_SR_NEXT_PROTO_A (0x210|SSL_ST_ACCEPT)
- #define SSL3_ST_SR_NEXT_PROTO_B (0x211|SSL_ST_ACCEPT)
- #endif
-+#define SSL3_ST_SR_CHANNEL_ID_A (0x220|SSL_ST_ACCEPT)
-+#define SSL3_ST_SR_CHANNEL_ID_B (0x221|SSL_ST_ACCEPT)
- #define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT)
- #define SSL3_ST_SR_FINISHED_B (0x1C1|SSL_ST_ACCEPT)
- /* write to client */
-@@ -663,6 +679,7 @@ typedef struct ssl3_state_st
- #ifndef OPENSSL_NO_NEXTPROTONEG
- #define SSL3_MT_NEXT_PROTO 67
- #endif
-+#define SSL3_MT_ENCRYPTED_EXTENSIONS 203
- #define DTLS1_MT_HELLO_VERIFY_REQUEST 3
-
-
---- openssl-1.0.1e.orig/ssl/ssl_err.c 2013-03-05 18:49:33.243297392 +0000
-+++ openssl-1.0.1e/ssl/ssl_err.c 2013-03-05 18:49:33.413299231 +0000
-@@ -151,6 +151,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
- {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST), "SSL3_GET_CERTIFICATE_REQUEST"},
- {ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS), "SSL3_GET_CERT_STATUS"},
- {ERR_FUNC(SSL_F_SSL3_GET_CERT_VERIFY), "SSL3_GET_CERT_VERIFY"},
-+{ERR_FUNC(SSL_F_SSL3_GET_CHANNEL_ID), "SSL3_GET_CHANNEL_ID"},
- {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_CERTIFICATE), "SSL3_GET_CLIENT_CERTIFICATE"},
- {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_HELLO), "SSL3_GET_CLIENT_HELLO"},
- {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE), "SSL3_GET_CLIENT_KEY_EXCHANGE"},
-@@ -170,6 +171,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
- {ERR_FUNC(SSL_F_SSL3_READ_BYTES), "SSL3_READ_BYTES"},
- {ERR_FUNC(SSL_F_SSL3_READ_N), "SSL3_READ_N"},
- {ERR_FUNC(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST), "SSL3_SEND_CERTIFICATE_REQUEST"},
-+{ERR_FUNC(SSL_F_SSL3_SEND_CHANNEL_ID), "SSL3_SEND_CHANNEL_ID"},
- {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE), "SSL3_SEND_CLIENT_CERTIFICATE"},
- {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE), "SSL3_SEND_CLIENT_KEY_EXCHANGE"},
- {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_VERIFY), "SSL3_SEND_CLIENT_VERIFY"},
-@@ -339,12 +341,15 @@ static ERR_STRING_DATA SSL_str_reasons[]
- {ERR_REASON(SSL_R_BIO_NOT_SET) ,"bio not set"},
- {ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG),"block cipher pad is wrong"},
- {ERR_REASON(SSL_R_BN_LIB) ,"bn lib"},
-+{ERR_REASON(SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY),"cannot serialize public key"},
- {ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH) ,"ca dn length mismatch"},
- {ERR_REASON(SSL_R_CA_DN_TOO_LONG) ,"ca dn too long"},
- {ERR_REASON(SSL_R_CCS_RECEIVED_EARLY) ,"ccs received early"},
- {ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED),"certificate verify failed"},
- {ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH) ,"cert length mismatch"},
- {ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT),"challenge is different"},
-+{ERR_REASON(SSL_R_CHANNEL_ID_NOT_P256) ,"channel id not p256"},
-+{ERR_REASON(SSL_R_CHANNEL_ID_SIGNATURE_INVALID),"Channel ID signature invalid"},
- {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher code wrong length"},
- {ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),"cipher or hash unavailable"},
- {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher table src error"},
-@@ -357,6 +362,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
- {ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT),"connection id is different"},
- {ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET),"connection type not set"},
- {ERR_REASON(SSL_R_COOKIE_MISMATCH) ,"cookie mismatch"},
-+{ERR_REASON(SSL_R_D2I_ECDSA_SIG) ,"d2i ecdsa sig"},
- {ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED),"data between ccs and finished"},
- {ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG) ,"data length too long"},
- {ERR_REASON(SSL_R_DECRYPTION_FAILED) ,"decryption failed"},
-@@ -374,9 +380,12 @@ static ERR_STRING_DATA SSL_str_reasons[]
- {ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG),"encrypted length too long"},
- {ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY),"error generating tmp rsa key"},
- {ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST),"error in received cipher list"},
-+{ERR_REASON(SSL_R_EVP_DIGESTSIGNFINAL_FAILED),"evp digestsignfinal failed"},
-+{ERR_REASON(SSL_R_EVP_DIGESTSIGNINIT_FAILED),"evp digestsigninit failed"},
- {ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE),"excessive message size"},
- {ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE) ,"extra data in message"},
- {ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS),"got a fin before a ccs"},
-+{ERR_REASON(SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS),"got Channel ID before a ccs"},
- {ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS),"got next proto before a ccs"},
- {ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION),"got next proto without seeing extension"},
- {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST) ,"https proxy request"},
-@@ -386,6 +395,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
- {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
- {ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"},
- {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"},
-+{ERR_REASON(SSL_R_INVALID_MESSAGE) ,"invalid message"},
- {ERR_REASON(SSL_R_INVALID_PURPOSE) ,"invalid purpose"},
- {ERR_REASON(SSL_R_INVALID_SRP_USERNAME) ,"invalid srp username"},
- {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE),"invalid status response"},
-@@ -440,6 +450,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
- {ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED),"no compression specified"},
- {ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER),"Peer haven't sent GOST certificate, required for selected ciphersuite"},
- {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED) ,"no method specified"},
-+{ERR_REASON(SSL_R_NO_P256_SUPPORT) ,"no p256 support"},
- {ERR_REASON(SSL_R_NO_PRIVATEKEY) ,"no privatekey"},
- {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED),"no private key assigned"},
- {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE),"no protocols available"},
---- openssl-1.0.1e.orig/ssl/ssl_lib.c 2013-03-05 18:49:33.243297392 +0000
-+++ openssl-1.0.1e/ssl/ssl_lib.c 2013-03-05 18:49:33.413299231 +0000
-@@ -579,6 +579,8 @@ void SSL_free(SSL *s)
- sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
- if (s->tlsext_ocsp_resp)
- OPENSSL_free(s->tlsext_ocsp_resp);
-+ if (s->tlsext_channel_id_private)
-+ EVP_PKEY_free(s->tlsext_channel_id_private);
- #endif
-
- if (s->client_CA != NULL)
-@@ -2005,6 +2007,11 @@ void SSL_CTX_free(SSL_CTX *a)
- ssl_buf_freelist_free(a->rbuf_freelist);
- #endif
-
-+#ifndef OPENSSL_NO_TLSEXT
-+ if (a->tlsext_channel_id_private)
-+ EVP_PKEY_free(a->tlsext_channel_id_private);
-+#endif
-+
- OPENSSL_free(a);
- }
-
---- openssl-1.0.1e.orig/ssl/ssl_locl.h 2013-03-05 18:49:33.243297392 +0000
-+++ openssl-1.0.1e/ssl/ssl_locl.h 2013-03-05 18:49:33.413299231 +0000
-@@ -378,6 +378,7 @@
- * (currently this also goes into algorithm2) */
- #define TLS1_STREAM_MAC 0x04
-
-+#define TLSEXT_CHANNEL_ID_SIZE 128
-
-
- /*
-@@ -1004,6 +1005,7 @@ int ssl3_check_cert_and_algorithm(SSL *s
- int ssl3_check_finished(SSL *s);
- # ifndef OPENSSL_NO_NEXTPROTONEG
- int ssl3_send_next_proto(SSL *s);
-+int ssl3_send_channel_id(SSL *s);
- # endif
- #endif
-
-@@ -1026,6 +1028,7 @@ int ssl3_get_cert_verify(SSL *s);
- #ifndef OPENSSL_NO_NEXTPROTONEG
- int ssl3_get_next_proto(SSL *s);
- #endif
-+int ssl3_get_channel_id(SSL *s);
-
- int dtls1_send_hello_request(SSL *s);
- int dtls1_send_server_hello(SSL *s);
-@@ -1123,7 +1126,9 @@ int tls12_get_sigandhash(unsigned char *
- 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);
- #endif
-+
- EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ;
- void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
- int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
---- openssl-1.0.1e.orig/ssl/t1_lib.c 2013-03-05 18:49:33.173296633 +0000
-+++ openssl-1.0.1e/ssl/t1_lib.c 2013-03-05 18:49:33.413299231 +0000
-@@ -649,6 +649,16 @@ unsigned char *ssl_add_clienthello_tlsex
- }
- #endif
-
-+ if (s->tlsext_channel_id_enabled)
-+ {
-+ /* The client advertises an emtpy extension to indicate its
-+ * support for Channel ID. */
-+ if (limit - ret - 4 < 0)
-+ return NULL;
-+ s2n(TLSEXT_TYPE_channel_id,ret);
-+ s2n(0,ret);
-+ }
-+
- #ifndef OPENSSL_NO_SRTP
- if(SSL_get_srtp_profiles(s))
- {
-@@ -859,6 +869,16 @@ unsigned char *ssl_add_serverhello_tlsex
- }
- #endif
-
-+ /* If the client advertised support for Channel ID, and we have it
-+ * enabled, then we want to echo it back. */
-+ if (s->s3->tlsext_channel_id_valid)
-+ {
-+ if (limit - ret - 4 < 0)
-+ return NULL;
-+ s2n(TLSEXT_TYPE_channel_id,ret);
-+ s2n(0,ret);
-+ }
-+
- if ((extdatalen = ret-p-2)== 0)
- return p;
-
-@@ -1332,6 +1352,9 @@ int ssl_parse_clienthello_tlsext(SSL *s,
- }
- #endif
-
-+ else if (type == TLSEXT_TYPE_channel_id && s->tlsext_channel_id_enabled)
-+ s->s3->tlsext_channel_id_valid = 1;
-+
- /* session ticket processed earlier */
- #ifndef OPENSSL_NO_SRTP
- else if (type == TLSEXT_TYPE_use_srtp)
-@@ -1562,6 +1585,9 @@ int ssl_parse_serverhello_tlsext(SSL *s,
- s->s3->next_proto_neg_seen = 1;
- }
- #endif
-+ else if (type == TLSEXT_TYPE_channel_id)
-+ s->s3->tlsext_channel_id_valid = 1;
-+
- else if (type == TLSEXT_TYPE_renegotiate)
- {
- if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
-@@ -2621,3 +2647,37 @@ tls1_heartbeat(SSL *s)
- return ret;
- }
- #endif
-+
-+#if !defined(OPENSSL_NO_TLSEXT)
-+/* tls1_channel_id_hash calculates the signed data for a Channel ID on the given
-+ * SSL connection and writes it to |md|.
-+ */
-+int
-+tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s)
-+ {
-+ EVP_MD_CTX ctx;
-+ unsigned char temp_digest[EVP_MAX_MD_SIZE];
-+ unsigned temp_digest_len;
-+ int i;
-+ static const char kClientIDMagic[] = "TLS Channel ID signature";
-+
-+ if (s->s3->handshake_buffer)
-+ if (!ssl3_digest_cached_records(s))
-+ return 0;
-+
-+ EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
-+
-+ EVP_MD_CTX_init(&ctx);
-+ for (i = 0; i < SSL_MAX_DIGEST; i++)
-+ {
-+ if (s->s3->handshake_dgst[i] == NULL)
-+ continue;
-+ EVP_MD_CTX_copy_ex(&ctx, s->s3->handshake_dgst[i]);
-+ EVP_DigestFinal_ex(&ctx, temp_digest, &temp_digest_len);
-+ EVP_DigestUpdate(md, temp_digest, temp_digest_len);
-+ }
-+ EVP_MD_CTX_cleanup(&ctx);
-+
-+ return 1;
-+ }
-+#endif
---- openssl-1.0.1e.orig/ssl/tls1.h 2013-03-05 18:49:33.173296633 +0000
-+++ openssl-1.0.1e/ssl/tls1.h 2013-03-05 18:49:33.413299231 +0000
-@@ -248,6 +248,9 @@ extern "C" {
- #define TLSEXT_TYPE_next_proto_neg 13172
- #endif
-
-+/* This is not an IANA defined extension number */
-+#define TLSEXT_TYPE_channel_id 30031
-+
- /* NameType value from RFC 3546 */
- #define TLSEXT_NAMETYPE_host_name 0
- /* status request value from RFC 3546 */
diff --git a/patches/early_ccs.patch b/patches/early_ccs.patch
deleted file mode 100644
index d4c31e6..0000000
--- a/patches/early_ccs.patch
+++ /dev/null
@@ -1,100 +0,0 @@
---- openssl-1.0.1e.orig/ssl/s3_clnt.c
-+++ openssl-1.0.1e/ssl/s3_clnt.c
-@@ -606,7 +606,7 @@ int ssl3_connect(SSL *s)
-
- case SSL3_ST_CR_FINISHED_A:
- case SSL3_ST_CR_FINISHED_B:
--
-+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
- ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
- SSL3_ST_CR_FINISHED_B);
- if (ret <= 0) goto end;
-@@ -915,6 +916,7 @@
- SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
- goto f_err;
- }
-+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
- s->hit=1;
- }
- else /* a miss or crap from the other end */
---- openssl-1.0.1e.orig/ssl/s3_pkt.c
-+++ openssl-1.0.1e/ssl/s3_pkt.c
-@@ -1297,6 +1297,13 @@ start:
- goto f_err;
- }
-
-+ if (!(s->s3->flags & SSL3_FLAGS_CCS_OK))
-+ {
-+ al=SSL_AD_UNEXPECTED_MESSAGE;
-+ SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_CCS);
-+ goto f_err;
-+ }
-+
- rr->length=0;
-
- if (s->msg_callback)
-@@ -1431,7 +1438,12 @@ int ssl3_do_change_cipher_spec(SSL *s)
-
- if (s->s3->tmp.key_block == NULL)
- {
-- if (s->session == NULL)
-+ if (s->session->master_key_length == 0)
-+ {
-+ SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_UNEXPECTED_CCS);
-+ return (0);
-+ }
-+ if (s->session == NULL)
- {
- /* might happen if dtls1_read_bytes() calls this */
- SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);
---- openssl-1.0.1e.orig/ssl/s3_srvr.c
-+++ openssl-1.0.1e/ssl/s3_srvr.c
-@@ -670,6 +670,7 @@ int ssl3_accept(SSL *s)
- case SSL3_ST_SR_CERT_VRFY_B:
-
- /* we should decide if we expected this one */
-+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
- ret=ssl3_get_cert_verify(s);
- if (ret <= 0) goto end;
-
-@@ -687,6 +688,7 @@ int ssl3_accept(SSL *s)
- channel_id = s->s3->tlsext_channel_id_valid;
- #endif
-
-+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
- if (next_proto_neg)
- s->state=SSL3_ST_SR_NEXT_PROTO_A;
- else if (channel_id)
---- openssl-1.0.1e.orig/ssl/ssl.h
-+++ openssl-1.0.1e/ssl/ssl.h
-@@ -2640,6 +2640,7 @@ void ERR_load_SSL_strings(void);
- #define SSL_R_WRONG_VERSION_NUMBER 267
- #define SSL_R_X509_LIB 268
- #define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269
-+#define SSL_R_UNEXPECTED_CCS 388
-
- #ifdef __cplusplus
- }
---- openssl-1.0.1e.orig/ssl/ssl3.h
-+++ openssl-1.0.1e/ssl/ssl3.h
-@@ -388,6 +388,10 @@ typedef struct ssl3_buffer_st
- #define TLS1_FLAGS_TLS_PADDING_BUG 0x0008
- #define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010
- #define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020
-+/* SSL3_FLAGS_CCS_OK indicates that a ChangeCipherSpec record is acceptable at
-+ * this point in the handshake. If this flag is not set then received CCS
-+ * records will cause a fatal error for the connection. */
-+#define SSL3_FLAGS_CCS_OK 0x0080
-
- /* SSL3_FLAGS_SGC_RESTART_DONE is set when we
- * restart a handshake because of MS SGC and so prevents us
---- openssl-1.0.1e.orig/ssl/ssl_err.c
-+++ openssl-1.0.1e/ssl/ssl_err.c
-@@ -604,6 +604,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
- {ERR_REASON(SSL_R_WRONG_VERSION_NUMBER) ,"wrong version number"},
- {ERR_REASON(SSL_R_X509_LIB) ,"x509 lib"},
- {ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS),"x509 verification setup problems"},
-+{ERR_REASON(SSL_R_UNEXPECTED_CCS),"unexpected CCS"},
- {0,NULL}
- };
-
diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c
index e9552ca..06a13de 100644
--- a/ssl/bio_ssl.c
+++ b/ssl/bio_ssl.c
@@ -206,6 +206,10 @@
BIO_set_retry_special(b);
retry_reason=BIO_RR_SSL_X509_LOOKUP;
break;
+ case SSL_ERROR_WANT_CHANNEL_ID_LOOKUP:
+ BIO_set_retry_special(b);
+ retry_reason=BIO_RR_SSL_CHANNEL_ID_LOOKUP;
+ break;
case SSL_ERROR_WANT_ACCEPT:
BIO_set_retry_special(b);
retry_reason=BIO_RR_ACCEPT;
@@ -280,6 +284,10 @@
BIO_set_retry_special(b);
retry_reason=BIO_RR_SSL_X509_LOOKUP;
break;
+ case SSL_ERROR_WANT_CHANNEL_ID_LOOKUP:
+ BIO_set_retry_special(b);
+ retry_reason=BIO_RR_SSL_CHANNEL_ID_LOOKUP;
+ break;
case SSL_ERROR_WANT_CONNECT:
BIO_set_retry_special(b);
retry_reason=BIO_RR_CONNECT;
diff --git a/ssl/d1_both.c b/ssl/d1_both.c
index 2e8cf68..04aa231 100644
--- a/ssl/d1_both.c
+++ b/ssl/d1_both.c
@@ -627,7 +627,16 @@
frag->msg_header.frag_off = 0;
}
else
+ {
frag = (hm_fragment*) item->data;
+ if (frag->msg_header.msg_len != msg_hdr->msg_len)
+ {
+ item = NULL;
+ frag = NULL;
+ goto err;
+ }
+ }
+
/* If message is already reassembled, this must be a
* retransmit and can be dropped.
@@ -674,8 +683,8 @@
item = pitem_new(seq64be, frag);
if (item == NULL)
{
- goto err;
i = -1;
+ goto err;
}
pqueue_insert(s->d1->buffered_messages, item);
@@ -784,6 +793,7 @@
int i,al;
struct hm_header_st msg_hdr;
+ redo:
/* see if we have the required fragment already */
if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok)
{
@@ -842,8 +852,7 @@
s->msg_callback_arg);
s->init_num = 0;
- return dtls1_get_message_fragment(s, st1, stn,
- max, ok);
+ goto redo;
}
else /* Incorrectly formated Hello request */
{
diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c
index 106939f..6bde16f 100644
--- a/ssl/d1_lib.c
+++ b/ssl/d1_lib.c
@@ -176,9 +176,12 @@
while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
{
- frag = (hm_fragment *)item->data;
- OPENSSL_free(frag->fragment);
- OPENSSL_free(frag);
+ rdata = (DTLS1_RECORD_DATA *) item->data;
+ if (rdata->rbuf.buf)
+ {
+ OPENSSL_free(rdata->rbuf.buf);
+ }
+ OPENSSL_free(item->data);
pitem_free(item);
}
}
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index 5b84e97..363fc8c 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -241,14 +241,6 @@
}
#endif
- /* insert should not fail, since duplicates are dropped */
- if (pqueue_insert(queue->q, item) == NULL)
- {
- OPENSSL_free(rdata);
- pitem_free(item);
- return(0);
- }
-
s->packet = NULL;
s->packet_length = 0;
memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER));
@@ -261,7 +253,16 @@
pitem_free(item);
return(0);
}
-
+
+ /* insert should not fail, since duplicates are dropped */
+ if (pqueue_insert(queue->q, item) == NULL)
+ {
+ SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+ OPENSSL_free(rdata);
+ pitem_free(item);
+ return(0);
+ }
+
return(1);
}
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 09f4762..c181db6 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -1356,6 +1356,7 @@
(unsigned char *)encodedPoint,
encodedlen);
OPENSSL_free(encodedPoint);
+ encodedPoint = NULL;
p += encodedlen;
}
#endif
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
index d9e18a3..607990d 100644
--- a/ssl/s3_both.c
+++ b/ssl/s3_both.c
@@ -561,7 +561,7 @@
#endif
/* Feed this message into MAC computation. */
- if (*(unsigned char*)s->init_buf->data != SSL3_MT_ENCRYPTED_EXTENSIONS)
+ if (*((unsigned char*) s->init_buf->data) != SSL3_MT_ENCRYPTED_EXTENSIONS)
ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
if (s->msg_callback)
s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg);
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 5e15b75..486f538 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -215,24 +215,12 @@
}
#endif
-// BEGIN android-added
-#if 0
-/* Send app data in separate packet, otherwise, some particular site
- * (only one site so far) closes the socket. http://b/2511073
- * Note: there is a very small chance that two TCP packets
- * could be arriving at server combined into a single TCP packet,
- * then trigger that site to break. We haven't encounter that though.
- */
-// END android-added
if (SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
{
/* Send app data along with CCS/Finished */
s->s3->flags |= SSL3_FLAGS_DELAY_CLIENT_FINISHED;
}
-// BEGIN android-added
-#endif
-// END android-added
for (;;)
{
state=s->state;
@@ -558,7 +546,20 @@
}
else
{
- if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) && SSL_get_cipher_bits(s, NULL) >= 128
+ /* 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. */
+ if (s->s3->tlsext_channel_id_new)
+ {
+ ret = tls1_record_handshake_hashes_for_channel_id(s);
+ if (ret <= 0)
+ goto end;
+ }
+ if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
+ && ssl3_can_cutthrough(s)
&& s->s3->previous_server_finished_len == 0 /* no cutthrough on renegotiation (would complicate the state machine) */
)
{
@@ -607,6 +608,7 @@
case SSL3_ST_CR_FINISHED_A:
case SSL3_ST_CR_FINISHED_B:
+
s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
SSL3_ST_CR_FINISHED_B);
@@ -2302,7 +2304,7 @@
int ssl3_send_client_key_exchange(SSL *s)
{
unsigned char *p,*d;
- int n;
+ int n = 0;
unsigned long alg_k;
unsigned long alg_a;
#ifndef OPENSSL_NO_RSA
@@ -2688,6 +2690,13 @@
unsigned int i;
#endif
+ if (s->session->sess_cert == NULL)
+ {
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
+ goto err;
+ }
+
/* Did we send out the client's
* ECDH share for use in premaster
* computation as part of client certificate?
@@ -3027,7 +3036,7 @@
}
}
#endif
- else if (!(alg_k & SSL_kPSK))
+ else if (!(alg_k & SSL_kPSK) || ((alg_k & SSL_kPSK) && !(alg_a & SSL_aPSK)))
{
ssl3_send_alert(s, SSL3_AL_FATAL,
SSL_AD_HANDSHAKE_FAILURE);
@@ -3491,10 +3500,29 @@
if (s->state != SSL3_ST_CW_CHANNEL_ID_A)
return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+ if (!s->tlsext_channel_id_private && s->ctx->channel_id_cb)
+ {
+ EVP_PKEY *key = NULL;
+ s->ctx->channel_id_cb(s, &key);
+ if (key != NULL)
+ {
+ s->tlsext_channel_id_private = key;
+ }
+ }
+ if (!s->tlsext_channel_id_private)
+ {
+ s->rwstate=SSL_CHANNEL_ID_LOOKUP;
+ return (-1);
+ }
+ s->rwstate=SSL_NOTHING;
+
d = (unsigned char *)s->init_buf->data;
*(d++)=SSL3_MT_ENCRYPTED_EXTENSIONS;
l2n3(2 + 2 + TLSEXT_CHANNEL_ID_SIZE, d);
- s2n(TLSEXT_TYPE_channel_id, d);
+ if (s->s3->tlsext_channel_id_new)
+ s2n(TLSEXT_TYPE_channel_id_new, d);
+ else
+ s2n(TLSEXT_TYPE_channel_id, d);
s2n(TLSEXT_CHANNEL_ID_SIZE, d);
EVP_MD_CTX_init(&md_ctx);
@@ -3505,9 +3533,9 @@
SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY);
goto err;
}
- // i2d_PublicKey will produce an ANSI X9.62 public key which, for a
- // P-256 key, is 0x04 (meaning uncompressed) followed by the x and y
- // field elements as 32-byte, big-endian numbers.
+ /* i2d_PublicKey will produce an ANSI X9.62 public key which, for a
+ * P-256 key, is 0x04 (meaning uncompressed) followed by the x and y
+ * field elements as 32-byte, big-endian numbers. */
if (public_key_len != 65)
{
SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_CHANNEL_ID_NOT_P256);
@@ -3553,14 +3581,14 @@
}
derp = der_sig;
- sig = d2i_ECDSA_SIG(NULL, (const unsigned char**)&derp, sig_len);
+ sig = d2i_ECDSA_SIG(NULL, (const unsigned char**) &derp, sig_len);
if (sig == NULL)
{
SSLerr(SSL_F_SSL3_SEND_CHANNEL_ID,SSL_R_D2I_ECDSA_SIG);
goto err;
}
- // The first byte of public_key will be 0x4, denoting an uncompressed key.
+ /* The first byte of public_key will be 0x4, denoting an uncompressed key. */
memcpy(d, public_key + 1, 64);
d += 64;
memset(d, 0, 2 * 32);
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 90fbb18..53b94b7 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -728,7 +728,7 @@
}
t=EVP_MD_CTX_size(hash);
- if (t < 0)
+ if (t < 0 || t > 20)
return -1;
md_size=t;
npad=(48/md_size)*md_size;
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index f84da7f..4eb5428 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3412,8 +3412,6 @@
break;
#endif
case SSL_CTRL_CHANNEL_ID:
- if (!s->server)
- break;
s->tlsext_channel_id_enabled = 1;
ret = 1;
break;
@@ -3429,7 +3427,7 @@
}
if (s->tlsext_channel_id_private)
EVP_PKEY_free(s->tlsext_channel_id_private);
- s->tlsext_channel_id_private = (EVP_PKEY*) parg;
+ s->tlsext_channel_id_private = EVP_PKEY_dup((EVP_PKEY*) parg);
ret = 1;
break;
@@ -3744,7 +3742,7 @@
}
if (ctx->tlsext_channel_id_private)
EVP_PKEY_free(ctx->tlsext_channel_id_private);
- ctx->tlsext_channel_id_private = (EVP_PKEY*) parg;
+ ctx->tlsext_channel_id_private = EVP_PKEY_dup((EVP_PKEY*) parg);
break;
default:
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 75997ac..60c4f1a 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -110,6 +110,7 @@
*/
#include <stdio.h>
+#include <limits.h>
#include <errno.h>
#define USE_SOCKETS
#include "ssl_locl.h"
@@ -580,10 +581,11 @@
int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
{
const unsigned char *buf=buf_;
- unsigned int tot,n,nw;
- int i;
+ unsigned int n,nw;
+ int i,tot;
s->rwstate=SSL_NOTHING;
+ OPENSSL_assert(s->s3->wnum <= INT_MAX);
tot=s->s3->wnum;
s->s3->wnum=0;
@@ -598,6 +600,22 @@
}
}
+ /* ensure that if we end up with a smaller value of data to write
+ * out than the the original len from a write which didn't complete
+ * for non-blocking I/O and also somehow ended up avoiding
+ * the check for this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as
+ * it must never be possible to end up with (len-tot) as a large
+ * number that will then promptly send beyond the end of the users
+ * buffer ... so we trap and report the error in a way the user
+ * will notice
+ */
+ if (len < tot)
+ {
+ SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_BAD_LENGTH);
+ return(-1);
+ }
+
+
n=(len-tot);
for (;;)
{
@@ -668,9 +686,6 @@
SSL3_BUFFER *wb=&(s->s3->wbuf);
SSL_SESSION *sess;
- if (wb->buf == NULL)
- if (!ssl3_setup_write_buffer(s))
- return -1;
/* first check if there is a SSL3_BUFFER still being written
* out. This will happen with non blocking IO */
@@ -686,6 +701,10 @@
/* if it went, fall through and send more stuff */
}
+ if (wb->buf == NULL)
+ if (!ssl3_setup_write_buffer(s))
+ return -1;
+
if (len == 0)
return 0;
@@ -1067,7 +1086,7 @@
{
s->rstate=SSL_ST_READ_HEADER;
rr->off=0;
- if (s->mode & SSL_MODE_RELEASE_BUFFERS)
+ if (s->mode & SSL_MODE_RELEASE_BUFFERS && s->s3->rbuf.left == 0)
ssl3_release_read_buffer(s);
}
}
@@ -1312,10 +1331,12 @@
if (!(s->s3->flags & SSL3_FLAGS_CCS_OK))
{
al=SSL_AD_UNEXPECTED_MESSAGE;
- SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_UNEXPECTED_CCS);
+ SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_CCS_RECEIVED_EARLY);
goto f_err;
}
+ s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
+
rr->length=0;
if (s->msg_callback)
@@ -1450,12 +1471,7 @@
if (s->s3->tmp.key_block == NULL)
{
- if (s->session->master_key_length == 0)
- {
- SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_UNEXPECTED_CCS);
- return (0);
- }
- if (s->session == NULL)
+ if (s->session == NULL || s->session->master_key_length == 0)
{
/* might happen if dtls1_read_bytes() calls this */
SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 1976efa..f83c936 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -675,8 +675,8 @@
case SSL3_ST_SR_CERT_VRFY_A:
case SSL3_ST_SR_CERT_VRFY_B:
- /* we should decide if we expected this one */
s->s3->flags |= SSL3_FLAGS_CCS_OK;
+ /* we should decide if we expected this one */
ret=ssl3_get_cert_verify(s);
if (ret <= 0) goto end;
@@ -694,7 +694,6 @@
channel_id = s->s3->tlsext_channel_id_valid;
#endif
- s->s3->flags |= SSL3_FLAGS_CCS_OK;
if (next_proto_neg)
s->state=SSL3_ST_SR_NEXT_PROTO_A;
else if (channel_id)
@@ -729,6 +728,7 @@
case SSL3_ST_SR_FINISHED_A:
case SSL3_ST_SR_FINISHED_B:
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
SSL3_ST_SR_FINISHED_B);
if (ret <= 0) goto end;
@@ -740,6 +740,15 @@
#endif
else
s->state=SSL3_ST_SW_CHANGE_A;
+ /* If this is a full handshake with ChannelID then
+ * record the hashshake hashes in |s->session| in case
+ * we need them to verify a ChannelID signature on a
+ * resumption of this session in the future. */
+ if (!s->hit && s->s3->tlsext_channel_id_new)
+ {
+ ret = tls1_record_handshake_hashes_for_channel_id(s);
+ if (ret <= 0) goto end;
+ }
s->init_num=0;
break;
@@ -1468,6 +1477,22 @@
if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
{
+ /* We only accept ChannelIDs on connections with ECDHE in order
+ * to avoid a known attack while we fix ChannelID itself. */
+ if (s->s3 &&
+ s->s3->tlsext_channel_id_valid &&
+ (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kEECDH) == 0)
+ s->s3->tlsext_channel_id_valid = 0;
+
+ /* If this is a resumption and the original handshake didn't
+ * support ChannelID then we didn't record the original
+ * handshake hashes in the session and so cannot resume with
+ * ChannelIDs. */
+ if (s->hit &&
+ s->s3->tlsext_channel_id_new &&
+ s->session->original_handshake_hash_len == 0)
+ s->s3->tlsext_channel_id_valid = 0;
+
buf=(unsigned char *)s->init_buf->data;
#ifdef OPENSSL_NO_TLSEXT
p=s->s3->server_random;
@@ -2143,6 +2168,11 @@
s->init_num=n+4;
s->init_off=0;
#ifdef NETSCAPE_HANG_BUG
+ if (!BUF_MEM_grow_clean(buf, s->init_num + 4))
+ {
+ SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
+ goto err;
+ }
p=(unsigned char *)s->init_buf->data + s->init_num;
/* do the header */
@@ -2885,6 +2915,8 @@
unsigned char premaster_secret[32], *start;
size_t outlen=32, inlen;
unsigned long alg_a;
+ int Ttag, Tclass;
+ long Tlen;
/* Get our certificate private key*/
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
@@ -2906,28 +2938,16 @@
ERR_clear_error();
}
/* Decrypt session key */
- if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED)))
+ if (ASN1_get_object((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, n) != V_ASN1_CONSTRUCTED ||
+ Ttag != V_ASN1_SEQUENCE ||
+ Tclass != V_ASN1_UNIVERSAL)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
goto gerr;
}
- if (p[1] == 0x81)
- {
- start = p+3;
- inlen = p[2];
- }
- else if (p[1] < 0x80)
- {
- start = p+2;
- inlen = p[1];
- }
- else
- {
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
- goto gerr;
- }
+ start = p;
+ inlen = Tlen;
if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0)
-
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
goto gerr;
@@ -3675,6 +3695,7 @@
EC_POINT* point = NULL;
ECDSA_SIG sig;
BIGNUM x, y;
+ unsigned short expected_extension_type;
if (s->state == SSL3_ST_SR_CHANNEL_ID_A && s->init_num == 0)
{
@@ -3732,7 +3753,11 @@
n2s(p, extension_type);
n2s(p, extension_len);
- if (extension_type != TLSEXT_TYPE_channel_id ||
+ expected_extension_type = TLSEXT_TYPE_channel_id;
+ if (s->s3->tlsext_channel_id_new)
+ expected_extension_type = TLSEXT_TYPE_channel_id_new;
+
+ if (extension_type != expected_extension_type ||
extension_len != TLSEXT_CHANNEL_ID_SIZE)
{
SSLerr(SSL_F_SSL3_GET_CHANNEL_ID,SSL_R_INVALID_MESSAGE);
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 54b0eb6..06bb90f 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -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
@@ -553,7 +560,7 @@
/* Allow initial connection to servers that don't support RI */
#define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L
#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L
-#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x00000010L
+#define SSL_OP_TLSEXT_PADDING 0x00000010L
#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L
#define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040L
#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x00000080L
@@ -562,6 +569,8 @@
/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */
#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0
+/* Refers to ancient SSLREF and SSLv2, retained for compatibility */
+#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x0
/* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS is vestigial. Previously it disabled the
* insertion of empty records in CBC mode, but the empty records were commonly
@@ -648,12 +657,14 @@
* TLS only.) "Released" buffers are put onto a free-list in the context
* or just freed (depending on the context's setting for freelist_max_len). */
#define SSL_MODE_RELEASE_BUFFERS 0x00000010L
+
/* Send the current time in the Random fields of the ClientHello and
* ServerHello records for compatibility with hypothetical implementations
* that require it.
*/
#define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
#define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
+
/* When set, clients may send application data before receipt of CCS
* and Finished. This mode enables full-handshakes to 'complete' in
* one RTT. */
@@ -866,6 +877,9 @@
/* get client cert callback */
int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+ /* get channel id callback */
+ void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey);
+
/* cookie generate callback */
int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie,
unsigned int *cookie_len);
@@ -1028,6 +1042,10 @@
/* If true, a client will advertise the Channel ID extension and a
* server will echo it. */
char tlsext_channel_id_enabled;
+ /* tlsext_channel_id_enabled_new is a hack to support both old and new
+ * ChannelID signatures. It indicates that a client should advertise the
+ * new ChannelID extension number. */
+ char tlsext_channel_id_enabled_new;
/* The client's Channel ID private key. */
EVP_PKEY *tlsext_channel_id_private;
#endif
@@ -1086,6 +1104,8 @@
void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val);
void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey));
+void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey);
#ifndef OPENSSL_NO_ENGINE
int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
#endif
@@ -1162,12 +1182,14 @@
#define SSL_WRITING 2
#define SSL_READING 3
#define SSL_X509_LOOKUP 4
+#define SSL_CHANNEL_ID_LOOKUP 5
/* These will only be used when doing non-blocking IO */
#define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING)
#define SSL_want_read(s) (SSL_want(s) == SSL_READING)
#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING)
#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
+#define SSL_want_channel_id_lookup(s) (SSL_want(s) == SSL_CHANNEL_ID_LOOKUP)
#define SSL_MAC_FLAG_READ_MAC_STREAM 1
#define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
@@ -1602,6 +1624,7 @@
#define SSL_ERROR_ZERO_RETURN 6
#define SSL_ERROR_WANT_CONNECT 7
#define SSL_ERROR_WANT_ACCEPT 8
+#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP 9
#define SSL_CTRL_NEED_TMP_RSA 1
#define SSL_CTRL_SET_TMP_RSA 2
@@ -1739,10 +1762,11 @@
#define SSL_set_tmp_ecdh(ssl,ecdh) \
SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
-/* SSL_enable_tls_channel_id configures a TLS server to accept TLS client
- * IDs from clients. Returns 1 on success. */
-#define SSL_enable_tls_channel_id(ctx) \
- SSL_ctrl(ctx,SSL_CTRL_CHANNEL_ID,0,NULL)
+/* SSL_enable_tls_channel_id either configures a TLS server to accept TLS client
+ * IDs from clients, or configure a client to send TLS client IDs to server.
+ * Returns 1 on success. */
+#define SSL_enable_tls_channel_id(s) \
+ SSL_ctrl(s,SSL_CTRL_CHANNEL_ID,0,NULL)
/* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to
* compatible servers. private_key must be a P-256 EVP_PKEY*. Returns 1 on
* success. */
@@ -1792,7 +1816,6 @@
char * SSL_CIPHER_get_version(const SSL_CIPHER *c);
const char * SSL_CIPHER_get_name(const SSL_CIPHER *c);
unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c);
-const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher);
int SSL_get_fd(const SSL *s);
int SSL_get_rfd(const SSL *s);
@@ -2707,7 +2730,6 @@
#define SSL_R_WRONG_VERSION_NUMBER 267
#define SSL_R_X509_LIB 268
#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269
-#define SSL_R_UNEXPECTED_CCS 388
#ifdef __cplusplus
}
diff --git a/ssl/ssl3.h b/ssl/ssl3.h
index f205f73..83d59bf 100644
--- a/ssl/ssl3.h
+++ b/ssl/ssl3.h
@@ -388,9 +388,6 @@
#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008
#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010
#define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020
-/* SSL3_FLAGS_CCS_OK indicates that a ChangeCipherSpec record is acceptable at
- * this point in the handshake. If this flag is not set then received CCS
- * records will cause a fatal error for the connection. */
#define SSL3_FLAGS_CCS_OK 0x0080
/* SSL3_FLAGS_SGC_RESTART_DONE is set when we
@@ -558,6 +555,11 @@
* for Channel IDs and that tlsext_channel_id will be valid after the
* handshake. */
char tlsext_channel_id_valid;
+ /* tlsext_channel_id_new means that the updated Channel ID extension
+ * was negotiated. This is a temporary hack in the code to support both
+ * forms of Channel ID extension while we transition to the new format,
+ * which fixed a security issue. */
+ char tlsext_channel_id_new;
/* For a server:
* If |tlsext_channel_id_valid| is true, then this contains the
* verified Channel ID from the client: a P256 point, (x,y), where
@@ -678,11 +680,11 @@
#define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT)
-#define SSL3_ST_SR_POST_CLIENT_CERT (0x1BF|SSL_ST_ACCEPT)
#ifndef OPENSSL_NO_NEXTPROTONEG
#define SSL3_ST_SR_NEXT_PROTO_A (0x210|SSL_ST_ACCEPT)
#define SSL3_ST_SR_NEXT_PROTO_B (0x211|SSL_ST_ACCEPT)
#endif
+#define SSL3_ST_SR_POST_CLIENT_CERT (0x1BF|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CHANNEL_ID_A (0x220|SSL_ST_ACCEPT)
#define SSL3_ST_SR_CHANNEL_ID_B (0x221|SSL_ST_ACCEPT)
#define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT)
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index 38540be..f83e18f 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -117,12 +117,13 @@
#ifndef OPENSSL_NO_SRP
ASN1_OCTET_STRING srp_username;
#endif /* OPENSSL_NO_SRP */
+ ASN1_OCTET_STRING original_handshake_hash;
} SSL_SESSION_ASN1;
int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
{
#define LSIZE2 (sizeof(long)*2)
- int v1=0,v2=0,v3=0,v4=0,v5=0,v7=0,v8=0;
+ int v1=0,v2=0,v3=0,v4=0,v5=0,v7=0,v8=0,v14=0;
unsigned char buf[4],ibuf1[LSIZE2],ibuf2[LSIZE2];
unsigned char ibuf3[LSIZE2],ibuf4[LSIZE2],ibuf5[LSIZE2];
#ifndef OPENSSL_NO_TLSEXT
@@ -272,6 +273,13 @@
a.psk_identity.type=V_ASN1_OCTET_STRING;
a.psk_identity.data=(unsigned char *)(in->psk_identity);
}
+
+ if (in->original_handshake_hash_len > 0)
+ {
+ a.original_handshake_hash.length = in->original_handshake_hash_len;
+ a.original_handshake_hash.type = V_ASN1_OCTET_STRING;
+ a.original_handshake_hash.data = in->original_handshake_hash;
+ }
#endif /* OPENSSL_NO_PSK */
#ifndef OPENSSL_NO_SRP
if (in->srp_username)
@@ -325,6 +333,8 @@
if (in->srp_username)
M_ASN1_I2D_len_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12);
#endif /* OPENSSL_NO_SRP */
+ if (in->original_handshake_hash_len > 0)
+ M_ASN1_I2D_len_EXP_opt(&(a.original_handshake_hash),i2d_ASN1_OCTET_STRING,14,v14);
M_ASN1_I2D_seq_total();
@@ -373,6 +383,8 @@
if (in->srp_username)
M_ASN1_I2D_put_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12);
#endif /* OPENSSL_NO_SRP */
+ if (in->original_handshake_hash_len > 0)
+ M_ASN1_I2D_put_EXP_opt(&(a.original_handshake_hash),i2d_ASN1_OCTET_STRING,14,v14);
M_ASN1_I2D_finish();
}
@@ -408,6 +420,7 @@
if (os.length != 3)
{
c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
+ c.line=__LINE__;
goto err;
}
id=0x02000000L|
@@ -420,6 +433,7 @@
if (os.length != 2)
{
c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
+ c.line=__LINE__;
goto err;
}
id=0x03000000L|
@@ -429,6 +443,7 @@
else
{
c.error=SSL_R_UNKNOWN_SSL_VERSION;
+ c.line=__LINE__;
goto err;
}
@@ -521,6 +536,7 @@
if (os.length > SSL_MAX_SID_CTX_LENGTH)
{
c.error=SSL_R_BAD_LENGTH;
+ c.line=__LINE__;
goto err;
}
else
@@ -638,5 +654,16 @@
ret->srp_username=NULL;
#endif /* OPENSSL_NO_SRP */
+ os.length=0;
+ os.data=NULL;
+ M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,14);
+ if (os.data && os.length < (int)sizeof(ret->original_handshake_hash))
+ {
+ memcpy(ret->original_handshake_hash, os.data, os.length);
+ ret->original_handshake_hash_len = os.length;
+ OPENSSL_free(os.data);
+ os.data = NULL;
+ }
+
M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION);
}
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index bddd794..ac0aad9 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -553,7 +553,7 @@
{ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME),"tlsv1 unrecognized name"},
{ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION),"tlsv1 unsupported extension"},
{ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER),"tls client cert req with anon cipher"},
-{ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT),"peer does not accept heartbearts"},
+{ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT),"peer does not accept heartbeats"},
{ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING) ,"heartbeat request already pending"},
{ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL),"tls illegal exporter label"},
{ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),"tls invalid ecpointformat list"},
@@ -604,7 +604,6 @@
{ERR_REASON(SSL_R_WRONG_VERSION_NUMBER) ,"wrong version number"},
{ERR_REASON(SSL_R_X509_LIB) ,"x509 lib"},
{ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS),"x509 verification setup problems"},
-{ERR_REASON(SSL_R_UNEXPECTED_CCS),"unexpected CCS"},
{0,NULL}
};
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 8d2c3a7..3de68a7 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1403,6 +1403,10 @@
p=buf;
sk=s->session->ciphers;
+
+ if (sk_SSL_CIPHER_num(sk) == 0)
+ return NULL;
+
for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
{
int n;
@@ -2671,6 +2675,10 @@
{
return(SSL_ERROR_WANT_X509_LOOKUP);
}
+ if ((i < 0) && SSL_want_channel_id_lookup(s))
+ {
+ return(SSL_ERROR_WANT_CHANNEL_ID_LOOKUP);
+ }
if (i == 0)
{
@@ -3419,12 +3427,41 @@
s->version >= SSL3_VERSION &&
s->s3->in_read_app_data == 0 && /* cutthrough only applies to write() */
(SSL_get_mode((SSL*)s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) && /* cutthrough enabled */
- SSL_get_cipher_bits(s, NULL) >= 128 && /* strong cipher choosen */
+ ssl3_can_cutthrough(s) && /* cutthrough allowed */
s->s3->previous_server_finished_len == 0 && /* not a renegotiation handshake */
(s->state == SSL3_ST_CR_SESSION_TICKET_A || /* ready to write app-data*/
s->state == SSL3_ST_CR_FINISHED_A));
}
+int ssl3_can_cutthrough(const SSL *s)
+ {
+ const SSL_CIPHER *c;
+
+ /* require a strong enough cipher */
+ if (SSL_get_cipher_bits(s, NULL) < 128)
+ return 0;
+
+ /* require ALPN or NPN extension */
+ if (!s->s3->alpn_selected
+#ifndef OPENSSL_NO_NEXTPROTONEG
+ && !s->s3->next_proto_neg_seen
+#endif
+ )
+ {
+ return 0;
+ }
+
+ /* require a forward-secret cipher */
+ c = SSL_get_current_cipher(s);
+ if (!c || (c->algorithm_mkey != SSL_kEDH &&
+ c->algorithm_mkey != SSL_kEECDH))
+ {
+ return 0;
+ }
+
+ return 1;
+ }
+
/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
* vairable, freeing EVP_MD_CTX previously stored in that variable, if
* any. If EVP_MD pointer is passed, initializes ctx with this md
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index f79ab00..6b7731a 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1070,6 +1070,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);
@@ -1126,8 +1127,10 @@
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);
EVP_MD_CTX* ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) ;
void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index ec08840..7d17085 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -1144,6 +1144,17 @@
return ctx->client_cert_cb;
}
+void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx,
+ void (*cb)(SSL *ssl, EVP_PKEY **pkey))
+ {
+ ctx->channel_id_cb=cb;
+ }
+
+void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL * ssl, EVP_PKEY **pkey)
+ {
+ return ctx->channel_id_cb;
+ }
+
#ifndef OPENSSL_NO_ENGINE
int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e)
{
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 2ed2e07..22dd3ca 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -895,54 +895,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 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)
{
- int hashsize = EVP_MD_size(md);
- EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx];
- if (!hdgst || hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
- {
- /* internal error: 'buf' is too small for this cipersuite! */
- err = 1;
- }
- else
- {
- if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
- !EVP_DigestFinal_ex(&ctx,q,&i) ||
- (i != (unsigned int)hashsize))
- err = 1;
- q+=hashsize;
- }
+ 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 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;
@@ -1048,14 +1073,10 @@
if (!stream_mac)
EVP_MD_CTX_cleanup(&hmac);
#ifdef TLS_DEBUG
-printf("sec=");
-{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
printf("seq=");
{int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); }
-printf("buf=");
-{int z; for (z=0; z<5; z++) printf("%02X ",buf[z]); printf("\n"); }
printf("rec=");
-{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
+{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",rec->data[z]); printf("\n"); }
#endif
if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER)
@@ -1185,7 +1206,7 @@
if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1;
- rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+ rv = tls1_PRF(ssl_get_algorithm2(s),
val, vallen,
NULL, 0,
NULL, 0,
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 369e09f..122a25f 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -617,6 +617,8 @@
#ifndef OPENSSL_NO_HEARTBEATS
/* Add Heartbeat extension */
+ if ((limit - ret - 4 - 1) < 0)
+ return NULL;
s2n(TLSEXT_TYPE_heartbeat,ret);
s2n(1,ret);
/* Set mode:
@@ -647,7 +649,10 @@
* support for Channel ID. */
if (limit - ret - 4 < 0)
return NULL;
- s2n(TLSEXT_TYPE_channel_id,ret);
+ if (s->ctx->tlsext_channel_id_enabled_new)
+ s2n(TLSEXT_TYPE_channel_id_new,ret);
+ else
+ s2n(TLSEXT_TYPE_channel_id,ret);
s2n(0,ret);
}
@@ -683,36 +688,35 @@
ret += el;
}
#endif
-
-#ifdef TLSEXT_TYPE_padding
/* Add padding to workaround bugs in F5 terminators.
* See https://tools.ietf.org/html/draft-agl-tls-padding-03
*
* NB: because this code works out the length of all existing
* extensions it MUST always appear last.
*/
- {
- int hlen = ret - (unsigned char *)s->init_buf->data;
- /* The code in s23_clnt.c to build ClientHello messages includes the
- * 5-byte record header in the buffer, while the code in s3_clnt.c does
- * not. */
- if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
- hlen -= 5;
- if (hlen > 0xff && hlen < 0x200)
+ if (s->options & SSL_OP_TLSEXT_PADDING)
{
- hlen = 0x200 - hlen;
- if (hlen >= 4)
- hlen -= 4;
- else
- hlen = 0;
+ int hlen = ret - (unsigned char *)s->init_buf->data;
+ /* The code in s23_clnt.c to build ClientHello messages
+ * includes the 5-byte record header in the buffer, while
+ * the code in s3_clnt.c does not.
+ */
+ if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
+ hlen -= 5;
+ if (hlen > 0xff && hlen < 0x200)
+ {
+ hlen = 0x200 - hlen;
+ if (hlen >= 4)
+ hlen -= 4;
+ else
+ hlen = 0;
- s2n(TLSEXT_TYPE_padding, ret);
- s2n(hlen, ret);
- memset(ret, 0, hlen);
- ret += hlen;
+ s2n(TLSEXT_TYPE_padding, ret);
+ s2n(hlen, ret);
+ memset(ret, 0, hlen);
+ ret += hlen;
+ }
}
- }
-#endif
if ((extdatalen = ret-p-2)== 0)
return p;
@@ -867,6 +871,8 @@
/* Add Heartbeat extension if we've received one */
if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED)
{
+ if ((limit - ret - 4 - 1) < 0)
+ return NULL;
s2n(TLSEXT_TYPE_heartbeat,ret);
s2n(1,ret);
/* Set mode:
@@ -909,7 +915,10 @@
{
if (limit - ret - 4 < 0)
return NULL;
- s2n(TLSEXT_TYPE_channel_id,ret);
+ if (s->s3->tlsext_channel_id_new)
+ s2n(TLSEXT_TYPE_channel_id_new,ret);
+ else
+ s2n(TLSEXT_TYPE_channel_id,ret);
s2n(0,ret);
}
@@ -1572,6 +1581,13 @@
else if (type == TLSEXT_TYPE_channel_id && s->tlsext_channel_id_enabled)
s->s3->tlsext_channel_id_valid = 1;
+ else if (type == TLSEXT_TYPE_channel_id_new &&
+ s->tlsext_channel_id_enabled)
+ {
+ s->s3->tlsext_channel_id_valid = 1;
+ s->s3->tlsext_channel_id_new = 1;
+ }
+
else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
s->ctx->alpn_select_cb &&
s->s3->tmp.finish_md_len == 0)
@@ -1821,6 +1837,12 @@
else if (type == TLSEXT_TYPE_channel_id)
s->s3->tlsext_channel_id_valid = 1;
+ else if (type == TLSEXT_TYPE_channel_id_new)
+ {
+ s->s3->tlsext_channel_id_valid = 1;
+ s->s3->tlsext_channel_id_new = 1;
+ }
+
else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation)
{
unsigned len;
@@ -2908,6 +2930,17 @@
EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
+ if (s->hit && s->s3->tlsext_channel_id_new)
+ {
+ 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++)
{
@@ -2922,3 +2955,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_new)
+ 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 ec8948d..6652089 100644
--- a/ssl/tls1.h
+++ b/ssl/tls1.h
@@ -259,6 +259,7 @@
/* This is not an IANA defined extension number */
#define TLSEXT_TYPE_channel_id 30031
+#define TLSEXT_TYPE_channel_id_new 30032
/* NameType value from RFC 3546 */
#define TLSEXT_NAMETYPE_host_name 0