},
};
+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_data(SSL *s, void *buf, size_t num, size_t *readbytes)
+{
+ int ret;
+
+ if (!s->server) {
+ SSLerr(SSL_F_SSL_READ_EARLY_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return SSL_READ_EARLY_DATA_ERROR;
+ }
+
+ switch (s->early_data_state) {
+ case SSL_EARLY_DATA_NONE:
+ if (!SSL_in_before(s)) {
+ SSLerr(SSL_F_SSL_READ_EARLY_DATA,
+ ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return SSL_READ_EARLY_DATA_ERROR;
+ }
+ /* fall through */
+
+ case SSL_EARLY_DATA_ACCEPT_RETRY:
+ s->early_data_state = SSL_EARLY_DATA_ACCEPTING;
+ ret = SSL_accept(s);
+ if (ret <= 0) {
+ /* NBIO or error */
+ s->early_data_state = SSL_EARLY_DATA_ACCEPT_RETRY;
+ return SSL_READ_EARLY_DATA_ERROR;
+ }
+ /* fall through */
+
+ case SSL_EARLY_DATA_READ_RETRY:
+ if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED) {
+ s->early_data_state = SSL_EARLY_DATA_READING;
+ ret = SSL_read_ex(s, buf, num, readbytes);
+ /*
+ * Record layer will call ssl_end_of_early_data_seen() if we see
+ * that alert - which updates the early_data_state to
+ * SSL_EARLY_DATA_FINISHED_READING
+ */
+ 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_DATA_SUCCESS
+ : SSL_READ_EARLY_DATA_ERROR;
+ }
+ } else {
+ s->early_data_state = SSL_EARLY_DATA_FINISHED_READING;
+ }
+ *readbytes = 0;
+ return SSL_READ_EARLY_DATA_FINISH;
+
+ default:
+ 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
+ || 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(const SSL *s)
+{
+ return s->ext.early_data;
+}
+
static int ssl_peek_internal(SSL *s, void *buf, size_t num, size_t *readbytes)
{
if (s->handshake_func == NULL) {
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;
ret->ext.status_type = TLSEXT_STATUSTYPE_nothing;
+ /*
+ * Default max early data is a fully loaded single record. Could be split
+ * across multiple records in practice
+ */
+ ret->max_early_data = SSL3_RT_MAX_PLAIN_LENGTH;
+
return ret;
err:
SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE);
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;
}