},
};
+static int ssl_write_early_finish(SSL *s);
+
static int dane_ctx_enable(struct dane_ctx_st *dctx)
{
const EVP_MD **mdevp;
#endif
OPENSSL_free(s->ext.ocsp.resp);
OPENSSL_free(s->ext.alpn);
+ OPENSSL_free(s->ext.tls13_cookie);
OPENSSL_free(s->clienthello);
sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
* data. That data may not result in any application data, or we may fail
* to parse the records for some reason.
*/
- if (SSL_pending(s))
+ if (RECORD_LAYER_processed_read_pending(&s->rlayer))
return 1;
return RECORD_LAYER_read_pending(&s->rlayer);
return 0;
}
+ if (s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY
+ || s->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY) {
+ SSLerr(SSL_F_SSL_READ_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ /*
+ * If we are a client and haven't received the ServerHello etc then we
+ * better do that
+ */
+ ossl_statem_check_finish_init(s, 0);
+
if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
struct ssl_async_args args;
int ret;
return ret;
}
-int SSL_read_early(SSL *s, void *buf, size_t num, size_t *readbytes)
+int SSL_read_early_data(SSL *s, void *buf, size_t num, size_t *readbytes)
{
int ret;
if (!s->server) {
- SSLerr(SSL_F_SSL_READ_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return SSL_READ_EARLY_ERROR;
+ SSLerr(SSL_F_SSL_READ_EARLY_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return SSL_READ_EARLY_DATA_ERROR;
}
- /*
- * TODO(TLS1.3): Somehow we need to check that we're not receiving too much
- * data
- */
-
switch (s->early_data_state) {
case SSL_EARLY_DATA_NONE:
if (!SSL_in_before(s)) {
- SSLerr(SSL_F_SSL_READ_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return SSL_READ_EARLY_ERROR;
+ SSLerr(SSL_F_SSL_READ_EARLY_DATA,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return SSL_READ_EARLY_DATA_ERROR;
}
/* fall through */
if (ret <= 0) {
/* NBIO or error */
s->early_data_state = SSL_EARLY_DATA_ACCEPT_RETRY;
- return SSL_READ_EARLY_ERROR;
+ return SSL_READ_EARLY_DATA_ERROR;
}
/* fall through */
if (ret > 0 || (ret <= 0 && s->early_data_state
!= SSL_EARLY_DATA_FINISHED_READING)) {
s->early_data_state = SSL_EARLY_DATA_READ_RETRY;
- return ret > 0 ? SSL_READ_EARLY_SUCCESS : SSL_READ_EARLY_ERROR;
+ return ret > 0 ? SSL_READ_EARLY_DATA_SUCCESS
+ : SSL_READ_EARLY_DATA_ERROR;
}
} else {
s->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
}
*readbytes = 0;
- ossl_statem_set_in_init(s, 1);
- return SSL_READ_EARLY_FINISH;
+ return SSL_READ_EARLY_DATA_FINISH;
default:
- SSLerr(SSL_F_SSL_READ_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return SSL_READ_EARLY_ERROR;
+ SSLerr(SSL_F_SSL_READ_EARLY_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return SSL_READ_EARLY_DATA_ERROR;
}
}
int ssl_end_of_early_data_seen(SSL *s)
{
- if (s->early_data_state == SSL_EARLY_DATA_READING) {
+ if (s->early_data_state == SSL_EARLY_DATA_READING
+ || s->early_data_state == SSL_EARLY_DATA_READ_RETRY) {
s->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
ossl_statem_finish_early_data(s);
return 1;
return 0;
}
-int SSL_get_early_data_status(SSL *s)
+int SSL_get_early_data_status(const SSL *s)
{
return s->ext.early_data;
}
return -1;
}
- if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY
- || s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY)
+ if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) {
+ /*
+ * We're still writing early data. We need to stop that so we can write
+ * normal data
+ */
+ if (!ssl_write_early_finish(s))
+ return 0;
+ } else if (s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY
+ || s->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY
+ || s->early_data_state == SSL_EARLY_DATA_READ_RETRY) {
+ SSLerr(SSL_F_SSL_WRITE_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
+ }
+ /* If we are a client and haven't sent the Finished we better do that */
+ ossl_statem_check_finish_init(s, 1);
if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
int ret;
return ret;
}
-int SSL_write_early(SSL *s, const void *buf, size_t num, size_t *written)
+int SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written)
{
int ret;
- if (s->server) {
- SSLerr(SSL_F_SSL_WRITE_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
-
- /*
- * TODO(TLS1.3): Somehow we need to check that we're not sending too much
- * data
- */
-
switch (s->early_data_state) {
case SSL_EARLY_DATA_NONE:
- if (!SSL_in_before(s)) {
- SSLerr(SSL_F_SSL_WRITE_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ if (s->server
+ || !SSL_in_before(s)
+ || s->session == NULL
+ || s->session->ext.max_early_data == 0) {
+ SSLerr(SSL_F_SSL_WRITE_EARLY_DATA,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
/* fall through */
s->early_data_state = SSL_EARLY_DATA_WRITE_RETRY;
return ret;
+ case SSL_EARLY_DATA_READ_RETRY:
+ /* We are a server writing to an unauthenticated client */
+ s->early_data_state = SSL_EARLY_DATA_UNAUTH_WRITING;
+ ret = SSL_write_ex(s, buf, num, written);
+ s->early_data_state = SSL_EARLY_DATA_READ_RETRY;
+ return ret;
+
default:
- SSLerr(SSL_F_SSL_WRITE_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ SSLerr(SSL_F_SSL_WRITE_EARLY_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
}
-int SSL_write_early_finish(SSL *s)
+static int ssl_write_early_finish(SSL *s)
{
int ret;
return -1;
}
- if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY
- || s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY)
- return -1;
+ if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) {
+ int edfin;
+
+ edfin = ssl_write_early_finish(s);
+ if (edfin <= 0)
+ return edfin;
+ }
+ ossl_statem_check_finish_init(s, -1);
s->method->ssl_renegotiate_check(s, 0);
return 1;
}
-uint32_t SSL_CTX_get_max_early_data(SSL_CTX *ctx)
+uint32_t SSL_CTX_get_max_early_data(const SSL_CTX *ctx)
{
return ctx->max_early_data;
}
return 1;
}
-uint32_t SSL_get_max_early_data(SSL_CTX *s)
+uint32_t SSL_get_max_early_data(const SSL_CTX *s)
{
return s->max_early_data;
}