summaryrefslogtreecommitdiff
path: root/ssl
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2022-10-07 16:23:14 +0100
committerMatt Caswell <matt@openssl.org>2022-10-20 14:39:32 +0100
commit602ee1f672a41f984e8923ad7430ca51ca42abde (patch)
treeb7e49f757deff9bfa07cfef7aa52e22e6c869b86 /ssl
parent4cdd198ec204a4c2ec6b3ec728ebcc8af04abc86 (diff)
downloadopenssl-new-602ee1f672a41f984e8923ad7430ca51ca42abde.tar.gz
Use common tls_write_records() even for DTLS
In practice this just means have a DTLS specific write_records that the common tls_write_records() just calls. We also replace the use of ssl3_write_pending() with tls_retry_write_records(). 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)
Diffstat (limited to 'ssl')
-rw-r--r--ssl/record/methods/dtls_meth.c105
-rw-r--r--ssl/record/methods/recmethod_local.h3
-rw-r--r--ssl/record/methods/tls1_meth.c2
-rw-r--r--ssl/record/methods/tlsany_meth.c2
4 files changed, 18 insertions, 94 deletions
diff --git a/ssl/record/methods/dtls_meth.c b/ssl/record/methods/dtls_meth.c
index 3e9b344cb7..14cd70095d 100644
--- a/ssl/record/methods/dtls_meth.c
+++ b/ssl/record/methods/dtls_meth.c
@@ -689,91 +689,13 @@ dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers,
return ret;
}
-/*
- * TODO(RECLAYER): Temporary copy of the old ssl3_write_pending() function now
- * replaced by tls_retry_write_records(). Needs to be removed when the DTLS code
- * is converted
- */
-/* if SSL3_BUFFER_get_left() != 0, we need to call this
- *
- * Return values are as per SSL_write()
- */
-static int ssl3_write_pending(OSSL_RECORD_LAYER *rl, int type,
- const unsigned char *buf, size_t len,
- size_t *written)
-{
- int i;
- /* TODO(RECLAYER): Remove me */
- SSL_CONNECTION *s = (SSL_CONNECTION *)rl->cbarg;
- SSL3_BUFFER *wb = rl->wbuf;
- size_t currbuf = 0;
- size_t tmpwrit = 0;
-
- if ((s->rlayer.wpend_tot > len)
- || (!(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)
- && (s->rlayer.wpend_buf != buf))
- || (s->rlayer.wpend_type != type)) {
- RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_WRITE_RETRY);
- return OSSL_RECORD_RETURN_FATAL;
- }
-
- for (;;) {
- clear_sys_error();
- if (s->wbio != NULL) {
- s->rwstate = SSL_WRITING;
-
- i = BIO_write(s->wbio, (char *)
- &(SSL3_BUFFER_get_buf(&wb[currbuf])
- [SSL3_BUFFER_get_offset(&wb[currbuf])]),
- (unsigned int)SSL3_BUFFER_get_left(&wb[currbuf]));
- if (i >= 0)
- tmpwrit = i;
- } else {
- RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_BIO_NOT_SET);
- i = -1;
- }
-
- /*
- * When an empty fragment is sent on a connection using KTLS,
- * it is sent as a write of zero bytes. If this zero byte
- * write succeeds, i will be 0 rather than a non-zero value.
- * Treat i == 0 as success rather than an error for zero byte
- * writes to permit this case.
- */
- if (i >= 0 && tmpwrit == SSL3_BUFFER_get_left(&wb[currbuf])) {
- SSL3_BUFFER_set_left(&wb[currbuf], 0);
- SSL3_BUFFER_add_offset(&wb[currbuf], tmpwrit);
- s->rwstate = SSL_NOTHING;
- *written = s->rlayer.wpend_ret;
- return OSSL_RECORD_RETURN_SUCCESS;
- } else if (i <= 0) {
- if (SSL_CONNECTION_IS_DTLS(s)) {
- /*
- * For DTLS, just drop it. That's kind of the whole point in
- * using a datagram service
- */
- SSL3_BUFFER_set_left(&wb[currbuf], 0);
- }
-
- if (BIO_should_retry(s->wbio))
- return OSSL_RECORD_RETURN_RETRY;
-
- return OSSL_RECORD_RETURN_FATAL;
- }
- SSL3_BUFFER_add_offset(&wb[currbuf], tmpwrit);
- SSL3_BUFFER_sub_left(&wb[currbuf], tmpwrit);
- }
-}
-
-static int dtls_write_records(OSSL_RECORD_LAYER *rl,
- OSSL_RECORD_TEMPLATE *templates,
- size_t numtempl)
+int dtls_write_records(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl)
{
/* TODO(RECLAYER): Remove me */
SSL_CONNECTION *sc = (SSL_CONNECTION *)rl->cbarg;
unsigned char *p, *pseq;
int mac_size, clear = 0;
- size_t written;
int eivlen;
SSL3_RECORD wr;
SSL3_BUFFER *wb;
@@ -794,19 +716,19 @@ static int dtls_write_records(OSSL_RECORD_LAYER *rl,
if (mac_size < 0) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR,
SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE);
- return OSSL_RECORD_RETURN_FATAL;
+ return 0;
}
}
if (numtempl != 1) {
/* Should not happen */
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- return OSSL_RECORD_RETURN_FATAL;
+ return 0;
}
if (!rl->funcs->allocate_write_buffers(rl, templates, numtempl, NULL)) {
/* RLAYERfatal() already called */
- return OSSL_RECORD_RETURN_FATAL;
+ return 0;
}
wb = rl->wbuf;
@@ -830,7 +752,7 @@ static int dtls_write_records(OSSL_RECORD_LAYER *rl,
eivlen = EVP_CIPHER_CTX_get_iv_length(sc->enc_write_ctx);
if (eivlen < 0) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG);
- return OSSL_RECORD_RETURN_FATAL;
+ return 0;
}
if (eivlen <= 1)
eivlen = 0;
@@ -858,7 +780,7 @@ static int dtls_write_records(OSSL_RECORD_LAYER *rl,
if (sc->compress != NULL) {
if (!ssl3_do_compress(sc, &wr)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_COMPRESSION_FAILURE);
- return OSSL_RECORD_RETURN_FATAL;
+ return 0;
}
} else {
memcpy(SSL3_RECORD_get_data(&wr), SSL3_RECORD_get_input(&wr),
@@ -877,7 +799,7 @@ static int dtls_write_records(OSSL_RECORD_LAYER *rl,
&(p[SSL3_RECORD_get_length(&wr) + eivlen]),
1)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- return OSSL_RECORD_RETURN_FATAL;
+ return 0;
}
SSL3_RECORD_add_length(&wr, mac_size);
}
@@ -893,14 +815,14 @@ static int dtls_write_records(OSSL_RECORD_LAYER *rl,
if (!ossl_statem_in_error(sc)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
}
- return OSSL_RECORD_RETURN_FATAL;
+ return 0;
}
if (SSL_WRITE_ETM(sc) && mac_size != 0) {
if (!s->method->ssl3_enc->mac(sc, &wr,
&(p[SSL3_RECORD_get_length(&wr)]), 1)) {
RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- return OSSL_RECORD_RETURN_FATAL;
+ return 0;
}
SSL3_RECORD_add_length(&wr, mac_size);
}
@@ -941,9 +863,8 @@ static int dtls_write_records(OSSL_RECORD_LAYER *rl,
sc->rlayer.wpend_type = templates->type;
sc->rlayer.wpend_ret = templates->buflen;
- /* we now just need to write the buffer. Calls SSLfatal() as required. */
- return ssl3_write_pending(rl, templates->type, templates->buf,
- templates->buflen, &written);
+
+ return 1;
}
const OSSL_RECORD_METHOD ossl_dtls_record_method = {
@@ -956,7 +877,7 @@ const OSSL_RECORD_METHOD ossl_dtls_record_method = {
tls_write_pending,
tls_get_max_record_len,
tls_get_max_records,
- dtls_write_records,
+ tls_write_records,
tls_retry_write_records,
tls_read_record,
tls_release_record,
diff --git a/ssl/record/methods/recmethod_local.h b/ssl/record/methods/recmethod_local.h
index cb68916364..b9ce61e4ef 100644
--- a/ssl/record/methods/recmethod_local.h
+++ b/ssl/record/methods/recmethod_local.h
@@ -349,6 +349,9 @@ int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend,
int tls_get_more_records(OSSL_RECORD_LAYER *rl);
int dtls_get_more_records(OSSL_RECORD_LAYER *rl);
+int dtls_write_records(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates,
+ size_t numtempl);
+
int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version);
int tls_default_validate_record_header(OSSL_RECORD_LAYER *rl, SSL3_RECORD *re);
int tls_do_uncompress(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec);
diff --git a/ssl/record/methods/tls1_meth.c b/ssl/record/methods/tls1_meth.c
index 71034a35c9..392ce336be 100644
--- a/ssl/record/methods/tls1_meth.c
+++ b/ssl/record/methods/tls1_meth.c
@@ -673,7 +673,7 @@ struct record_functions_st dtls_1_funcs = {
NULL,
NULL,
NULL,
- NULL,
+ dtls_write_records,
/*
* Don't use tls1_allocate_write_buffers since that handles empty fragment
* records which aren't needed in DTLS. We just use the default allocation
diff --git a/ssl/record/methods/tlsany_meth.c b/ssl/record/methods/tlsany_meth.c
index 3fb66d372f..0914acc15e 100644
--- a/ssl/record/methods/tlsany_meth.c
+++ b/ssl/record/methods/tlsany_meth.c
@@ -183,7 +183,7 @@ struct record_functions_st dtls_any_funcs = {
NULL,
NULL,
NULL,
- NULL,
+ dtls_write_records,
tls_allocate_write_buffers_default,
NULL,
NULL,