diff options
Diffstat (limited to 'main/openssl')
73 files changed, 613 insertions, 1088 deletions
diff --git a/main/openssl/Apps-config-host.mk b/main/openssl/Apps-config-host.mk index 37dcb78b..5c1604e0 100644 --- a/main/openssl/Apps-config-host.mk +++ b/main/openssl/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/main/openssl/Apps-config-target.mk b/main/openssl/Apps-config-target.mk index bccd250d..0c567d4d 100644 --- a/main/openssl/Apps-config-target.mk +++ b/main/openssl/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/main/openssl/Crypto-config-host.mk b/main/openssl/Crypto-config-host.mk index a377fec4..988df044 100644 --- a/main/openssl/Crypto-config-host.mk +++ b/main/openssl/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/main/openssl/Crypto-config-target.mk b/main/openssl/Crypto-config-target.mk index 2c5b01e5..6dc14066 100644 --- a/main/openssl/Crypto-config-target.mk +++ b/main/openssl/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/main/openssl/Crypto-config-trusty.mk b/main/openssl/Crypto-config-trusty.mk index dc5b12c2..59915986 100644 --- a/main/openssl/Crypto-config-trusty.mk +++ b/main/openssl/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/main/openssl/Crypto.mk b/main/openssl/Crypto.mk index 4214b91e..dbabfc6c 100644 --- a/main/openssl/Crypto.mk +++ b/main/openssl/Crypto.mk @@ -31,7 +31,7 @@ LOCAL_SHARED_LIBRARIES := $(log_shared_libraries) # in the NDK. ifeq (,$(TARGET_BUILD_APPS)) LOCAL_CLANG := true -ifeq ($(HOST_OS), darwin_XXX) +ifeq ($(HOST_OS), darwin) LOCAL_ASFLAGS += -no-integrated-as LOCAL_CFLAGS += -no-integrated-as endif diff --git a/main/openssl/Ssl-config-host.mk b/main/openssl/Ssl-config-host.mk index 95035487..57ea3775 100644 --- a/main/openssl/Ssl-config-host.mk +++ b/main/openssl/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/main/openssl/Ssl-config-target.mk b/main/openssl/Ssl-config-target.mk index 32439d3f..c08a971d 100644 --- a/main/openssl/Ssl-config-target.mk +++ b/main/openssl/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/main/openssl/apps/enc.c b/main/openssl/apps/enc.c index 719acc32..19ea3df9 100644 --- a/main/openssl/apps/enc.c +++ b/main/openssl/apps/enc.c @@ -331,6 +331,12 @@ bad: 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/main/openssl/apps/ocsp.c b/main/openssl/apps/ocsp.c index 83c5a767..767f12c6 100644 --- a/main/openssl/apps/ocsp.c +++ b/main/openssl/apps/ocsp.c @@ -127,6 +127,7 @@ int MAIN(int argc, char **argv) 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 @@ int MAIN(int argc, char **argv) } 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 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "Error parsing URL\n"); badarg = 1; } + thost = host; + tport = port; + tpath = path; } else badarg = 1; } @@ -920,12 +930,12 @@ end: 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/main/openssl/apps/req.c b/main/openssl/apps/req.c index 5e034a85..d41385d7 100644 --- a/main/openssl/apps/req.c +++ b/main/openssl/apps/req.c @@ -1489,7 +1489,13 @@ start: #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 @@ start: #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/main/openssl/apps/s_cb.c b/main/openssl/apps/s_cb.c index 84c3b447..146a9607 100644 --- a/main/openssl/apps/s_cb.c +++ b/main/openssl/apps/s_cb.c @@ -747,6 +747,10 @@ void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type, break; #endif + case TLSEXT_TYPE_padding: + extname = "TLS padding"; + break; + default: extname = "unknown"; break; diff --git a/main/openssl/apps/s_socket.c b/main/openssl/apps/s_socket.c index 380efdb1..94eb40f3 100644 --- a/main/openssl/apps/s_socket.c +++ b/main/openssl/apps/s_socket.c @@ -274,7 +274,7 @@ static int init_client_ip(int *sock, unsigned char ip[4], int port, int type) { 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 @@ redoit: 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 @@ redoit: 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/main/openssl/apps/smime.c b/main/openssl/apps/smime.c index c583f8a0..d1fe32d3 100644 --- a/main/openssl/apps/smime.c +++ b/main/openssl/apps/smime.c @@ -541,8 +541,8 @@ int MAIN(int argc, char **argv) { 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/main/openssl/build-config-32.mk b/main/openssl/build-config-32.mk index 4f7484b9..bc2aa442 100644 --- a/main/openssl/build-config-32.mk +++ b/main/openssl/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/main/openssl/build-config-64.mk b/main/openssl/build-config-64.mk index c0e6f6de..fde3b6ab 100644 --- a/main/openssl/build-config-64.mk +++ b/main/openssl/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/main/openssl/build-config-trusty.mk b/main/openssl/build-config-trusty.mk index e5809a3b..4d6fb58c 100644 --- a/main/openssl/build-config-trusty.mk +++ b/main/openssl/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/main/openssl/crypto/asn1/a_strnid.c b/main/openssl/crypto/asn1/a_strnid.c index 2fc48c15..2afd5a41 100644 --- a/main/openssl/crypto/asn1/a_strnid.c +++ b/main/openssl/crypto/asn1/a_strnid.c @@ -74,7 +74,7 @@ static int sk_table_cmp(const ASN1_STRING_TABLE * const *a, * 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/main/openssl/crypto/bio/bio.h b/main/openssl/crypto/bio/bio.h index 05699ab2..d05fa22a 100644 --- a/main/openssl/crypto/bio/bio.h +++ b/main/openssl/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/main/openssl/crypto/bio/bss_dgram.c b/main/openssl/crypto/bio/bss_dgram.c index 54c012c4..d9967e72 100644 --- a/main/openssl/crypto/bio/bss_dgram.c +++ b/main/openssl/crypto/bio/bss_dgram.c @@ -1333,7 +1333,7 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) 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 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) /* 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 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) 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/main/openssl/crypto/bn/bn_mont.c b/main/openssl/crypto/bn/bn_mont.c index 427b5cf4..ee8532c7 100644 --- a/main/openssl/crypto/bn/bn_mont.c +++ b/main/openssl/crypto/bn/bn_mont.c @@ -478,32 +478,38 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) 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) + ret = *pmont; + 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)) { - CRYPTO_r_unlock(lock); - CRYPTO_w_lock(lock); - got_write_lock = 1; + BN_MONT_CTX_free(ret); + return NULL; + } - if (!*pmont) - { - ret = BN_MONT_CTX_new(); - if (ret && !BN_MONT_CTX_set(ret, mod, ctx)) - BN_MONT_CTX_free(ret); - else - *pmont = ret; - } + /* The locked compare-and-set, after the local work is done. */ + CRYPTO_w_lock(lock); + if (*pmont) + { + BN_MONT_CTX_free(ret); + ret = *pmont; } - - ret = *pmont; - - if (got_write_lock) - CRYPTO_w_unlock(lock); else - CRYPTO_r_unlock(lock); - + *pmont = ret; + CRYPTO_w_unlock(lock); return ret; } diff --git a/main/openssl/crypto/cms/cms_env.c b/main/openssl/crypto/cms/cms_env.c index be20b1c0..add00bf9 100644 --- a/main/openssl/crypto/cms/cms_env.c +++ b/main/openssl/crypto/cms/cms_env.c @@ -185,6 +185,8 @@ CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, if (flags & CMS_USE_KEYID) { ktri->version = 2; + if (env->version < 2) + env->version = 2; type = CMS_RECIPINFO_KEYIDENTIFIER; } else diff --git a/main/openssl/crypto/cms/cms_sd.c b/main/openssl/crypto/cms/cms_sd.c index 77fbd135..51dd33a1 100644 --- a/main/openssl/crypto/cms/cms_sd.c +++ b/main/openssl/crypto/cms/cms_sd.c @@ -158,8 +158,8 @@ static void cms_sd_set_version(CMS_SignedData *sd) 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/main/openssl/crypto/cms/cms_smime.c b/main/openssl/crypto/cms/cms_smime.c index 8c56e3a8..1af9f3a6 100644 --- a/main/openssl/crypto/cms/cms_smime.c +++ b/main/openssl/crypto/cms/cms_smime.c @@ -611,7 +611,7 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) 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 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) 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 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) } } /* 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/main/openssl/crypto/dso/dso_dlfcn.c b/main/openssl/crypto/dso/dso_dlfcn.c index 5f225480..4a56aace 100644 --- a/main/openssl/crypto/dso/dso_dlfcn.c +++ b/main/openssl/crypto/dso/dso_dlfcn.c @@ -464,7 +464,7 @@ static int dlfcn_pathbyaddr(void *addr,char *path,int sz) return len; } - ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror()); + ERR_add_error_data(2, "dlfcn_pathbyaddr(): ", dlerror()); #endif return -1; } diff --git a/main/openssl/crypto/ec/ec_ameth.c b/main/openssl/crypto/ec/ec_ameth.c index 0ce45240..f715a238 100644 --- a/main/openssl/crypto/ec/ec_ameth.c +++ b/main/openssl/crypto/ec/ec_ameth.c @@ -352,6 +352,7 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) 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/main/openssl/crypto/ec/ec_asn1.c b/main/openssl/crypto/ec/ec_asn1.c index 145807b6..e94f34e1 100644 --- a/main/openssl/crypto/ec/ec_asn1.c +++ b/main/openssl/crypto/ec/ec_asn1.c @@ -1435,8 +1435,11 @@ int i2o_ECPublicKey(EC_KEY *a, unsigned char **out) *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/main/openssl/crypto/ec/ec_lcl.h b/main/openssl/crypto/ec/ec_lcl.h index 6f714c75..dae91483 100644 --- a/main/openssl/crypto/ec/ec_lcl.h +++ b/main/openssl/crypto/ec/ec_lcl.h @@ -405,7 +405,7 @@ int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 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/main/openssl/crypto/evp/bio_b64.c b/main/openssl/crypto/evp/bio_b64.c index ac6d441a..16863fe2 100644 --- a/main/openssl/crypto/evp/bio_b64.c +++ b/main/openssl/crypto/evp/bio_b64.c @@ -226,6 +226,7 @@ static int b64_read(BIO *b, char *out, int outl) 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/main/openssl/crypto/evp/encode.c b/main/openssl/crypto/evp/encode.c index 28546a84..4654bdc6 100644 --- a/main/openssl/crypto/evp/encode.c +++ b/main/openssl/crypto/evp/encode.c @@ -324,6 +324,7 @@ int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, 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/main/openssl/crypto/evp/p_lib.c b/main/openssl/crypto/evp/p_lib.c index bd1977d7..8ee53c1d 100644 --- a/main/openssl/crypto/evp/p_lib.c +++ b/main/openssl/crypto/evp/p_lib.c @@ -202,7 +202,7 @@ EVP_PKEY *EVP_PKEY_new(void) 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/main/openssl/crypto/opensslv.h b/main/openssl/crypto/opensslv.h index ebe71807..c3b6acec 100644 --- a/main/openssl/crypto/opensslv.h +++ b/main/openssl/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/main/openssl/crypto/pkcs12/p12_crt.c b/main/openssl/crypto/pkcs12/p12_crt.c index a34915d0..35e8a4a8 100644 --- a/main/openssl/crypto/pkcs12/p12_crt.c +++ b/main/openssl/crypto/pkcs12/p12_crt.c @@ -96,7 +96,11 @@ PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, 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 @@ int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, 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/main/openssl/crypto/pkcs12/p12_kiss.c b/main/openssl/crypto/pkcs12/p12_kiss.c index 206b1b0b..c9b7ab61 100644 --- a/main/openssl/crypto/pkcs12/p12_kiss.c +++ b/main/openssl/crypto/pkcs12/p12_kiss.c @@ -269,7 +269,7 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, 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/main/openssl/crypto/pkcs7/pk7_doit.c b/main/openssl/crypto/pkcs7/pk7_doit.c index 77fda3b8..d91aa116 100644 --- a/main/openssl/crypto/pkcs7/pk7_doit.c +++ b/main/openssl/crypto/pkcs7/pk7_doit.c @@ -440,6 +440,11 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { 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 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) 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/main/openssl/crypto/pkcs7/pkcs7.h b/main/openssl/crypto/pkcs7/pkcs7.h index e4d44319..04f60379 100644 --- a/main/openssl/crypto/pkcs7/pkcs7.h +++ b/main/openssl/crypto/pkcs7/pkcs7.h @@ -453,6 +453,7 @@ void ERR_load_PKCS7_strings(void); #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/main/openssl/crypto/pkcs7/pkcs7err.c b/main/openssl/crypto/pkcs7/pkcs7err.c index d0af32a2..f3db08e0 100644 --- a/main/openssl/crypto/pkcs7/pkcs7err.c +++ b/main/openssl/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 @@ static ERR_STRING_DATA PKCS7_str_reasons[]= {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/main/openssl/crypto/rsa/rsa_ameth.c b/main/openssl/crypto/rsa/rsa_ameth.c index 5a2062f9..4c8ecd92 100644 --- a/main/openssl/crypto/rsa/rsa_ameth.c +++ b/main/openssl/crypto/rsa/rsa_ameth.c @@ -358,7 +358,7 @@ static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss, 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/main/openssl/crypto/srp/srp_vfy.c b/main/openssl/crypto/srp/srp_vfy.c index 4a3d13ed..fdca19ff 100644 --- a/main/openssl/crypto/srp/srp_vfy.c +++ b/main/openssl/crypto/srp/srp_vfy.c @@ -93,6 +93,9 @@ static int t_fromb64(unsigned char *a, const char *src) 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/main/openssl/crypto/x509v3/v3_purp.c b/main/openssl/crypto/x509v3/v3_purp.c index ad688657..f59bfc18 100644 --- a/main/openssl/crypto/x509v3/v3_purp.c +++ b/main/openssl/crypto/x509v3/v3_purp.c @@ -389,8 +389,8 @@ static void x509v3_cache_extensions(X509 *x) /* 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 @@ static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, 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/main/openssl/import_openssl.sh b/main/openssl/import_openssl.sh index 02d2ab1c..4ae7e333 100755 --- a/main/openssl/import_openssl.sh +++ b/main/openssl/import_openssl.sh @@ -610,12 +610,13 @@ function applypatches () { 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/main/openssl/include/openssl/bio.h b/main/openssl/include/openssl/bio.h index 05699ab2..d05fa22a 100644 --- a/main/openssl/include/openssl/bio.h +++ b/main/openssl/include/openssl/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/main/openssl/include/openssl/opensslv.h b/main/openssl/include/openssl/opensslv.h index ebe71807..c3b6acec 100644 --- a/main/openssl/include/openssl/opensslv.h +++ b/main/openssl/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/main/openssl/include/openssl/pkcs7.h b/main/openssl/include/openssl/pkcs7.h index e4d44319..04f60379 100644 --- a/main/openssl/include/openssl/pkcs7.h +++ b/main/openssl/include/openssl/pkcs7.h @@ -453,6 +453,7 @@ void ERR_load_PKCS7_strings(void); #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/main/openssl/include/openssl/ssl.h b/main/openssl/include/openssl/ssl.h index 54b0eb6c..06bb90f8 100644 --- a/main/openssl/include/openssl/ssl.h +++ b/main/openssl/include/openssl/ssl.h @@ -544,6 +544,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 @@ -553,7 +560,7 @@ struct ssl_session_st /* 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 @@ struct ssl_session_st /* 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 @@ 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. */ #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 @@ 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); @@ -1028,6 +1042,10 @@ struct ssl_ctx_st /* 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_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 @@ -1162,12 +1182,14 @@ 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 */ #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 @@ 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 #define SSL_CTRL_SET_TMP_RSA 2 @@ -1739,10 +1762,11 @@ 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_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 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits); 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 @@ 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 } diff --git a/main/openssl/include/openssl/ssl3.h b/main/openssl/include/openssl/ssl3.h index f205f73d..83d59bff 100644 --- a/main/openssl/include/openssl/ssl3.h +++ b/main/openssl/include/openssl/ssl3.h @@ -388,9 +388,6 @@ 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 @@ -558,6 +555,11 @@ typedef struct ssl3_state_st * 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 @@ 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_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/main/openssl/include/openssl/tls1.h b/main/openssl/include/openssl/tls1.h index ec8948d5..66520893 100644 --- a/main/openssl/include/openssl/tls1.h +++ b/main/openssl/include/openssl/tls1.h @@ -259,6 +259,7 @@ extern "C" { /* 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/main/openssl/openssl.config b/main/openssl/openssl.config index aa028705..d44b0bbc 100644 --- a/main/openssl/openssl.config +++ b/main/openssl/openssl.config @@ -94,7 +94,6 @@ README.ASN1 \ 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 @@ apps/vms_decc_init.c \ 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/bfs.cpp \ 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_utils.c \ 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 @@ makevms.com \ 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/version.c \ 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/main/openssl/openssl.version b/main/openssl/openssl.version index 2e849911..ab2e62bf 100644 --- a/main/openssl/openssl.version +++ b/main/openssl/openssl.version @@ -1 +1 @@ -OPENSSL_VERSION=1.0.1g +OPENSSL_VERSION=1.0.1h diff --git a/main/openssl/patches/handshake_cutthrough.patch b/main/openssl/patches/handshake_cutthrough.patch deleted file mode 100644 index f05a10fd..00000000 --- a/main/openssl/patches/handshake_cutthrough.patch +++ /dev/null @@ -1,311 +0,0 @@ -From d0e735d01271055f09bc4a1be034253e6e3c2dee 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 - -Enables SSL3+ clients to send application data immediately following the -Finished message even when negotiating full-handshakes. With this -patch, clients can negotiate SSL connections in 1-RTT even when -performing full-handshakes. ---- - apps/s_client.c | 13 +++++++++++++ - ssl/s3_clnt.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++------ - ssl/s3_lib.c | 15 ++++++++++++++- - ssl/ssl.h | 8 +++++++- - ssl/ssl3.h | 1 + - ssl/ssl_lib.c | 13 +++++++++++++ - ssl/ssltest.c | 12 ++++++++++++ - test/testssl | 3 +++ - 8 files changed, 110 insertions(+), 8 deletions(-) - -diff --git a/apps/s_client.c b/apps/s_client.c -index 3ba6605..791e277 100644 ---- a/apps/s_client.c -+++ b/apps/s_client.c -@@ -361,6 +361,7 @@ static void sc_usage(void) - BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n"); - # endif - #endif -+ BIO_printf(bio_err," -cutthrough - enable 1-RTT full-handshake for strong ciphers\n"); - BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n"); - #ifndef OPENSSL_NO_SRTP - BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n"); -@@ -577,6 +578,7 @@ int MAIN(int argc, char **argv) - EVP_PKEY *key = NULL; - char *CApath=NULL,*CAfile=NULL,*cipher=NULL; - int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0; -+ int cutthrough=0; - int crlf=0; - int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending; - SSL_CTX *ctx=NULL; -@@ -883,6 +885,8 @@ int MAIN(int argc, char **argv) - } - # endif - #endif -+ else if (strcmp(*argv,"-cutthrough") == 0) -+ cutthrough=1; - else if (strcmp(*argv,"-serverpref") == 0) - off|=SSL_OP_CIPHER_SERVER_PREFERENCE; - else if (strcmp(*argv,"-legacy_renegotiation") == 0) -@@ -1158,6 +1162,15 @@ bad: - SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto); - #endif - -+ /* Enable handshake cutthrough for client connections using -+ * strong ciphers. */ -+ if (cutthrough) -+ { -+ int ssl_mode = SSL_CTX_get_mode(ctx); -+ ssl_mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH; -+ SSL_CTX_set_mode(ctx, ssl_mode); -+ } -+ - if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback); - 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 ---- a/ssl/s3_clnt.c -+++ b/ssl/s3_clnt.c -@@ -215,6 +215,24 @@ 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) - } - else - { --#ifndef OPENSSL_NO_TLSEXT -- /* 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 -+ && s->s3->previous_server_finished_len == 0 /* no cutthrough on renegotiation (would complicate the state machine) */ -+ ) -+ { -+ if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) -+ { -+ s->state=SSL3_ST_CUTTHROUGH_COMPLETE; -+ s->s3->flags|=SSL3_FLAGS_POP_BUFFER; -+ s->s3->delay_buf_pop_ret=0; -+ } -+ else -+ { -+ s->s3->tmp.next_state=SSL3_ST_CUTTHROUGH_COMPLETE; -+ } -+ } - else -+ { -+#ifndef OPENSSL_NO_TLSEXT -+ /* Allow NewSessionTicket if ticket expected */ -+ if (s->tlsext_ticket_expected) -+ s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A; -+ else - #endif -- -- s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A; -+ s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A; -+ } - } - s->init_num=0; - break; -@@ -581,6 +604,24 @@ int ssl3_connect(SSL *s) - s->state=s->s3->tmp.next_state; - break; - -+ case SSL3_ST_CUTTHROUGH_COMPLETE: -+#ifndef OPENSSL_NO_TLSEXT -+ /* Allow NewSessionTicket if ticket expected */ -+ if (s->tlsext_ticket_expected) -+ s->state=SSL3_ST_CR_SESSION_TICKET_A; -+ else -+#endif -+ s->state=SSL3_ST_CR_FINISHED_A; -+ -+ /* SSL_write() will take care of flushing buffered data if -+ * DELAY_CLIENT_FINISHED is set. -+ */ -+ if (!(s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)) -+ ssl_free_wbio_buffer(s); -+ ret = 1; -+ goto end; -+ /* break; */ -+ - case SSL_ST_OK: - /* 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 ---- a/ssl/s3_lib.c -+++ b/ssl/s3_lib.c -@@ -4199,9 +4199,22 @@ int ssl3_write(SSL *s, const void *buf, int len) - - static int ssl3_read_internal(SSL *s, void *buf, int len, int peek) - { -- int ret; -+ int n,ret; - - clear_sys_error(); -+ if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio)) -+ { -+ /* Deal with an application that calls SSL_read() when handshake data -+ * is yet to be written. -+ */ -+ if (BIO_wpending(s->wbio) > 0) -+ { -+ s->rwstate=SSL_WRITING; -+ n=BIO_flush(s->wbio); -+ if (n <= 0) return(n); -+ s->rwstate=SSL_NOTHING; -+ } -+ } - if (s->s3->renegotiate) ssl3_renegotiate_check(s); - 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 ---- a/ssl/ssl.h -+++ b/ssl/ssl.h -@@ -649,6 +649,10 @@ 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" { - /* 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) --#define SSL_in_init(a) (SSL_state(a)&SSL_ST_INIT) -+#define SSL_in_init(a) ((SSL_state(a)&SSL_ST_INIT) && \ -+ !SSL_cutthrough_complete(a)) - #define SSL_in_before(a) (SSL_state(a)&SSL_ST_BEFORE) - #define SSL_in_connect_init(a) (SSL_state(a)&SSL_ST_CONNECT) - #define SSL_in_accept_init(a) (SSL_state(a)&SSL_ST_ACCEPT) -+int SSL_cutthrough_complete(const SSL *s); - - /* 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 ---- a/ssl/ssl3.h -+++ b/ssl/ssl3.h -@@ -547,6 +547,7 @@ typedef struct ssl3_state_st - /*client */ - /* extra state */ - #define SSL3_ST_CW_FLUSH (0x100|SSL_ST_CONNECT) -+#define SSL3_ST_CUTTHROUGH_COMPLETE (0x101|SSL_ST_CONNECT) - #ifndef OPENSSL_NO_SCTP - #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 ---- 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 - SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); - } - -+int SSL_cutthrough_complete(const SSL *s) -+ { -+ return (!s->server && /* cutthrough only applies to clients */ -+ !s->hit && /* full-handshake */ -+ 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 */ -+ 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)); -+ } -+ - /* 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/ssltest.c b/ssl/ssltest.c -index 316bbb0..91169bb 100644 ---- a/ssl/ssltest.c -+++ b/ssl/ssltest.c -@@ -369,6 +369,7 @@ static void sv_usage(void) - " (default is sect163r2).\n"); - #endif - fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n"); -+ fprintf(stderr," -cutthrough - enable 1-RTT full-handshake for strong ciphers\n"); - } - - static void print_details(SSL *c_ssl, const char *prefix) -@@ -549,6 +550,7 @@ int main(int argc, char *argv[]) - #ifdef OPENSSL_FIPS - int fips_mode=0; - #endif -+ int cutthrough = 0; - - verbose = 0; - debug = 0; -@@ -765,6 +767,10 @@ int main(int argc, char *argv[]) - { - test_cipherlist = 1; - } -+ else if (strcmp(*argv, "-cutthrough") == 0) -+ { -+ cutthrough = 1; -+ } - else - { - fprintf(stderr,"unknown option %s\n",*argv); -@@ -900,6 +906,12 @@ bad: - SSL_CTX_set_cipher_list(c_ctx,cipher); - SSL_CTX_set_cipher_list(s_ctx,cipher); - } -+ if (cutthrough) -+ { -+ int ssl_mode = SSL_CTX_get_mode(c_ctx); -+ ssl_mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH; -+ SSL_CTX_set_mode(c_ctx, ssl_mode); -+ } - - #ifndef OPENSSL_NO_DH - if (!no_dhe) -diff --git a/test/testssl b/test/testssl -index 4e8542b..b5f90ba 100644 ---- a/test/testssl -+++ b/test/testssl -@@ -70,6 +70,9 @@ $ssltest -client_auth $CA $extra || exit 1 - echo test sslv2/sslv3 with both client and server authentication - $ssltest -server_auth -client_auth $CA $extra || exit 1 - -+echo test sslv2/sslv3 with both client and server authentication and handshake cutthrough -+$ssltest -server_auth -client_auth -cutthrough $CA $extra || exit 1 -+ - echo test sslv2 via BIO pair - $ssltest -bio_pair -ssl2 $extra || exit 1 - --- -1.8.2.1 - diff --git a/main/openssl/patches/jsse.patch b/main/openssl/patches/jsse.patch deleted file mode 100644 index 795a2bbb..00000000 --- a/main/openssl/patches/jsse.patch +++ /dev/null @@ -1,422 +0,0 @@ ---- openssl-1.0.0b.orig/ssl/ssl.h 2010-11-30 00:03:46.000000000 +0000 -+++ openssl-1.0.0b/ssl/ssl.h 2010-11-30 00:03:47.000000000 +0000 -@@ -1133,6 +1133,9 @@ struct ssl_st - /* This can also be in the session once a session is established */ - SSL_SESSION *session; - -+ /* This can be disabled to prevent the use of uncached sessions */ -+ int session_creation_enabled; -+ - /* Default generate session ID callback. */ - GEN_SESSION_CB generate_session_id; - -@@ -1554,6 +1558,7 @@ const char * SSL_get_cipher_list(const - char * SSL_get_shared_ciphers(const SSL *s, char *buf, int len); - int SSL_get_read_ahead(const SSL * s); - int SSL_pending(const SSL *s); -+const char * SSL_authentication_method(const SSL *c); - #ifndef OPENSSL_NO_SOCK - int SSL_set_fd(SSL *s, int fd); - int SSL_set_rfd(SSL *s, int fd); -@@ -1565,6 +1570,7 @@ BIO * SSL_get_rbio(const SSL *s); - BIO * SSL_get_wbio(const SSL *s); - #endif - int SSL_set_cipher_list(SSL *s, const char *str); -+int SSL_set_cipher_lists(SSL *s, STACK_OF(SSL_CIPHER) *sk); - void SSL_set_read_ahead(SSL *s, int yes); - int SSL_get_verify_mode(const SSL *s); - int SSL_get_verify_depth(const SSL *s); -@@ -1580,6 +1586,8 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKE - int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len); - int SSL_use_certificate(SSL *ssl, X509 *x); - int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); -+int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain); -+STACK_OF(X509) * SSL_get_certificate_chain(SSL *ssl, X509 *x); - - #ifndef OPENSSL_NO_STDIO - int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); -@@ -1615,6 +1623,7 @@ void SSL_copy_session_id(SSL *to,const S - SSL_SESSION *SSL_SESSION_new(void); - const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, - unsigned int *len); -+const char * SSL_SESSION_get_version(const SSL_SESSION *s); - unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s); - #ifndef OPENSSL_NO_FP_API - int SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses); -@@ -1624,6 +1633,7 @@ int SSL_SESSION_print(BIO *fp,const SSL_ - void SSL_SESSION_free(SSL_SESSION *ses); - int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp); - int SSL_set_session(SSL *to, SSL_SESSION *session); -+void SSL_set_session_creation_enabled(SSL *, int); - int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c); - int SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c); - int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB); -@@ -2066,6 +2076,7 @@ void ERR_load_SSL_strings(void); - #define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 - #define SSL_F_SSL_USE_CERTIFICATE 198 - #define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 -+#define SSL_F_SSL_USE_CERTIFICATE_CHAIN 2000 - #define SSL_F_SSL_USE_CERTIFICATE_FILE 200 - #define SSL_F_SSL_USE_PRIVATEKEY 201 - #define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 -@@ -2272,6 +2283,7 @@ void ERR_load_SSL_strings(void); - #define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 - #define SSL_R_SERVERHELLO_TLSEXT 275 - #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 -+#define SSL_R_SESSION_MAY_NOT_BE_CREATED 2000 - #define SSL_R_SHORT_READ 219 - #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 - #define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 ---- openssl-1.0.0b.orig/ssl/d1_clnt.c 2010-01-26 19:46:29.000000000 +0000 -+++ openssl-1.0.0b/ssl/d1_clnt.c 2010-11-30 00:03:47.000000000 +0000 -@@ -613,6 +613,12 @@ int dtls1_client_hello(SSL *s) - #endif - (s->session->not_resumable)) - { -+ if (!s->session_creation_enabled) -+ { -+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); -+ SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); -+ goto err; -+ } - if (!ssl_get_new_session(s,0)) - goto err; - } ---- openssl-1.0.0b.orig/ssl/s23_clnt.c 2010-02-16 14:20:40.000000000 +0000 -+++ openssl-1.0.0b/ssl/s23_clnt.c 2010-11-30 00:03:47.000000000 +0000 -@@ -687,6 +687,13 @@ static int ssl23_get_server_hello(SSL *s - - /* Since, if we are sending a ssl23 client hello, we are not - * reusing a session-id */ -+ if (!s->session_creation_enabled) -+ { -+ if (!(s->client_version == SSL2_VERSION)) -+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); -+ SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); -+ goto err; -+ } - if (!ssl_get_new_session(s,0)) - goto err; - ---- openssl-1.0.0b.orig/ssl/s3_both.c 2010-11-30 00:03:46.000000000 +0000 -+++ openssl-1.0.0b/ssl/s3_both.c 2010-11-30 00:03:47.000000000 +0000 -@@ -347,8 +347,11 @@ unsigned long ssl3_output_cert_chain(SSL - unsigned long l=7; - BUF_MEM *buf; - int no_chain; -+ STACK_OF(X509) *cert_chain; - -- if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs) -+ cert_chain = SSL_get_certificate_chain(s, x); -+ -+ if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs || cert_chain) - no_chain = 1; - else - no_chain = 0; -@@ -400,6 +403,10 @@ unsigned long ssl3_output_cert_chain(SSL - return(0); - } - -+ for (i=0; i<sk_X509_num(cert_chain); i++) -+ if (ssl3_add_cert_to_buf(buf, &l, sk_X509_value(cert_chain,i))) -+ return(0); -+ - l-=7; - p=(unsigned char *)&(buf->data[4]); - l2n3(l,p); ---- openssl-1.0.0b.orig/ssl/s3_clnt.c 2010-11-30 00:03:46.000000000 +0000 -+++ openssl-1.0.0b/ssl/s3_clnt.c 2010-11-30 00:03:47.000000000 +0000 -@@ -686,6 +686,12 @@ int ssl3_client_hello(SSL *s) - #endif - (sess->not_resumable)) - { -+ if (!s->session_creation_enabled) -+ { -+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); -+ SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); -+ goto err; -+ } - if (!ssl_get_new_session(s,0)) - goto err; - } -@@ -894,6 +900,12 @@ int ssl3_get_server_hello(SSL *s) - s->hit=0; - if (s->session->session_id_length > 0) - { -+ if (!s->session_creation_enabled) -+ { -+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); -+ SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); -+ goto err; -+ } - if (!ssl_get_new_session(s,0)) - { - al=SSL_AD_INTERNAL_ERROR; ---- openssl-1.0.0b.orig/ssl/s3_srvr.c 2010-11-30 00:03:46.000000000 +0000 -+++ openssl-1.0.0b/ssl/s3_srvr.c 2010-11-30 00:03:47.000000000 +0000 -@@ -902,6 +902,12 @@ int ssl3_get_client_hello(SSL *s) - */ - if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) - { -+ if (!s->session_creation_enabled) -+ { -+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); -+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); -+ goto err; -+ } - if (!ssl_get_new_session(s,1)) - goto err; - } -@@ -916,6 +922,12 @@ int ssl3_get_client_hello(SSL *s) - goto err; - else /* i == 0 */ - { -+ if (!s->session_creation_enabled) -+ { -+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); -+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); -+ goto err; -+ } - if (!ssl_get_new_session(s,1)) - goto err; - } ---- openssl-1.0.0b.orig/ssl/ssl_ciph.c 2010-06-15 17:25:14.000000000 +0000 -+++ openssl-1.0.0b/ssl/ssl_ciph.c 2010-11-30 00:03:47.000000000 +0000 -@@ -1652,6 +1652,52 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER - return(ret); - } - -+/* return string version of key exchange algorithm */ -+const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher) -+ { -+ switch (cipher->algorithm_mkey) -+ { -+ case SSL_kRSA: -+ return SSL_TXT_RSA; -+ case SSL_kDHr: -+ return SSL_TXT_DH "_" SSL_TXT_RSA; -+ case SSL_kDHd: -+ return SSL_TXT_DH "_" SSL_TXT_DSS; -+ case SSL_kEDH: -+ switch (cipher->algorithm_auth) -+ { -+ case SSL_aDSS: -+ return "DHE_" SSL_TXT_DSS; -+ case SSL_aRSA: -+ return "DHE_" SSL_TXT_RSA; -+ case SSL_aNULL: -+ return SSL_TXT_DH "_anon"; -+ default: -+ return "UNKNOWN"; -+ } -+ case SSL_kKRB5: -+ return SSL_TXT_KRB5; -+ case SSL_kECDHr: -+ return SSL_TXT_ECDH "_" SSL_TXT_RSA; -+ case SSL_kECDHe: -+ return SSL_TXT_ECDH "_" SSL_TXT_ECDSA; -+ case SSL_kEECDH: -+ switch (cipher->algorithm_auth) -+ { -+ case SSL_aECDSA: -+ return "ECDHE_" SSL_TXT_ECDSA; -+ case SSL_aRSA: -+ return "ECDHE_" SSL_TXT_RSA; -+ case SSL_aNULL: -+ return SSL_TXT_ECDH "_anon"; -+ default: -+ return "UNKNOWN"; -+ } -+ default: -+ return "UNKNOWN"; -+ } -+ } -+ - SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) - { - SSL_COMP *ctmp; ---- openssl-1.0.0b.orig/ssl/ssl_err.c 2010-11-30 00:03:46.000000000 +0000 -+++ openssl-1.0.0b/ssl/ssl_err.c 2010-11-30 00:03:47.000000000 +0000 -@@ -465,6 +465,7 @@ static ERR_STRING_DATA SSL_str_reasons[] - {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"}, - {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) ,"serverhello tlsext"}, - {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"}, -+{ERR_REASON(SSL_R_SESSION_MAY_NOT_BE_CREATED),"session may not be created"}, - {ERR_REASON(SSL_R_SHORT_READ) ,"short read"}, - {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"}, - {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"}, ---- openssl-1.0.0b.orig/ssl/ssl_lib.c 2010-11-30 00:03:46.000000000 +0000 -+++ openssl-1.0.0b/ssl/ssl_lib.c 2010-11-30 00:03:47.000000000 +0000 -@@ -326,6 +326,7 @@ SSL *SSL_new(SSL_CTX *ctx) - OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx); - memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx)); - s->verify_callback=ctx->default_verify_callback; -+ s->session_creation_enabled=1; - s->generate_session_id=ctx->generate_session_id; - - s->param = X509_VERIFY_PARAM_new(); -@@ -1311,6 +1312,32 @@ int SSL_set_cipher_list(SSL *s,const cha - return 1; - } - -+/** specify the ciphers to be used by the SSL */ -+int SSL_set_cipher_lists(SSL *s,STACK_OF(SSL_CIPHER) *sk) -+ { -+ STACK_OF(SSL_CIPHER) *tmp_cipher_list; -+ -+ if (sk == NULL) -+ return 0; -+ -+ /* Based on end of ssl_create_cipher_list */ -+ tmp_cipher_list = sk_SSL_CIPHER_dup(sk); -+ if (tmp_cipher_list == NULL) -+ { -+ return 0; -+ } -+ if (s->cipher_list != NULL) -+ sk_SSL_CIPHER_free(s->cipher_list); -+ s->cipher_list = sk; -+ if (s->cipher_list_by_id != NULL) -+ sk_SSL_CIPHER_free(s->cipher_list_by_id); -+ s->cipher_list_by_id = tmp_cipher_list; -+ (void)sk_SSL_CIPHER_set_cmp_func(s->cipher_list_by_id,ssl_cipher_ptr_id_cmp); -+ -+ sk_SSL_CIPHER_sort(s->cipher_list_by_id); -+ return 1; -+ } -+ - /* works well for SSLv2, not so good for SSLv3 */ - char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len) - { -@@ -2551,22 +2578,45 @@ SSL_METHOD *ssl_bad_method(int ver) - return(NULL); - } - --const char *SSL_get_version(const SSL *s) -+static const char *ssl_get_version(int version) - { -- if (s->version == TLS1_2_VERSION) -+ if (version == TLS1_2_VERSION) - return("TLSv1.2"); -- else if (s->version == TLS1_1_VERSION) -+ else if (version == TLS1_1_VERSION) - return("TLSv1.1"); -- else if (s->version == TLS1_VERSION) -+ else if (version == TLS1_VERSION) - return("TLSv1"); -- else if (s->version == SSL3_VERSION) -+ else if (version == SSL3_VERSION) - return("SSLv3"); -- else if (s->version == SSL2_VERSION) -+ else if (version == SSL2_VERSION) - return("SSLv2"); - else - return("unknown"); - } - -+const char *SSL_get_version(const SSL *s) -+ { -+ return ssl_get_version(s->version); -+ } -+ -+const char *SSL_SESSION_get_version(const SSL_SESSION *s) -+ { -+ return ssl_get_version(s->ssl_version); -+ } -+ -+const char* SSL_authentication_method(const SSL* ssl) -+ { -+ if (ssl->cert != NULL && ssl->cert->rsa_tmp != NULL) -+ return SSL_TXT_RSA "_" SSL_TXT_EXPORT; -+ switch (ssl->version) -+ { -+ case SSL2_VERSION: -+ return SSL_TXT_RSA; -+ default: -+ return SSL_CIPHER_authentication_method(ssl->s3->tmp.new_cipher); -+ } -+ } -+ - SSL *SSL_dup(SSL *s) - { - STACK_OF(X509_NAME) *sk; ---- openssl-1.0.0b.orig/ssl/ssl_locl.h 2010-11-30 00:03:46.000000000 +0000 -+++ openssl-1.0.0b/ssl/ssl_locl.h 2010-11-30 00:03:47.000000000 +0000 -@@ -456,6 +456,7 @@ - typedef struct cert_pkey_st - { - X509 *x509; -+ STACK_OF(X509) *cert_chain; - EVP_PKEY *privatekey; - } CERT_PKEY; - ---- openssl-1.0.0b.orig/ssl/ssl_rsa.c 2009-09-12 23:09:26.000000000 +0000 -+++ openssl-1.0.0b/ssl/ssl_rsa.c 2010-11-30 00:03:47.000000000 +0000 -@@ -697,6 +697,44 @@ int SSL_CTX_use_PrivateKey_ASN1(int type - } - - -+int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain) -+ { -+ if (ssl == NULL) -+ { -+ SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,ERR_R_PASSED_NULL_PARAMETER); -+ return(0); -+ } -+ if (ssl->cert == NULL) -+ { -+ SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED); -+ return(0); -+ } -+ if (ssl->cert->key == NULL) -+ { -+ SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED); -+ return(0); -+ } -+ if (ssl->cert->key->cert_chain != NULL) -+ sk_X509_pop_free(ssl->cert->key->cert_chain, X509_free); -+ ssl->cert->key->cert_chain = cert_chain; -+ return(1); -+ } -+ -+STACK_OF(X509) *SSL_get_certificate_chain(SSL *ssl, X509 *x) -+ { -+ int i; -+ if (x == NULL) -+ return NULL; -+ if (ssl == NULL) -+ return NULL; -+ if (ssl->cert == NULL) -+ return NULL; -+ for (i = 0; i < SSL_PKEY_NUM; i++) -+ if (ssl->cert->pkeys[i].x509 == x) -+ return ssl->cert->pkeys[i].cert_chain; -+ return NULL; -+ } -+ - #ifndef OPENSSL_NO_STDIO - /* Read a file that contains our certificate in "PEM" format, - * possibly followed by a sequence of CA certificates that should be ---- openssl-1.0.0b.orig/ssl/ssl_sess.c 2010-02-01 16:49:42.000000000 +0000 -+++ openssl-1.0.0b/ssl/ssl_sess.c 2010-11-30 00:03:47.000000000 +0000 -@@ -261,6 +261,11 @@ static int def_generate_session_id(const - return 0; - } - -+void SSL_set_session_creation_enabled (SSL *s, int creation_enabled) -+ { -+ s->session_creation_enabled = creation_enabled; -+ } -+ - int ssl_get_new_session(SSL *s, int session) - { - /* This gets used by clients and servers. */ -@@ -269,6 +274,8 @@ int ssl_get_new_session(SSL *s, int sess - SSL_SESSION *ss=NULL; - GEN_SESSION_CB cb = def_generate_session_id; - -+ /* caller should check this if they can do better error handling */ -+ if (!s->session_creation_enabled) return(0); - if ((ss=SSL_SESSION_new()) == NULL) return(0); - - /* If the context has a default timeout, use it */ diff --git a/main/openssl/patches/progs.patch b/main/openssl/patches/progs.patch deleted file mode 100644 index f0879ae7..00000000 --- a/main/openssl/patches/progs.patch +++ /dev/null @@ -1,54 +0,0 @@ ---- openssl-1.0.0.orig/apps/openssl.c 2009-10-04 09:43:21.000000000 -0700 -+++ openssl-1.0.0/apps/openssl.c 2010-05-18 14:05:14.000000000 -0700 -@@ -275,8 +275,10 @@ int main(int Argc, char *Argv[]) - if (ERR_GET_REASON(ERR_peek_last_error()) - == CONF_R_NO_SUCH_FILE) - { -+#if 0 /* ANDROID */ - BIO_printf(bio_err, - "WARNING: can't open config file: %s\n",p); -+#endif - ERR_clear_error(); - NCONF_free(config); - config = NULL; ---- openssl-1.0.0.orig/apps/progs.h 2009-06-30 08:08:38.000000000 -0700 -+++ openssl-1.0.0/apps/progs.h 2010-05-18 14:05:38.000000000 -0700 -@@ -146,7 +152,9 @@ FUNCTION functions[] = { - {FUNC_TYPE_GENERAL,"ocsp",ocsp_main}, - #endif - {FUNC_TYPE_GENERAL,"prime",prime_main}, -+#if 0 /* ANDROID */ - {FUNC_TYPE_GENERAL,"ts",ts_main}, -+#endif - #ifndef OPENSSL_NO_SRP - {FUNC_TYPE_GENERAL,"srp",srp_main}, - #endif ---- openssl-1.0.0.orig/apps/speed.c 2010-03-03 11:56:17.000000000 -0800 -+++ openssl-1.0.0/apps/speed.c 2010-05-18 14:05:57.000000000 -0700 -@@ -1718,6 +1718,7 @@ int MAIN(int argc, char **argv) - } - } - -+#if 0 /* ANDROID */ - if (doit[D_IGE_128_AES]) - { - for (j=0; j<SIZE_NUM; j++) -@@ -1763,6 +1764,7 @@ int MAIN(int argc, char **argv) - - - #endif -+#endif - #ifndef OPENSSL_NO_CAMELLIA - if (doit[D_CBC_128_CML]) - { ---- openssl-1.0.0.orig/crypto/ui/ui_openssl.c 2009-10-04 09:43:21.000000000 -0700 -+++ openssl-1.0.0/crypto/ui/ui_openssl.c 2010-05-18 13:36:26.000000000 -0700 -@@ -184,7 +184,7 @@ - # undef SGTTY - #endif - --#if defined(linux) && !defined(TERMIO) -+#if defined(linux) && !defined(TERMIO) && !defined(__ANDROID__) - # undef TERMIOS - # define TERMIO - # undef SGTTY diff --git a/main/openssl/ssl/bio_ssl.c b/main/openssl/ssl/bio_ssl.c index e9552cae..06a13de4 100644 --- a/main/openssl/ssl/bio_ssl.c +++ b/main/openssl/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/main/openssl/ssl/d1_both.c b/main/openssl/ssl/d1_both.c index 2e8cf681..04aa2310 100644 --- a/main/openssl/ssl/d1_both.c +++ b/main/openssl/ssl/d1_both.c @@ -627,7 +627,16 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) 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 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok) 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 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) 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 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) 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/main/openssl/ssl/d1_lib.c b/main/openssl/ssl/d1_lib.c index 106939f2..6bde16fa 100644 --- a/main/openssl/ssl/d1_lib.c +++ b/main/openssl/ssl/d1_lib.c @@ -176,9 +176,12 @@ static void dtls1_clear_queues(SSL *s) 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/main/openssl/ssl/d1_pkt.c b/main/openssl/ssl/d1_pkt.c index 5b84e97c..363fc8c8 100644 --- a/main/openssl/ssl/d1_pkt.c +++ b/main/openssl/ssl/d1_pkt.c @@ -241,14 +241,6 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) } #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 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) 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/main/openssl/ssl/d1_srvr.c b/main/openssl/ssl/d1_srvr.c index 09f47627..c181db6d 100644 --- a/main/openssl/ssl/d1_srvr.c +++ b/main/openssl/ssl/d1_srvr.c @@ -1356,6 +1356,7 @@ int dtls1_send_server_key_exchange(SSL *s) (unsigned char *)encodedPoint, encodedlen); OPENSSL_free(encodedPoint); + encodedPoint = NULL; p += encodedlen; } #endif diff --git a/main/openssl/ssl/s3_both.c b/main/openssl/ssl/s3_both.c index d9e18a31..607990d0 100644 --- a/main/openssl/ssl/s3_both.c +++ b/main/openssl/ssl/s3_both.c @@ -561,7 +561,7 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) #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/main/openssl/ssl/s3_clnt.c b/main/openssl/ssl/s3_clnt.c index 5e15b75c..486f538b 100644 --- a/main/openssl/ssl/s3_clnt.c +++ b/main/openssl/ssl/s3_clnt.c @@ -215,24 +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; @@ -558,7 +546,20 @@ int ssl3_connect(SSL *s) } 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 @@ 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); @@ -2302,7 +2304,7 @@ int ssl3_get_server_done(SSL *s) 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 @@ int ssl3_send_client_key_exchange(SSL *s) 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 @@ int ssl3_send_client_key_exchange(SSL *s) } } #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 @@ int ssl3_send_channel_id(SSL *s) 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 @@ int ssl3_send_channel_id(SSL *s) 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 @@ int ssl3_send_channel_id(SSL *s) } 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/main/openssl/ssl/s3_enc.c b/main/openssl/ssl/s3_enc.c index 90fbb180..53b94b7c 100644 --- a/main/openssl/ssl/s3_enc.c +++ b/main/openssl/ssl/s3_enc.c @@ -728,7 +728,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/main/openssl/ssl/s3_lib.c b/main/openssl/ssl/s3_lib.c index f84da7f5..4eb54284 100644 --- a/main/openssl/ssl/s3_lib.c +++ b/main/openssl/ssl/s3_lib.c @@ -3412,8 +3412,6 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) break; #endif case SSL_CTRL_CHANNEL_ID: - if (!s->server) - break; s->tlsext_channel_id_enabled = 1; ret = 1; break; @@ -3429,7 +3427,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) } 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 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) } 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/main/openssl/ssl/s3_pkt.c b/main/openssl/ssl/s3_pkt.c index 75997ac2..60c4f1a4 100644 --- a/main/openssl/ssl/s3_pkt.c +++ b/main/openssl/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_do_compress(SSL *ssl) 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 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) } } + /* 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 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, 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 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* 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 @@ start: { 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 @@ start: 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 @@ int ssl3_do_change_cipher_spec(SSL *s) 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/main/openssl/ssl/s3_srvr.c b/main/openssl/ssl/s3_srvr.c index 1976efa7..f83c9366 100644 --- a/main/openssl/ssl/s3_srvr.c +++ b/main/openssl/ssl/s3_srvr.c @@ -675,8 +675,8 @@ int ssl3_accept(SSL *s) 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 @@ 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) @@ -729,6 +728,7 @@ int ssl3_accept(SSL *s) 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 @@ 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; @@ -1468,6 +1477,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; @@ -2143,6 +2168,11 @@ int ssl3_send_certificate_request(SSL *s) 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 @@ int ssl3_get_client_key_exchange(SSL *s) 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 @@ int ssl3_get_client_key_exchange(SSL *s) 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 + 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; @@ -3675,6 +3695,7 @@ int ssl3_get_channel_id(SSL *s) 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 @@ int ssl3_get_channel_id(SSL *s) 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/main/openssl/ssl/ssl.h b/main/openssl/ssl/ssl.h index 54b0eb6c..06bb90f8 100644 --- a/main/openssl/ssl/ssl.h +++ b/main/openssl/ssl/ssl.h @@ -544,6 +544,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 @@ -553,7 +560,7 @@ struct ssl_session_st /* 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 @@ struct ssl_session_st /* 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 @@ 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. */ #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 @@ 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); @@ -1028,6 +1042,10 @@ struct ssl_ctx_st /* 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_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 @@ -1162,12 +1182,14 @@ 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 */ #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 @@ 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 #define SSL_CTRL_SET_TMP_RSA 2 @@ -1739,10 +1762,11 @@ 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_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 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits); 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 @@ 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 } diff --git a/main/openssl/ssl/ssl3.h b/main/openssl/ssl/ssl3.h index f205f73d..83d59bff 100644 --- a/main/openssl/ssl/ssl3.h +++ b/main/openssl/ssl/ssl3.h @@ -388,9 +388,6 @@ 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 @@ -558,6 +555,11 @@ typedef struct ssl3_state_st * 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 @@ 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_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/main/openssl/ssl/ssl_asn1.c b/main/openssl/ssl/ssl_asn1.c index 38540be1..f83e18f8 100644 --- a/main/openssl/ssl/ssl_asn1.c +++ b/main/openssl/ssl/ssl_asn1.c @@ -117,12 +117,13 @@ typedef struct ssl_session_asn1_st #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 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) 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 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) 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 @@ int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) 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 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, if (os.length != 3) { c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH; + c.line=__LINE__; goto err; } id=0x02000000L| @@ -420,6 +433,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, if (os.length != 2) { c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH; + c.line=__LINE__; goto err; } id=0x03000000L| @@ -429,6 +443,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, else { c.error=SSL_R_UNKNOWN_SSL_VERSION; + c.line=__LINE__; goto err; } @@ -521,6 +536,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, if (os.length > SSL_MAX_SID_CTX_LENGTH) { c.error=SSL_R_BAD_LENGTH; + c.line=__LINE__; goto err; } else @@ -638,5 +654,16 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, 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/main/openssl/ssl/ssl_err.c b/main/openssl/ssl/ssl_err.c index bddd7949..ac0aad9b 100644 --- a/main/openssl/ssl/ssl_err.c +++ b/main/openssl/ssl/ssl_err.c @@ -553,7 +553,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {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 @@ 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/main/openssl/ssl/ssl_lib.c b/main/openssl/ssl/ssl_lib.c index 8d2c3a76..3de68a78 100644 --- a/main/openssl/ssl/ssl_lib.c +++ b/main/openssl/ssl/ssl_lib.c @@ -1403,6 +1403,10 @@ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len) 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 @@ 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) { @@ -3419,12 +3427,41 @@ int SSL_cutthrough_complete(const SSL *s) 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/main/openssl/ssl/ssl_locl.h b/main/openssl/ssl/ssl_locl.h index f79ab009..6b7731a4 100644 --- a/main/openssl/ssl/ssl_locl.h +++ b/main/openssl/ssl/ssl_locl.h @@ -1070,6 +1070,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); @@ -1126,8 +1127,10 @@ 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); 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/main/openssl/ssl/ssl_sess.c b/main/openssl/ssl/ssl_sess.c index ec088404..7d170852 100644 --- a/main/openssl/ssl/ssl_sess.c +++ b/main/openssl/ssl/ssl_sess.c @@ -1144,6 +1144,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/main/openssl/ssl/t1_enc.c b/main/openssl/ssl/t1_enc.c index 2ed2e076..22dd3cab 100644 --- a/main/openssl/ssl/t1_enc.c +++ b/main/openssl/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; @@ -1048,14 +1073,10 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send) 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 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, 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/main/openssl/ssl/t1_lib.c b/main/openssl/ssl/t1_lib.c index 369e09f4..122a25f5 100644 --- a/main/openssl/ssl/t1_lib.c +++ b/main/openssl/ssl/t1_lib.c @@ -617,6 +617,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha #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 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha * 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 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha 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 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha /* 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 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha { 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 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in 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 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in 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 @@ tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s) 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 @@ tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s) return 1; } #endif + +/* tls1_record_handshake_hashes_for_channel_id records the current handshake + * hashes in |s->session| so that Channel ID resumptions can sign that data. */ +int tls1_record_handshake_hashes_for_channel_id(SSL *s) + { + int digest_len; + /* This function should never be called for a resumed session because + * the handshake hashes that we wish to record are for the original, + * full handshake. */ + if (s->hit) + return -1; + /* It only makes sense to call this function if Channel IDs have been + * negotiated. */ + if (!s->s3->tlsext_channel_id_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/main/openssl/ssl/tls1.h b/main/openssl/ssl/tls1.h index ec8948d5..66520893 100644 --- a/main/openssl/ssl/tls1.h +++ b/main/openssl/ssl/tls1.h @@ -259,6 +259,7 @@ extern "C" { /* 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 |