* https://www.openssl.org/source/license.html
*/
+#include <assert.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
* http://www.openssl.org/~bodo/tls-cbc.txt)
*/
prefixtempl.buf = NULL;
+ prefixtempl.version = templates[0].version;
prefixtempl.buflen = 0;
prefixtempl.type = SSL3_RT_APPLICATION_DATA;
wpinited = 1;
/* Clear our SSL3_RECORD structures */
memset(wr, 0, sizeof(wr));
for (j = 0; j < numtempl + prefix; j++) {
- unsigned int version = (s->version == TLS1_3_VERSION) ? TLS1_2_VERSION
- : s->version;
unsigned char *compressdata = NULL;
size_t maxcomplen;
unsigned int rectype;
rectype = thistempl->type;
SSL3_RECORD_set_type(thiswr, rectype);
-
- /*
- * Some servers hang if initial client hello is larger than 256 bytes
- * and record version number > TLS 1.0
- */
- if (SSL_get_state(ssl) == TLS_ST_CW_CLNT_HELLO
- && !s->renegotiate
- && TLS1_get_version(ssl) > TLS1_VERSION
- && s->hello_retry_request == SSL_HRR_NONE)
- version = TLS1_VERSION;
- SSL3_RECORD_set_rec_version(thiswr, version);
+ SSL3_RECORD_set_rec_version(thiswr, thistempl->version);
maxcomplen = thistempl->buflen;
if (s->compress != NULL)
*/
if (!using_ktls
&& (!WPACKET_put_bytes_u8(thispkt, rectype)
- || !WPACKET_put_bytes_u16(thispkt, version)
+ || !WPACKET_put_bytes_u16(thispkt, thistempl->version)
|| !WPACKET_start_sub_packet_u16(thispkt)
|| (eivlen > 0
&& !WPACKET_allocate_bytes(thispkt, eivlen, NULL))
if (rl->nextwbuf == rl->numwpipes
&& (rl->mode & SSL_MODE_RELEASE_BUFFERS) != 0)
tls_release_write_buffer(rl);
-
return 1;
} else if (i <= 0) {
if (SSL_CONNECTION_IS_DTLS(s)) {
int i;
SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
OSSL_RECORD_TEMPLATE tmpls[SSL_MAX_PIPELINES];
+ unsigned int recversion;
if (s == NULL)
return -1;
return -1;
}
+ /*
+ * Some servers hang if initial client hello is larger than 256 bytes
+ * and record version number > TLS 1.0
+ */
+ /* TODO(RECLAYER): Does this also need to be in the DTLS equivalent code? */
+ recversion = (s->version == TLS1_3_VERSION) ? TLS1_2_VERSION : s->version;
+ if (SSL_get_state(ssl) == TLS_ST_CW_CLNT_HELLO
+ && !s->renegotiate
+ && TLS1_get_version(ssl) > TLS1_VERSION
+ && s->hello_retry_request == SSL_HRR_NONE)
+ recversion = TLS1_VERSION;
+
for (;;) {
size_t tmppipelen, remain;
size_t numpipes, j, lensofar = 0;
*/
for (j = 0; j < numpipes; j++) {
tmpls[j].type = type;
+ tmpls[j].version = recversion;
tmpls[j].buf = &(buf[tot]) + (j * max_send_fragment);
tmpls[j].buflen = max_send_fragment;
}
tmppipelen++;
for (j = 0; j < numpipes; j++) {
tmpls[j].type = type;
+ tmpls[j].version = recversion;
tmpls[j].buf = &(buf[tot]) + lensofar;
tmpls[j].buflen = tmppipelen;
lensofar += tmppipelen;
return ssl_post_record_layer_select(s, direction);
}
+
+int ssl_set_record_protocol_version(SSL_CONNECTION *s, int vers)
+{
+ if (!ossl_assert(s->rlayer.rrlmethod != NULL)
+ || !ossl_assert(s->rlayer.wrlmethod != NULL))
+ return 0;
+ s->rlayer.rrlmethod->set_protocol_version(s->rlayer.rrl, s->version);
+ s->rlayer.wrlmethod->set_protocol_version(s->rlayer.wrl, s->version);
+
+ return 1;
+}
const EVP_CIPHER *ciph, size_t taglen,
int mactype, const EVP_MD *md,
const SSL_COMP *comp);
+int ssl_set_record_protocol_version(SSL_CONNECTION *s, int vers);
# define OSSL_FUNC_RLAYER_SKIP_EARLY_DATA 1
OSSL_CORE_MAKE_FUNC(int, rlayer_skip_early_data, (void *cbarg))
*/
struct ossl_record_template_st {
int type;
+ unsigned int version;
const unsigned char *buf;
size_t buflen;
};
}
templ.type = SSL3_RT_ALERT;
+ templ.version = (sc->version == TLS1_3_VERSION) ? TLS1_2_VERSION
+ : sc->version;
+ if (SSL_get_state(s) == TLS_ST_CW_CLNT_HELLO
+ && !sc->renegotiate
+ && TLS1_get_version(s) > TLS1_VERSION
+ && sc->hello_retry_request == SSL_HRR_NONE) {
+ templ.version = TLS1_VERSION;
+ }
templ.buf = &sc->s3.send_alert[0];
templ.buflen = 2;
/* We just set it here. We validate it in ssl_choose_client_version */
s->version = version;
- s->rlayer.rrlmethod->set_protocol_version(s->rlayer.rrl, version);
+ if (!ssl_set_record_protocol_version(s, version)) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
return 1;
}
}
s->hello_retry_request = SSL_HRR_PENDING;
/* Tell the record layer that we know we're going to get TLSv1.3 */
- s->rlayer.rrlmethod->set_protocol_version(s->rlayer.rrl, s->version);
+ if (!ssl_set_record_protocol_version(s, s->version)) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
hrr = 1;
if (!PACKET_forward(pkt, SSL3_RANDOM_SIZE)) {
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH);
check_for_downgrade(s, best_vers, dgrd);
s->version = best_vers;
ssl->method = best_method;
- if (!s->rlayer.rrlmethod->set_protocol_version(s->rlayer.rrl,
- best_vers))
+ if (!ssl_set_record_protocol_version(s, best_vers))
return ERR_R_INTERNAL_ERROR;
return 0;
check_for_downgrade(s, vent->version, dgrd);
s->version = vent->version;
ssl->method = method;
- if (!s->rlayer.rrlmethod->set_protocol_version(s->rlayer.rrl,
- s->version))
+ if (!ssl_set_record_protocol_version(s, s->version))
return ERR_R_INTERNAL_ERROR;
return 0;
* versions they don't want. If not, then easy to fix, just return
* ssl_method_error(s, s->method)
*/
- if (!s->rlayer.rrlmethod->set_protocol_version(s->rlayer.rrl,
- s->version)) {
+ if (!ssl_set_record_protocol_version(s, s->version)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
continue;
ssl->method = vent->cmeth();
- if (!s->rlayer.rrlmethod->set_protocol_version(s->rlayer.rrl,
- s->version)) {
+ if (!ssl_set_record_protocol_version(s, s->version)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
* we read the ServerHello. So we need to tell the record layer
* about this immediately.
*/
- s->rlayer.rrlmethod->set_protocol_version(s->rlayer.rrl, ver_max);
+ if (!ssl_set_record_protocol_version(s, ver_max))
+ return 0;
}
} else if (ver_max > TLS1_2_VERSION) {
/* TLS1.3 always uses TLS1.2 in the legacy_version field */