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:
@@ -697,13 +697,34 @@ int ssl3_client_hello(SSL *s)
|
||||
/* else use the pre-loaded session */
|
||||
|
||||
p=s->s3->client_random;
|
||||
Time=(unsigned long)time(NULL); /* Time */
|
||||
l2n(Time,p);
|
||||
if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
|
||||
goto err;
|
||||
|
||||
/* for DTLS if client_random is initialized, reuse it, we are
|
||||
* required to use same upon reply to HelloVerify */
|
||||
if (SSL_IS_DTLS(s))
|
||||
{
|
||||
size_t idx;
|
||||
i = 1;
|
||||
for (idx=0; idx < sizeof(s->s3->client_random); idx++)
|
||||
{
|
||||
if (p[idx])
|
||||
{
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
i = 1;
|
||||
|
||||
if (i)
|
||||
{
|
||||
Time=(unsigned long)time(NULL); /* Time */
|
||||
l2n(Time,p);
|
||||
RAND_pseudo_bytes(p,sizeof(s->s3->client_random)-4);
|
||||
}
|
||||
|
||||
/* Do the message type and length last */
|
||||
d=p= &(buf[4]);
|
||||
d=p= ssl_handshake_start(s);
|
||||
|
||||
/* version indicates the negotiated version: for example from
|
||||
* an SSLv2/v3 compatible client hello). The client_version
|
||||
@@ -764,6 +785,19 @@ int ssl3_client_hello(SSL *s)
|
||||
p+=i;
|
||||
}
|
||||
|
||||
/* cookie stuff for DTLS */
|
||||
if (SSL_IS_DTLS(s))
|
||||
{
|
||||
if ( s->d1->cookie_len > sizeof(s->d1->cookie))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
*(p++) = s->d1->cookie_len;
|
||||
memcpy(p, s->d1->cookie, s->d1->cookie_len);
|
||||
p += s->d1->cookie_len;
|
||||
}
|
||||
|
||||
/* Ciphers supported */
|
||||
i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),0);
|
||||
if (i == 0)
|
||||
@@ -816,19 +850,13 @@ int ssl3_client_hello(SSL *s)
|
||||
}
|
||||
#endif
|
||||
|
||||
l=(p-d);
|
||||
d=buf;
|
||||
*(d++)=SSL3_MT_CLIENT_HELLO;
|
||||
l2n3(l,d);
|
||||
|
||||
l= p-d;
|
||||
ssl_set_handshake_header(s, SSL3_MT_CLIENT_HELLO, l);
|
||||
s->state=SSL3_ST_CW_CLNT_HELLO_B;
|
||||
/* number of bytes to write */
|
||||
s->init_num=p-buf;
|
||||
s->init_off=0;
|
||||
}
|
||||
|
||||
/* SSL3_ST_CW_CLNT_HELLO_B */
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
return ssl_do_write(s);
|
||||
err:
|
||||
return(-1);
|
||||
}
|
||||
@@ -2261,7 +2289,7 @@ int ssl3_get_server_done(SSL *s)
|
||||
|
||||
int ssl3_send_client_key_exchange(SSL *s)
|
||||
{
|
||||
unsigned char *p,*d;
|
||||
unsigned char *p;
|
||||
int n;
|
||||
unsigned long alg_k;
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
@@ -2282,8 +2310,7 @@ int ssl3_send_client_key_exchange(SSL *s)
|
||||
|
||||
if (s->state == SSL3_ST_CW_KEY_EXCH_A)
|
||||
{
|
||||
d=(unsigned char *)s->init_buf->data;
|
||||
p= &(d[4]);
|
||||
p = ssl_handshake_start(s);
|
||||
|
||||
alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
|
||||
|
||||
@@ -2984,18 +3011,13 @@ int ssl3_send_client_key_exchange(SSL *s)
|
||||
ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
*(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE;
|
||||
l2n3(n,d);
|
||||
|
||||
ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, n);
|
||||
s->state=SSL3_ST_CW_KEY_EXCH_B;
|
||||
/* number of bytes to write */
|
||||
s->init_num=n+4;
|
||||
s->init_off=0;
|
||||
}
|
||||
|
||||
/* SSL3_ST_CW_KEY_EXCH_B */
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
return ssl_do_write(s);
|
||||
err:
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
BN_CTX_free(bn_ctx);
|
||||
@@ -3009,7 +3031,7 @@ err:
|
||||
|
||||
int ssl3_send_client_verify(SSL *s)
|
||||
{
|
||||
unsigned char *p,*d;
|
||||
unsigned char *p;
|
||||
unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
|
||||
EVP_PKEY *pkey;
|
||||
EVP_PKEY_CTX *pctx=NULL;
|
||||
@@ -3022,8 +3044,7 @@ int ssl3_send_client_verify(SSL *s)
|
||||
|
||||
if (s->state == SSL3_ST_CW_CERT_VRFY_A)
|
||||
{
|
||||
d=(unsigned char *)s->init_buf->data;
|
||||
p= &(d[4]);
|
||||
p= ssl_handshake_start(s);
|
||||
pkey=s->cert->key->privatekey;
|
||||
/* Create context from key and test if sha1 is allowed as digest */
|
||||
pctx = EVP_PKEY_CTX_new(pkey,NULL);
|
||||
@@ -3149,16 +3170,12 @@ int ssl3_send_client_verify(SSL *s)
|
||||
SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
*(d++)=SSL3_MT_CERTIFICATE_VERIFY;
|
||||
l2n3(n,d);
|
||||
|
||||
ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n);
|
||||
s->state=SSL3_ST_CW_CERT_VRFY_B;
|
||||
s->init_num=(int)n+4;
|
||||
s->init_off=0;
|
||||
}
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
return ssl_do_write(s);
|
||||
err:
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
@@ -3215,7 +3232,6 @@ int ssl3_send_client_certificate(SSL *s)
|
||||
X509 *x509=NULL;
|
||||
EVP_PKEY *pkey=NULL;
|
||||
int i;
|
||||
unsigned long l;
|
||||
|
||||
if (s->state == SSL3_ST_CW_CERT_A)
|
||||
{
|
||||
@@ -3284,13 +3300,11 @@ int ssl3_send_client_certificate(SSL *s)
|
||||
if (s->state == SSL3_ST_CW_CERT_C)
|
||||
{
|
||||
s->state=SSL3_ST_CW_CERT_D;
|
||||
l=ssl3_output_cert_chain(s,
|
||||
ssl3_output_cert_chain(s,
|
||||
(s->s3->tmp.cert_req == 2)?NULL:s->cert->key);
|
||||
s->init_num=(int)l;
|
||||
s->init_off=0;
|
||||
}
|
||||
/* SSL3_ST_CW_CERT_D */
|
||||
return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
|
||||
return ssl_do_write(s);
|
||||
}
|
||||
|
||||
#define has_bits(i,m) (((i)&(m)) == (m))
|
||||
|
Reference in New Issue
Block a user