DTLS revision.
Revise DTLS code. There was a *lot* of code duplication in the
DTLS code that generates records. This makes it harder to maintain and
sometimes a TLS update is omitted by accident from the DTLS code.
Specifically almost all of the record generation functions have code like
this:
some_pointer = buffer + HANDSHAKE_HEADER_LENGTH;
... Record creation stuff ...
set_handshake_header(ssl, SSL_MT_SOMETHING, message_len);
...
write_handshake_message(ssl);
Where the "Record creation stuff" is identical between SSL/TLS and DTLS or
in some cases has very minor differences.
By adding a few fields to SSL3_ENC to include the header length, some flags
and function pointers for handshake header setting and handshake writing the
code can cope with both cases.
(cherry picked from commit 173e72e64c
)
This commit is contained in:
132
ssl/s3_srvr.c
132
ssl/s3_srvr.c
@@ -869,24 +869,15 @@ end:
|
||||
|
||||
int ssl3_send_hello_request(SSL *s)
|
||||
{
|
||||
unsigned char *p;
|
||||
|
||||
if (s->state == SSL3_ST_SW_HELLO_REQ_A)
|
||||
{
|
||||
p=(unsigned char *)s->init_buf->data;
|
||||
*(p++)=SSL3_MT_HELLO_REQUEST;
|
||||
*(p++)=0;
|
||||
*(p++)=0;
|
||||
*(p++)=0;
|
||||
|
||||
ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0);
|
||||
s->state=SSL3_ST_SW_HELLO_REQ_B;
|
||||
/* number of bytes to write */
|
||||
s->init_num=4;
|
||||
s->init_off=0;
|
||||
}
|
||||
|
||||
/* SSL3_ST_SW_HELLO_REQ_B */
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
return ssl_do_write(s);
|
||||
}
|
||||
|
||||
int ssl3_check_client_hello(SSL *s)
|
||||
@@ -1472,7 +1463,7 @@ int ssl3_send_server_hello(SSL *s)
|
||||
return -1;
|
||||
#endif
|
||||
/* Do the message type and length last */
|
||||
d=p= &(buf[4]);
|
||||
d=p= ssl_handshake_start(s);
|
||||
|
||||
*(p++)=s->version>>8;
|
||||
*(p++)=s->version&0xff;
|
||||
@@ -1537,42 +1528,25 @@ int ssl3_send_server_hello(SSL *s)
|
||||
#endif
|
||||
/* do the header */
|
||||
l=(p-d);
|
||||
d=buf;
|
||||
*(d++)=SSL3_MT_SERVER_HELLO;
|
||||
l2n3(l,d);
|
||||
|
||||
ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l);
|
||||
s->state=SSL3_ST_SW_SRVR_HELLO_B;
|
||||
/* number of bytes to write */
|
||||
s->init_num=p-buf;
|
||||
s->init_off=0;
|
||||
}
|
||||
|
||||
/* SSL3_ST_SW_SRVR_HELLO_B */
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
return ssl_do_write(s);
|
||||
}
|
||||
|
||||
int ssl3_send_server_done(SSL *s)
|
||||
{
|
||||
unsigned char *p;
|
||||
|
||||
if (s->state == SSL3_ST_SW_SRVR_DONE_A)
|
||||
{
|
||||
p=(unsigned char *)s->init_buf->data;
|
||||
|
||||
/* do the header */
|
||||
*(p++)=SSL3_MT_SERVER_DONE;
|
||||
*(p++)=0;
|
||||
*(p++)=0;
|
||||
*(p++)=0;
|
||||
|
||||
s->state=SSL3_ST_SW_SRVR_DONE_B;
|
||||
/* number of bytes to write */
|
||||
s->init_num=4;
|
||||
s->init_off=0;
|
||||
ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0);
|
||||
s->state = SSL3_ST_SW_SRVR_DONE_B;
|
||||
}
|
||||
|
||||
/* SSL3_ST_SW_SRVR_DONE_B */
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
return ssl_do_write(s);
|
||||
}
|
||||
|
||||
int ssl3_send_server_key_exchange(SSL *s)
|
||||
@@ -1896,13 +1870,12 @@ int ssl3_send_server_key_exchange(SSL *s)
|
||||
kn=0;
|
||||
}
|
||||
|
||||
if (!BUF_MEM_grow_clean(buf,n+4+kn))
|
||||
if (!BUF_MEM_grow_clean(buf,n+SSL_HM_HEADER_LENGTH(s)+kn))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF);
|
||||
goto err;
|
||||
}
|
||||
d=(unsigned char *)s->init_buf->data;
|
||||
p= &(d[4]);
|
||||
d = p = ssl_handshake_start(s);
|
||||
|
||||
for (i=0; r[i] != NULL && i<4; i++)
|
||||
{
|
||||
@@ -1974,7 +1947,7 @@ int ssl3_send_server_key_exchange(SSL *s)
|
||||
?s->ctx->md5:s->ctx->sha1, NULL);
|
||||
EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
|
||||
EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
|
||||
EVP_DigestUpdate(&md_ctx,&(d[4]),n);
|
||||
EVP_DigestUpdate(&md_ctx,d,n);
|
||||
EVP_DigestFinal_ex(&md_ctx,q,
|
||||
(unsigned int *)&i);
|
||||
q+=i;
|
||||
@@ -2013,7 +1986,7 @@ int ssl3_send_server_key_exchange(SSL *s)
|
||||
EVP_SignInit_ex(&md_ctx, md, NULL);
|
||||
EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
|
||||
EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
|
||||
EVP_SignUpdate(&md_ctx,&(d[4]),n);
|
||||
EVP_SignUpdate(&md_ctx,d,n);
|
||||
if (!EVP_SignFinal(&md_ctx,&(p[2]),
|
||||
(unsigned int *)&i,pkey))
|
||||
{
|
||||
@@ -2034,18 +2007,12 @@ int ssl3_send_server_key_exchange(SSL *s)
|
||||
}
|
||||
}
|
||||
|
||||
*(d++)=SSL3_MT_SERVER_KEY_EXCHANGE;
|
||||
l2n3(n,d);
|
||||
|
||||
/* we should now have things packed up, so lets send
|
||||
* it off */
|
||||
s->init_num=n+4;
|
||||
s->init_off=0;
|
||||
ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n);
|
||||
}
|
||||
|
||||
s->state = SSL3_ST_SW_KEY_EXCH_B;
|
||||
EVP_MD_CTX_cleanup(&md_ctx);
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
return ssl_do_write(s);
|
||||
f_err:
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,al);
|
||||
err:
|
||||
@@ -2069,7 +2036,7 @@ int ssl3_send_certificate_request(SSL *s)
|
||||
{
|
||||
buf=s->init_buf;
|
||||
|
||||
d=p=(unsigned char *)&(buf->data[4]);
|
||||
d=p=ssl_handshake_start(s);
|
||||
|
||||
/* get the list of acceptable cert types */
|
||||
p++;
|
||||
@@ -2124,34 +2091,29 @@ int ssl3_send_certificate_request(SSL *s)
|
||||
}
|
||||
}
|
||||
/* else no CA names */
|
||||
p=(unsigned char *)&(buf->data[4+off]);
|
||||
p = ssl_handshake_start(s) + off;
|
||||
s2n(nl,p);
|
||||
|
||||
d=(unsigned char *)buf->data;
|
||||
*(d++)=SSL3_MT_CERTIFICATE_REQUEST;
|
||||
l2n3(n,d);
|
||||
ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n);
|
||||
|
||||
/* we should now have things packed up, so lets send
|
||||
* it off */
|
||||
|
||||
s->init_num=n+4;
|
||||
s->init_off=0;
|
||||
#ifdef NETSCAPE_HANG_BUG
|
||||
p=(unsigned char *)s->init_buf->data + s->init_num;
|
||||
|
||||
/* do the header */
|
||||
*(p++)=SSL3_MT_SERVER_DONE;
|
||||
*(p++)=0;
|
||||
*(p++)=0;
|
||||
*(p++)=0;
|
||||
s->init_num += 4;
|
||||
if (!SSL_IS_DTLS(s))
|
||||
{
|
||||
p=(unsigned char *)s->init_buf->data + s->init_num;
|
||||
/* do the header */
|
||||
*(p++)=SSL3_MT_SERVER_DONE;
|
||||
*(p++)=0;
|
||||
*(p++)=0;
|
||||
*(p++)=0;
|
||||
s->init_num += 4;
|
||||
}
|
||||
#endif
|
||||
|
||||
s->state = SSL3_ST_SW_CERT_REQ_B;
|
||||
}
|
||||
|
||||
/* SSL3_ST_SW_CERT_REQ_B */
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
return ssl_do_write(s);
|
||||
err:
|
||||
return(-1);
|
||||
}
|
||||
@@ -3387,7 +3349,6 @@ err:
|
||||
|
||||
int ssl3_send_server_certificate(SSL *s)
|
||||
{
|
||||
unsigned long l;
|
||||
CERT_PKEY *cpk;
|
||||
|
||||
if (s->state == SSL3_ST_SW_CERT_A)
|
||||
@@ -3404,14 +3365,12 @@ int ssl3_send_server_certificate(SSL *s)
|
||||
}
|
||||
}
|
||||
|
||||
l=ssl3_output_cert_chain(s,cpk);
|
||||
ssl3_output_cert_chain(s,cpk);
|
||||
s->state=SSL3_ST_SW_CERT_B;
|
||||
s->init_num=(int)l;
|
||||
s->init_off=0;
|
||||
}
|
||||
|
||||
/* SSL3_ST_SW_CERT_B */
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
return ssl_do_write(s);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
@@ -3465,22 +3424,17 @@ int ssl3_send_newsession_ticket(SSL *s)
|
||||
SSL_SESSION_free(sess);
|
||||
|
||||
/* Grow buffer if need be: the length calculation is as
|
||||
* follows 1 (size of message name) + 3 (message length
|
||||
* bytes) + 4 (ticket lifetime hint) + 2 (ticket length) +
|
||||
* follows handshake_header_length +
|
||||
* 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,
|
||||
26 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH +
|
||||
EVP_MAX_MD_SIZE + slen))
|
||||
SSL_HM_HEADER_LENGTH(s) + 22 + EVP_MAX_IV_LENGTH +
|
||||
EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen))
|
||||
return -1;
|
||||
|
||||
p=(unsigned char *)s->init_buf->data;
|
||||
/* do the header */
|
||||
*(p++)=SSL3_MT_NEWSESSION_TICKET;
|
||||
/* Skip message length for now */
|
||||
p += 3;
|
||||
p = ssl_handshake_start(s);
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
HMAC_CTX_init(&hctx);
|
||||
/* Initialize HMAC and cipher contexts. If callback present
|
||||
@@ -3535,21 +3489,17 @@ int ssl3_send_newsession_ticket(SSL *s)
|
||||
p += hlen;
|
||||
/* Now write out lengths: p points to end of data written */
|
||||
/* Total length */
|
||||
len = p - (unsigned char *)s->init_buf->data;
|
||||
p=(unsigned char *)s->init_buf->data + 1;
|
||||
l2n3(len - 4, p); /* Message length */
|
||||
p += 4;
|
||||
s2n(len - 10, p); /* Ticket length */
|
||||
|
||||
/* number of bytes to write */
|
||||
s->init_num= len;
|
||||
len = p - ssl_handshake_start(s);
|
||||
ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len);
|
||||
/* Skip ticket lifetime hint */
|
||||
p = ssl_handshake_start(s) + 4;
|
||||
s2n(len - 6, p);
|
||||
s->state=SSL3_ST_SW_SESSION_TICKET_B;
|
||||
s->init_off=0;
|
||||
OPENSSL_free(senc);
|
||||
}
|
||||
|
||||
/* SSL3_ST_SW_SESSION_TICKET_B */
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
return ssl_do_write(s);
|
||||
}
|
||||
|
||||
int ssl3_send_cert_status(SSL *s)
|
||||
|
Reference in New Issue
Block a user