mirror of https://github.com/openssl/openssl.git
Add support for magic cipher suite value (MCSV). Make secure renegotiation
work in SSLv3: initial handshake has no extensions but includes MCSV, if server indicates RI support then renegotiation handshakes include RI. NB: current MCSV value is bogus for testing only, will be updated when we have an official value. Change mismatch alerts to handshake_failure as required by spec. Also have some debugging fprintfs so we can clearly see what is going on if OPENSSL_RI_DEBUG is set.
This commit is contained in:
parent
1ff44a99a4
commit
7a014dceb6
5
CHANGES
5
CHANGES
|
|
@ -8,15 +8,14 @@
|
|||
the updated NID creation version. This should correctly handle UTF8.
|
||||
[Steve Henson]
|
||||
|
||||
*) Implement
|
||||
https://svn.resiprocate.org/rep/ietf-drafts/ekr/draft-rescorla-tls-renegotiate.txt. Re-enable
|
||||
*) Implement draft-ietf-tls-renegotiation. Re-enable
|
||||
renegotiation but require the extension as needed. Unfortunately,
|
||||
SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION turns out to be a
|
||||
bad idea. It has been replaced by
|
||||
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with
|
||||
SSL_CTX_set_options(). This is really not recommended unless you
|
||||
know what you are doing.
|
||||
[Eric Rescorla <ekr@networkresonance.com> and Ben Laurie]
|
||||
[Eric Rescorla <ekr@networkresonance.com>, Ben Laurie, Steve Henson]
|
||||
|
||||
*) Fixes to stateless session resumption handling. Use initial_ctx when
|
||||
issuing and attempting to decrypt tickets in case it has changed during
|
||||
|
|
|
|||
|
|
@ -283,15 +283,43 @@ int dtls1_connect(SSL *s)
|
|||
|
||||
case SSL3_ST_CR_CERT_A:
|
||||
case SSL3_ST_CR_CERT_B:
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
ret=ssl3_check_finished(s);
|
||||
if (ret <= 0) goto end;
|
||||
if (ret == 2)
|
||||
{
|
||||
s->hit = 1;
|
||||
if (s->tlsext_ticket_expected)
|
||||
s->state=SSL3_ST_CR_SESSION_TICKET_A;
|
||||
else
|
||||
s->state=SSL3_ST_CR_FINISHED_A;
|
||||
s->init_num=0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* Check if it is anon DH */
|
||||
if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
|
||||
{
|
||||
ret=ssl3_get_server_certificate(s);
|
||||
if (ret <= 0) goto end;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s->tlsext_status_expected)
|
||||
s->state=SSL3_ST_CR_CERT_STATUS_A;
|
||||
else
|
||||
s->state=SSL3_ST_CR_KEY_EXCH_A;
|
||||
}
|
||||
else
|
||||
{
|
||||
skip = 1;
|
||||
s->state=SSL3_ST_CR_KEY_EXCH_A;
|
||||
}
|
||||
#else
|
||||
}
|
||||
else
|
||||
skip=1;
|
||||
|
||||
s->state=SSL3_ST_CR_KEY_EXCH_A;
|
||||
#endif
|
||||
s->init_num=0;
|
||||
break;
|
||||
|
||||
|
|
@ -434,12 +462,37 @@ int dtls1_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;
|
||||
else
|
||||
#endif
|
||||
|
||||
s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
|
||||
}
|
||||
s->init_num=0;
|
||||
|
||||
break;
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
case SSL3_ST_CR_SESSION_TICKET_A:
|
||||
case SSL3_ST_CR_SESSION_TICKET_B:
|
||||
ret=ssl3_get_new_session_ticket(s);
|
||||
if (ret <= 0) goto end;
|
||||
s->state=SSL3_ST_CR_FINISHED_A;
|
||||
s->init_num=0;
|
||||
break;
|
||||
|
||||
case SSL3_ST_CR_CERT_STATUS_A:
|
||||
case SSL3_ST_CR_CERT_STATUS_B:
|
||||
ret=ssl3_get_cert_status(s);
|
||||
if (ret <= 0) goto end;
|
||||
s->state=SSL3_ST_CR_KEY_EXCH_A;
|
||||
s->init_num=0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SSL3_ST_CR_FINISHED_A:
|
||||
case SSL3_ST_CR_FINISHED_B:
|
||||
s->d1->change_cipher_spec_ok = 1;
|
||||
|
|
@ -552,8 +605,14 @@ int dtls1_client_hello(SSL *s)
|
|||
buf=(unsigned char *)s->init_buf->data;
|
||||
if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
|
||||
{
|
||||
SSL_SESSION *sess = s->session;
|
||||
if ((s->session == NULL) ||
|
||||
(s->session->ssl_version != s->version) ||
|
||||
#ifdef OPENSSL_NO_TLSEXT
|
||||
!sess->session_id_length ||
|
||||
#else
|
||||
(!sess->session_id_length && !sess->tlsext_tick) ||
|
||||
#endif
|
||||
(s->session->not_resumable))
|
||||
{
|
||||
if (!ssl_get_new_session(s,0))
|
||||
|
|
@ -634,7 +693,7 @@ int dtls1_client_hello(SSL *s)
|
|||
*(p++)=0; /* Add the NULL method */
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if ((p = ssl_add_clienthello_dtlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
|
||||
if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
|
|
|
|||
191
ssl/d1_lib.c
191
ssl/d1_lib.c
|
|
@ -404,194 +404,3 @@ int dtls1_listen(SSL *s, struct sockaddr *client)
|
|||
(void) BIO_dgram_get_peer(SSL_get_rbio(s), client);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
unsigned char *ssl_add_clienthello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit)
|
||||
{
|
||||
int extdatalen = 0;
|
||||
unsigned char *ret = p;
|
||||
int el;
|
||||
|
||||
ret+=2;
|
||||
|
||||
if (ret>=limit) return NULL; /* this really never occurs, but ... */
|
||||
|
||||
/* Renegotiate extension */
|
||||
if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((limit - p - 4 - el) < 0) return NULL;
|
||||
|
||||
s2n(TLSEXT_TYPE_renegotiate,ret);
|
||||
s2n(el,ret);
|
||||
|
||||
if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret += el;
|
||||
|
||||
if ((extdatalen = ret-p-2)== 0)
|
||||
return p;
|
||||
|
||||
s2n(extdatalen,p);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ssl_parse_clienthello_dtlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
|
||||
{
|
||||
unsigned short type;
|
||||
unsigned short size;
|
||||
unsigned short len;
|
||||
unsigned char *data = *p;
|
||||
int renegotiate_seen = 0;
|
||||
|
||||
if (data >= (d+n-2))
|
||||
{
|
||||
if (s->new_session
|
||||
&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
|
||||
{
|
||||
/* We should always see one extension: the renegotiate extension */
|
||||
SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
|
||||
*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
n2s(data,len);
|
||||
|
||||
if (data > (d+n-len))
|
||||
return 1;
|
||||
|
||||
while (data <= (d+n-4))
|
||||
{
|
||||
n2s(data,type);
|
||||
n2s(data,size);
|
||||
|
||||
if (data+size > (d+n))
|
||||
return 1;
|
||||
|
||||
if (type == TLSEXT_TYPE_renegotiate)
|
||||
{
|
||||
if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
|
||||
return 0;
|
||||
renegotiate_seen = 1;
|
||||
}
|
||||
|
||||
data+=size;
|
||||
}
|
||||
|
||||
if (s->new_session && !renegotiate_seen
|
||||
&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
|
||||
{
|
||||
*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
|
||||
SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*p = data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char *ssl_add_serverhello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit)
|
||||
{
|
||||
int extdatalen = 0;
|
||||
unsigned char *ret = p;
|
||||
|
||||
ret+=2;
|
||||
|
||||
if (ret>=limit) return NULL; /* this really never occurs, but ... */
|
||||
|
||||
if(s->s3->send_connection_binding)
|
||||
{
|
||||
int el;
|
||||
|
||||
if(!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((limit - p - 4 - el) < 0) return NULL;
|
||||
|
||||
s2n(TLSEXT_TYPE_renegotiate,ret);
|
||||
s2n(el,ret);
|
||||
|
||||
if(!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret += el;
|
||||
}
|
||||
|
||||
if ((extdatalen = ret-p-2)== 0)
|
||||
return p;
|
||||
|
||||
s2n(extdatalen,p);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ssl_parse_serverhello_dtlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
|
||||
{
|
||||
unsigned short type;
|
||||
unsigned short size;
|
||||
unsigned short len;
|
||||
unsigned char *data = *p;
|
||||
int renegotiate_seen = 0;
|
||||
|
||||
if (data >= (d+n-2))
|
||||
{
|
||||
if (s->new_session
|
||||
&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
|
||||
{
|
||||
/* We should always see one extension: the renegotiate extension */
|
||||
SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
|
||||
*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
n2s(data,len);
|
||||
|
||||
if (data > (d+n-len))
|
||||
return 1;
|
||||
|
||||
while (data <= (d+n-4))
|
||||
{
|
||||
n2s(data,type);
|
||||
n2s(data,size);
|
||||
|
||||
if (data+size > (d+n))
|
||||
return 1;
|
||||
|
||||
if (type == TLSEXT_TYPE_renegotiate)
|
||||
{
|
||||
if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
|
||||
return 0;
|
||||
renegotiate_seen = 1;
|
||||
}
|
||||
|
||||
data+=size;
|
||||
}
|
||||
|
||||
if (s->new_session && !renegotiate_seen
|
||||
&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
|
||||
{
|
||||
*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
|
||||
SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*p = data;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
162
ssl/d1_srvr.c
162
ssl/d1_srvr.c
|
|
@ -303,8 +303,18 @@ int dtls1_accept(SSL *s)
|
|||
ret=dtls1_send_server_hello(s);
|
||||
if (ret <= 0) goto end;
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s->hit)
|
||||
s->state=SSL3_ST_SW_CHANGE_A;
|
||||
{
|
||||
if (s->tlsext_ticket_expected)
|
||||
s->state=SSL3_ST_SW_SESSION_TICKET_A;
|
||||
else
|
||||
s->state=SSL3_ST_SW_CHANGE_A;
|
||||
}
|
||||
#else
|
||||
if (s->hit)
|
||||
s->state=SSL3_ST_SW_CHANGE_A;
|
||||
#endif
|
||||
else
|
||||
s->state=SSL3_ST_SW_CERT_A;
|
||||
s->init_num=0;
|
||||
|
|
@ -318,10 +328,24 @@ int dtls1_accept(SSL *s)
|
|||
dtls1_start_timer(s);
|
||||
ret=dtls1_send_server_certificate(s);
|
||||
if (ret <= 0) goto end;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s->tlsext_status_expected)
|
||||
s->state=SSL3_ST_SW_CERT_STATUS_A;
|
||||
else
|
||||
s->state=SSL3_ST_SW_KEY_EXCH_A;
|
||||
}
|
||||
else
|
||||
{
|
||||
skip = 1;
|
||||
s->state=SSL3_ST_SW_KEY_EXCH_A;
|
||||
}
|
||||
#else
|
||||
}
|
||||
else
|
||||
skip=1;
|
||||
|
||||
s->state=SSL3_ST_SW_KEY_EXCH_A;
|
||||
#endif
|
||||
s->init_num=0;
|
||||
break;
|
||||
|
||||
|
|
@ -492,11 +516,34 @@ int dtls1_accept(SSL *s)
|
|||
dtls1_stop_timer(s);
|
||||
if (s->hit)
|
||||
s->state=SSL_ST_OK;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
else if (s->tlsext_ticket_expected)
|
||||
s->state=SSL3_ST_SW_SESSION_TICKET_A;
|
||||
#endif
|
||||
else
|
||||
s->state=SSL3_ST_SW_CHANGE_A;
|
||||
s->init_num=0;
|
||||
break;
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
case SSL3_ST_SW_SESSION_TICKET_A:
|
||||
case SSL3_ST_SW_SESSION_TICKET_B:
|
||||
ret=dtls1_send_newsession_ticket(s);
|
||||
if (ret <= 0) goto end;
|
||||
s->state=SSL3_ST_SW_CHANGE_A;
|
||||
s->init_num=0;
|
||||
break;
|
||||
|
||||
case SSL3_ST_SW_CERT_STATUS_A:
|
||||
case SSL3_ST_SW_CERT_STATUS_B:
|
||||
ret=ssl3_send_cert_status(s);
|
||||
if (ret <= 0) goto end;
|
||||
s->state=SSL3_ST_SW_KEY_EXCH_A;
|
||||
s->init_num=0;
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
case SSL3_ST_SW_CHANGE_A:
|
||||
case SSL3_ST_SW_CHANGE_B:
|
||||
|
||||
|
|
@ -746,7 +793,7 @@ int dtls1_send_server_hello(SSL *s)
|
|||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if ((p = ssl_add_serverhello_dtlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
|
||||
if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
|
|
@ -1172,3 +1219,114 @@ int dtls1_send_server_certificate(SSL *s)
|
|||
/* SSL3_ST_SW_CERT_B */
|
||||
return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
int dtls1_send_newsession_ticket(SSL *s)
|
||||
{
|
||||
if (s->state == SSL3_ST_SW_SESSION_TICKET_A)
|
||||
{
|
||||
unsigned char *p, *senc, *macstart;
|
||||
int len, slen;
|
||||
unsigned int hlen, msg_len;
|
||||
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];
|
||||
|
||||
/* get session encoding length */
|
||||
slen = i2d_SSL_SESSION(s->session, NULL);
|
||||
/* Some length values are 16 bits, so forget it if session is
|
||||
* too long
|
||||
*/
|
||||
if (slen > 0xFF00)
|
||||
return -1;
|
||||
/* Grow buffer if need be: the length calculation is as
|
||||
* follows 12 (DTLS handshake message header) +
|
||||
* 4 (ticket lifetime hint) + 2 (ticket length) +
|
||||
* 16 (key name) + max_iv_len (iv length) +
|
||||
* session_length + max_enc_block_size (max encrypted session
|
||||
* length) + max_md_size (HMAC).
|
||||
*/
|
||||
if (!BUF_MEM_grow(s->init_buf,
|
||||
DTLS1_HM_HEADER_LENGTH + 22 + EVP_MAX_IV_LENGTH +
|
||||
EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen))
|
||||
return -1;
|
||||
senc = OPENSSL_malloc(slen);
|
||||
if (!senc)
|
||||
return -1;
|
||||
p = senc;
|
||||
i2d_SSL_SESSION(s->session, &p);
|
||||
|
||||
p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]);
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
HMAC_CTX_init(&hctx);
|
||||
/* Initialize HMAC and cipher contexts. If callback present
|
||||
* it does all the work otherwise use generated values
|
||||
* from parent ctx.
|
||||
*/
|
||||
if (tctx->tlsext_ticket_key_cb)
|
||||
{
|
||||
if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
|
||||
&hctx, 1) < 0)
|
||||
{
|
||||
OPENSSL_free(senc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RAND_pseudo_bytes(iv, 16);
|
||||
EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
|
||||
tctx->tlsext_tick_aes_key, iv);
|
||||
HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
|
||||
tlsext_tick_md(), NULL);
|
||||
memcpy(key_name, tctx->tlsext_tick_key_name, 16);
|
||||
}
|
||||
l2n(s->session->tlsext_tick_lifetime_hint, p);
|
||||
/* Skip ticket length for now */
|
||||
p += 2;
|
||||
/* Output key name */
|
||||
macstart = p;
|
||||
memcpy(p, key_name, 16);
|
||||
p += 16;
|
||||
/* output IV */
|
||||
memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx));
|
||||
p += EVP_CIPHER_CTX_iv_length(&ctx);
|
||||
/* Encrypt session data */
|
||||
EVP_EncryptUpdate(&ctx, p, &len, senc, slen);
|
||||
p += len;
|
||||
EVP_EncryptFinal(&ctx, p, &len);
|
||||
p += len;
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
|
||||
HMAC_Update(&hctx, macstart, p - macstart);
|
||||
HMAC_Final(&hctx, p, &hlen);
|
||||
HMAC_CTX_cleanup(&hctx);
|
||||
|
||||
p += hlen;
|
||||
/* Now write out lengths: p points to end of data written */
|
||||
/* Total length */
|
||||
len = p - (unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]);
|
||||
p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]) + 4;
|
||||
s2n(len - 18, p); /* Ticket length */
|
||||
|
||||
/* number of bytes to write */
|
||||
s->init_num= len;
|
||||
s->state=SSL3_ST_SW_SESSION_TICKET_B;
|
||||
s->init_off=0;
|
||||
OPENSSL_free(senc);
|
||||
|
||||
/* XDTLS: set message header ? */
|
||||
msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH;
|
||||
dtls1_set_message_header(s, (void *)s->init_buf->data,
|
||||
SSL3_MT_NEWSESSION_TICKET, msg_len, 0, msg_len);
|
||||
|
||||
/* buffer the message to handle re-xmits */
|
||||
dtls1_buffer_message(s, 0);
|
||||
}
|
||||
|
||||
/* SSL3_ST_SW_SESSION_TICKET_B */
|
||||
return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
}
|
||||
#endif
|
||||
|
|
@ -144,9 +144,6 @@
|
|||
|
||||
static SSL_METHOD *ssl3_get_client_method(int ver);
|
||||
static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static int ssl3_check_finished(SSL *s);
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
static int curve_id2nid(int curve_id);
|
||||
|
|
@ -861,7 +858,7 @@ int ssl3_get_server_hello(SSL *s)
|
|||
#endif
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* TLS extensions*/
|
||||
if (s->version > SSL3_VERSION && s->version != DTLS1_VERSION && s->version != DTLS1_BAD_VER)
|
||||
if (s->version >= SSL3_VERSION)
|
||||
{
|
||||
if (!ssl_parse_serverhello_tlsext(s,&p,d,n, &al))
|
||||
{
|
||||
|
|
@ -875,17 +872,6 @@ int ssl3_get_server_hello(SSL *s)
|
|||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* DTLS extensions */
|
||||
if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
|
||||
{
|
||||
if (!ssl_parse_serverhello_dtlsext(s,&p,d,n, &al))
|
||||
{
|
||||
/* 'al' set by ssl_parse_serverhello_dtlsext */
|
||||
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT);
|
||||
goto f_err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -1732,6 +1718,7 @@ int ssl3_get_new_session_ticket(SSL *s)
|
|||
SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
p=d=(unsigned char *)s->init_msg;
|
||||
n2l(p, s->session->tlsext_tick_lifetime_hint);
|
||||
n2s(p, ticklen);
|
||||
|
|
@ -2735,7 +2722,7 @@ static int curve_id2nid(int curve_id)
|
|||
*/
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static int ssl3_check_finished(SSL *s)
|
||||
int ssl3_check_finished(SSL *s)
|
||||
{
|
||||
int ok;
|
||||
long n;
|
||||
|
|
|
|||
|
|
@ -957,7 +957,7 @@ int ssl3_get_client_hello(SSL *s)
|
|||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
/* TLS extensions*/
|
||||
if (s->version > SSL3_VERSION && s->version != DTLS1_VERSION && s->version != DTLS1_BAD_VER)
|
||||
if (s->version >= SSL3_VERSION)
|
||||
{
|
||||
if (!ssl_parse_clienthello_tlsext(s,&p,d,n, &al))
|
||||
{
|
||||
|
|
@ -970,17 +970,6 @@ int ssl3_get_client_hello(SSL *s)
|
|||
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* DTLS extensions */
|
||||
if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
|
||||
{
|
||||
if (!ssl_parse_clienthello_dtlsext(s,&p,d,n, &al))
|
||||
{
|
||||
/* 'al' set by ssl_parse_clienthello_dtlsext */
|
||||
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT);
|
||||
goto f_err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Worst case, we will use the NULL compression, but if we have other
|
||||
* options, we will now look for them. We have i-1 compression
|
||||
|
|
|
|||
|
|
@ -129,6 +129,9 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Magic Cipher Suite Value. NB: bogus value used for testing */
|
||||
#define SSL3_CK_MCSV 0x03000FEC
|
||||
|
||||
#define SSL3_CK_RSA_NULL_MD5 0x03000001
|
||||
#define SSL3_CK_RSA_NULL_SHA 0x03000002
|
||||
#define SSL3_CK_RSA_RC4_40_MD5 0x03000003
|
||||
|
|
|
|||
|
|
@ -1287,6 +1287,22 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
|
|||
j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
|
||||
p+=j;
|
||||
}
|
||||
/* If p == q, no ciphers and caller indicates an error, otherwise
|
||||
* add MCSV
|
||||
*/
|
||||
if (p != q)
|
||||
{
|
||||
static SSL_CIPHER msvc =
|
||||
{
|
||||
0, NULL, SSL3_CK_MCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
j = put_cb ? put_cb(&msvc,p) : ssl_put_cipher_by_char(s,&msvc,p);
|
||||
p+=j;
|
||||
#ifdef OPENSSL_RI_DEBUG
|
||||
fprintf(stderr, "MCSV sent by client\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
return(p-q);
|
||||
}
|
||||
|
||||
|
|
@ -1297,6 +1313,8 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
|
|||
STACK_OF(SSL_CIPHER) *sk;
|
||||
int i,n;
|
||||
|
||||
s->s3->send_connection_binding = 0;
|
||||
|
||||
n=ssl_put_cipher_by_char(s,NULL,NULL);
|
||||
if ((num%n) != 0)
|
||||
{
|
||||
|
|
@ -1313,6 +1331,19 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
|
|||
|
||||
for (i=0; i<num; i+=n)
|
||||
{
|
||||
/* Check for MCSV */
|
||||
if ((n != 3 || !p[0]) &&
|
||||
(p[n-2] == ((SSL3_CK_MCSV >> 8) & 0xff)) &&
|
||||
(p[n-1] == (SSL3_CK_MCSV & 0xff)))
|
||||
{
|
||||
s->s3->send_connection_binding = 1;
|
||||
p += n;
|
||||
#ifdef OPENSSL_RI_DEBUG
|
||||
fprintf(stderr, "MCSV received by server\n");
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
c=ssl_get_cipher_by_char(s,p);
|
||||
p+=n;
|
||||
if (c != NULL)
|
||||
|
|
|
|||
|
|
@ -876,7 +876,7 @@ void dtls1_start_timer(SSL *s);
|
|||
void dtls1_stop_timer(SSL *s);
|
||||
int dtls1_is_timer_expired(SSL *s);
|
||||
void dtls1_double_timeout(SSL *s);
|
||||
|
||||
int dtls1_send_newsession_ticket(SSL *s);
|
||||
|
||||
|
||||
/* some client-only functions */
|
||||
|
|
@ -893,6 +893,9 @@ int ssl3_send_client_key_exchange(SSL *s);
|
|||
int ssl3_get_key_exchange(SSL *s);
|
||||
int ssl3_get_server_certificate(SSL *s);
|
||||
int ssl3_check_cert_and_algorithm(SSL *s);
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
int ssl3_check_finished(SSL *s);
|
||||
#endif
|
||||
|
||||
int dtls1_client_hello(SSL *s);
|
||||
int dtls1_send_client_certificate(SSL *s);
|
||||
|
|
@ -977,11 +980,6 @@ int ssl_prepare_serverhello_tlsext(SSL *s);
|
|||
int ssl_check_clienthello_tlsext(SSL *s);
|
||||
int ssl_check_serverhello_tlsext(SSL *s);
|
||||
|
||||
unsigned char *ssl_add_clienthello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit);
|
||||
unsigned char *ssl_add_serverhello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit);
|
||||
int ssl_parse_clienthello_dtlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
|
||||
int ssl_parse_serverhello_dtlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
|
||||
|
||||
#ifdef OPENSSL_NO_SHA256
|
||||
#define tlsext_tick_md EVP_sha1
|
||||
#else
|
||||
|
|
|
|||
22
ssl/t1_lib.c
22
ssl/t1_lib.c
|
|
@ -133,8 +133,9 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
|||
int extdatalen=0;
|
||||
unsigned char *ret = p;
|
||||
|
||||
/* don't add extensions for SSLv3 */
|
||||
if (s->client_version == SSL3_VERSION)
|
||||
/* don't add extensions for SSLv3 unless doing secure renegotiation */
|
||||
if (s->client_version == SSL3_VERSION
|
||||
&& !s->s3->send_connection_binding)
|
||||
return p;
|
||||
|
||||
ret+=2;
|
||||
|
|
@ -220,7 +221,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
|||
}
|
||||
}
|
||||
|
||||
if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
|
||||
if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp &&
|
||||
s->version != DTLS1_VERSION)
|
||||
{
|
||||
int i;
|
||||
long extlen, idlen, itmp;
|
||||
|
|
@ -280,8 +282,8 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
|||
int extdatalen=0;
|
||||
unsigned char *ret = p;
|
||||
|
||||
/* don't add extensions for SSLv3 */
|
||||
if (s->version == SSL3_VERSION)
|
||||
/* don't add extensions for SSLv3, unless doing secure renegotiation */
|
||||
if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
|
||||
return p;
|
||||
|
||||
ret+=2;
|
||||
|
|
@ -295,7 +297,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
|
|||
s2n(0,ret);
|
||||
}
|
||||
|
||||
if(s->s3->send_connection_binding)
|
||||
if(s->s3->send_connection_binding)
|
||||
{
|
||||
int el;
|
||||
|
||||
|
|
@ -351,7 +353,6 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
|||
|
||||
s->servername_done = 0;
|
||||
s->tlsext_status_type = -1;
|
||||
s->s3->send_connection_binding = 0;
|
||||
|
||||
if (data >= (d+n-2))
|
||||
{
|
||||
|
|
@ -483,8 +484,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
|||
return 0;
|
||||
renegotiate_seen = 1;
|
||||
}
|
||||
else if (type == TLSEXT_TYPE_status_request
|
||||
&& s->ctx->tlsext_status_cb)
|
||||
else if (type == TLSEXT_TYPE_status_request &&
|
||||
s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb)
|
||||
{
|
||||
|
||||
if (size < 5)
|
||||
|
|
@ -658,7 +659,8 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
|
|||
}
|
||||
s->tlsext_ticket_expected = 1;
|
||||
}
|
||||
else if (type == TLSEXT_TYPE_status_request)
|
||||
else if (type == TLSEXT_TYPE_status_request &&
|
||||
s->version != DTLS1_VERSION)
|
||||
{
|
||||
/* MUST be empty and only sent if we've requested
|
||||
* a status request message.
|
||||
|
|
|
|||
|
|
@ -130,10 +130,14 @@ int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
|
|||
|
||||
memcpy(p, s->s3->previous_client_finished,
|
||||
s->s3->previous_client_finished_len);
|
||||
#ifdef OPENSSL_RI_DEBUG
|
||||
fprintf(stderr, "RI extension sent by client\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
*len=s->s3->previous_client_finished_len + 1;
|
||||
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -166,7 +170,7 @@ int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
|
|||
if(ilen != s->s3->previous_client_finished_len)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
|
||||
*al=SSL_AD_ILLEGAL_PARAMETER;
|
||||
*al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -174,9 +178,12 @@ int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
|
|||
s->s3->previous_client_finished_len))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
|
||||
*al=SSL_AD_ILLEGAL_PARAMETER;
|
||||
*al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
return 0;
|
||||
}
|
||||
#ifdef OPENSSL_RI_DEBUG
|
||||
fprintf(stderr, "RI extension received by server\n");
|
||||
#endif
|
||||
|
||||
s->s3->send_connection_binding=1;
|
||||
|
||||
|
|
@ -206,6 +213,9 @@ int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
|
|||
|
||||
memcpy(p, s->s3->previous_server_finished,
|
||||
s->s3->previous_server_finished_len);
|
||||
#ifdef OPENSSL_RI_DEBUG
|
||||
fprintf(stderr, "RI extension sent by server\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
*len=s->s3->previous_client_finished_len
|
||||
|
|
@ -249,7 +259,7 @@ int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
|
|||
if(ilen != expected_len)
|
||||
{
|
||||
SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
|
||||
*al=SSL_AD_ILLEGAL_PARAMETER;
|
||||
*al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -257,7 +267,7 @@ int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
|
|||
s->s3->previous_client_finished_len))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,SSL_R_RENEGOTIATION_MISMATCH);
|
||||
*al=SSL_AD_ILLEGAL_PARAMETER;
|
||||
*al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
return 0;
|
||||
}
|
||||
d += s->s3->previous_client_finished_len;
|
||||
|
|
@ -269,6 +279,10 @@ int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
|
|||
*al=SSL_AD_ILLEGAL_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
#ifdef OPENSSL_RI_DEBUG
|
||||
fprintf(stderr, "RI extension received by client\n");
|
||||
#endif
|
||||
s->s3->send_connection_binding=1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue