mirror of https://github.com/openssl/openssl.git
Create a dlts_write_records() function
In preparation for moving the DTLS code to use the new write record layer architecture we first restructure the code to create a dtls_write_records() function that mirrors the functionality that the record layer will provide. Reviewed-by: Richard Levitte <levitte@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Hugo Landau <hlandau@openssl.org> (Merged from https://github.com/openssl/openssl/pull/19424)
This commit is contained in:
parent
22d6e8547f
commit
88bf978eb1
|
|
@ -713,45 +713,18 @@ static int ssl3_write_pending(SSL_CONNECTION *s, int type,
|
|||
}
|
||||
}
|
||||
|
||||
int do_dtls1_write(SSL_CONNECTION *sc, int type, const unsigned char *buf,
|
||||
size_t len, size_t *written)
|
||||
static int dtls_write_records(SSL_CONNECTION *sc, OSSL_RECORD_TEMPLATE *tmpl,
|
||||
size_t numtmpl)
|
||||
{
|
||||
unsigned char *p, *pseq;
|
||||
int i, mac_size, clear = 0;
|
||||
size_t prefix_len = 0;
|
||||
int mac_size, clear = 0;
|
||||
size_t prefix_len = 0, written;
|
||||
int eivlen;
|
||||
SSL3_RECORD wr;
|
||||
SSL3_BUFFER *wb;
|
||||
SSL3_BUFFER *wb = sc->rlayer.wbuf;
|
||||
SSL_SESSION *sess;
|
||||
SSL *s = SSL_CONNECTION_GET_SSL(sc);
|
||||
|
||||
wb = &sc->rlayer.wbuf[0];
|
||||
|
||||
/*
|
||||
* DTLS writes whole datagrams, so there can't be anything left in
|
||||
* the buffer.
|
||||
*/
|
||||
if (!ossl_assert(SSL3_BUFFER_get_left(wb) == 0)) {
|
||||
SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If we have an alert to send, lets send it */
|
||||
if (sc->s3.alert_dispatch) {
|
||||
i = s->method->ssl_dispatch_alert(s);
|
||||
if (i <= 0)
|
||||
return i;
|
||||
/* if it went, fall through and send more stuff */
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
if (len > ssl_get_max_send_fragment(sc)) {
|
||||
SSLfatal(sc, SSL_AD_INTERNAL_ERROR, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sess = sc->session;
|
||||
|
||||
if ((sess == NULL)
|
||||
|
|
@ -774,21 +747,10 @@ int do_dtls1_write(SSL_CONNECTION *sc, int type, const unsigned char *buf,
|
|||
|
||||
/* write the header */
|
||||
|
||||
*(p++) = type & 0xff;
|
||||
SSL3_RECORD_set_type(&wr, type);
|
||||
/*
|
||||
* Special case: for hello verify request, client version 1.0 and we
|
||||
* haven't decided which version to use yet send back using version 1.0
|
||||
* header: otherwise some clients will ignore it.
|
||||
*/
|
||||
if (s->method->version == DTLS_ANY_VERSION &&
|
||||
sc->max_proto_version != DTLS1_BAD_VER) {
|
||||
*(p++) = DTLS1_VERSION >> 8;
|
||||
*(p++) = DTLS1_VERSION & 0xff;
|
||||
} else {
|
||||
*(p++) = sc->version >> 8;
|
||||
*(p++) = sc->version & 0xff;
|
||||
}
|
||||
*(p++) = tmpl->type & 0xff;
|
||||
SSL3_RECORD_set_type(&wr, tmpl->type);
|
||||
*(p++) = tmpl->version >> 8;
|
||||
*(p++) = tmpl->version & 0xff;
|
||||
|
||||
/* field where we are to write out packet epoch, seq num and len */
|
||||
pseq = p;
|
||||
|
|
@ -818,8 +780,8 @@ int do_dtls1_write(SSL_CONNECTION *sc, int type, const unsigned char *buf,
|
|||
|
||||
/* lets setup the record stuff. */
|
||||
SSL3_RECORD_set_data(&wr, p + eivlen); /* make room for IV in case of CBC */
|
||||
SSL3_RECORD_set_length(&wr, len);
|
||||
SSL3_RECORD_set_input(&wr, (unsigned char *)buf);
|
||||
SSL3_RECORD_set_length(&wr, tmpl->buflen);
|
||||
SSL3_RECORD_set_input(&wr, (unsigned char *)tmpl->buf);
|
||||
|
||||
/*
|
||||
* we now 'read' from wr.input, wr.length bytes into wr.data
|
||||
|
|
@ -894,7 +856,7 @@ int do_dtls1_write(SSL_CONNECTION *sc, int type, const unsigned char *buf,
|
|||
* we should now have wr.data pointing to the encrypted data, which is
|
||||
* wr->length long
|
||||
*/
|
||||
SSL3_RECORD_set_type(&wr, type); /* not needed but helps for debugging */
|
||||
SSL3_RECORD_set_type(&wr, tmpl->type); /* not needed but helps for debugging */
|
||||
SSL3_RECORD_add_length(&wr, DTLS1_RT_HEADER_LENGTH);
|
||||
|
||||
ssl3_record_sequence_update(&(sc->rlayer.write_sequence[0]));
|
||||
|
|
@ -907,13 +869,72 @@ int do_dtls1_write(SSL_CONNECTION *sc, int type, const unsigned char *buf,
|
|||
* memorize arguments so that ssl3_write_pending can detect bad write
|
||||
* retries later
|
||||
*/
|
||||
sc->rlayer.wpend_tot = len;
|
||||
sc->rlayer.wpend_buf = buf;
|
||||
sc->rlayer.wpend_type = type;
|
||||
sc->rlayer.wpend_ret = len;
|
||||
sc->rlayer.wpend_tot = tmpl->buflen;
|
||||
sc->rlayer.wpend_buf = tmpl->buf;
|
||||
sc->rlayer.wpend_type = tmpl->type;
|
||||
sc->rlayer.wpend_ret = tmpl->buflen;
|
||||
|
||||
/* we now just need to write the buffer. Calls SSLfatal() as required. */
|
||||
return ssl3_write_pending(sc, type, buf, len, written);
|
||||
return ssl3_write_pending(sc, tmpl->type, tmpl->buf, tmpl->buflen, &written);
|
||||
}
|
||||
|
||||
int do_dtls1_write(SSL_CONNECTION *sc, int type, const unsigned char *buf,
|
||||
size_t len, size_t *written)
|
||||
{
|
||||
int i;
|
||||
OSSL_RECORD_TEMPLATE tmpl;
|
||||
SSL *s = SSL_CONNECTION_GET_SSL(sc);
|
||||
SSL3_BUFFER *wb;
|
||||
int ret;
|
||||
|
||||
wb = &sc->rlayer.wbuf[0];
|
||||
|
||||
/*
|
||||
* DTLS writes whole datagrams, so there can't be anything left in
|
||||
* the buffer.
|
||||
*/
|
||||
/* TODO(RECLAYER): Remove me */
|
||||
if (!ossl_assert(SSL3_BUFFER_get_left(wb) == 0)) {
|
||||
SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If we have an alert to send, lets send it */
|
||||
if (sc->s3.alert_dispatch) {
|
||||
i = s->method->ssl_dispatch_alert(s);
|
||||
if (i <= 0)
|
||||
return i;
|
||||
/* if it went, fall through and send more stuff */
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
if (len > ssl_get_max_send_fragment(sc)) {
|
||||
SSLfatal(sc, SSL_AD_INTERNAL_ERROR, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmpl.type = type;
|
||||
/*
|
||||
* Special case: for hello verify request, client version 1.0 and we
|
||||
* haven't decided which version to use yet send back using version 1.0
|
||||
* header: otherwise some clients will ignore it.
|
||||
*/
|
||||
if (s->method->version == DTLS_ANY_VERSION
|
||||
&& sc->max_proto_version != DTLS1_BAD_VER)
|
||||
tmpl.version = DTLS1_VERSION;
|
||||
else
|
||||
tmpl.version = sc->version;
|
||||
tmpl.buf = buf;
|
||||
tmpl.buflen = len;
|
||||
|
||||
ret = dtls_write_records(sc, &tmpl, 1);
|
||||
|
||||
if (ret > 0)
|
||||
*written = (int)len;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dtls1_reset_seq_numbers(SSL_CONNECTION *s, int rw)
|
||||
|
|
|
|||
Loading…
Reference in New Issue