BUF_MEM *buf;
unsigned long alg_k,Time=(unsigned long)time(NULL);
void (*cb)(const SSL *ssl,int type,int val)=NULL;
- long num1;
int ret= -1;
int new_state,state,skip=0;
s->state=SSL3_ST_SR_CLNT_HELLO_A;
s->ctx->stats.sess_accept++;
}
+ else if (!s->s3->send_connection_binding &&
+ !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+ {
+ /* Server attempting to renegotiate with
+ * client that doesn't support secure
+ * renegotiation.
+ */
+ SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
+ ret = -1;
+ goto end;
+ }
else
{
/* s->state == SSL_ST_RENEGOTIATE,
break;
case SSL3_ST_SW_FLUSH:
- /* number of bytes to be flushed */
- num1=BIO_ctrl(s->wbio,BIO_CTRL_WPENDING,0,NULL);
- if (num1 > 0)
+
+ /* This code originally checked to see if
+ * any data was pending using BIO_CTRL_INFO
+ * and then flushed. This caused problems
+ * as documented in PR#1939. The proposed
+ * fix doesn't completely resolve this issue
+ * as buggy implementations of BIO_CTRL_PENDING
+ * still exist. So instead we just flush
+ * unconditionally.
+ */
+
+ s->rwstate=SSL_WRITING;
+ if (BIO_flush(s->wbio) <= 0)
{
- s->rwstate=SSL_WRITING;
- num1=BIO_flush(s->wbio);
- if (num1 <= 0) { ret= -1; goto end; }
- s->rwstate=SSL_NOTHING;
+ ret= -1;
+ goto end;
}
+ s->rwstate=SSL_NOTHING;
s->state=s->s3->tmp.next_state;
break;
#ifndef OPENSSL_NO_TLSEXT
/* TLS extensions*/
- if (s->version > SSL3_VERSION)
+ if (s->version >= SSL3_VERSION)
{
if (!ssl_parse_clienthello_tlsext(s,&p,d,n, &al))
{
* algorithms from the client, starting at q. */
s->s3->tmp.new_compression=NULL;
#ifndef OPENSSL_NO_COMP
- if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods)
+ /* This only happens if we have a cache hit */
+ if (s->session->compress_meth != 0)
+ {
+ int m, comp_id = s->session->compress_meth;
+ /* Perform sanity checks on resumed compression algorithm */
+ /* Can't disable compression */
+ if (s->options & SSL_OP_NO_COMPRESSION)
+ {
+ al=SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION);
+ goto f_err;
+ }
+ /* Look for resumed compression method */
+ for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++)
+ {
+ comp=sk_SSL_COMP_value(s->ctx->comp_methods,m);
+ if (comp_id == comp->id)
+ {
+ s->s3->tmp.new_compression=comp;
+ break;
+ }
+ }
+ if (s->s3->tmp.new_compression == NULL)
+ {
+ al=SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INVALID_COMPRESSION_ALGORITHM);
+ goto f_err;
+ }
+ /* Look for resumed method in compression list */
+ for (m = 0; m < i; m++)
+ {
+ if (q[m] == comp_id)
+ break;
+ }
+ if (m >= i)
+ {
+ al=SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING);
+ goto f_err;
+ }
+ }
+ else if (s->hit)
+ comp = NULL;
+ else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods)
{ /* See if we have a match */
int m,nn,o,v,done=0;
else
comp=NULL;
}
+#else
+ /* If compression is disabled we'd better not try to resume a session
+ * using compression.
+ */
+ if (s->session->compress_meth != 0)
+ {
+ al=SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION);
+ goto f_err;
+ }
#endif
/* Given s->session->ciphers and SSL_get_ciphers, we must
unsigned int hlen;
EVP_CIPHER_CTX ctx;
HMAC_CTX hctx;
+ SSL_CTX *tctx = s->initial_ctx;
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char key_name[16];
* it does all the work otherwise use generated values
* from parent ctx.
*/
- if (s->ctx->tlsext_ticket_key_cb)
+ if (tctx->tlsext_ticket_key_cb)
{
- if (s->ctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
+ if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
&hctx, 1) < 0)
{
OPENSSL_free(senc);
{
RAND_pseudo_bytes(iv, 16);
EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
- s->ctx->tlsext_tick_aes_key, iv);
- HMAC_Init_ex(&hctx, s->ctx->tlsext_tick_hmac_key, 16,
+ tctx->tlsext_tick_aes_key, iv);
+ HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
tlsext_tick_md(), NULL);
- memcpy(key_name, s->ctx->tlsext_tick_key_name, 16);
+ memcpy(key_name, tctx->tlsext_tick_key_name, 16);
}
l2n(s->session->tlsext_tick_lifetime_hint, p);
/* Skip ticket length for now */