{
/*
* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how
- * we can "construct" a session to give us the desired check - ie. to
+ * we can "construct" a session to give us the desired check - i.e. to
* find if there's a session in the hash table that would conflict with
* any new session built out of this id/id_len and the ssl_version in use
* by this SSL.
#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_NONE
- && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING
- && s->early_data_state != SSL_EARLY_DATA_FINISHED_READING
- && s->early_data_state != SSL_EARLY_DATA_READING) {
+ 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;
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;
}
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 */
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
+ * State machine will update early_data_state to
+ * SSL_EARLY_DATA_FINISHED_READING if we get an EndOfEarlyData
+ * message
*/
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;
- }
-}
-
-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_FINISHED_READING;
- ossl_statem_finish_early_data(s);
- return 1;
+ SSLerr(SSL_F_SSL_READ_EARLY_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return SSL_READ_EARLY_DATA_ERROR;
}
-
- return 0;
}
int SSL_get_early_data_status(const SSL *s)
return -1;
}
- if (s->early_data_state != SSL_EARLY_DATA_NONE
- && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING
- && s->early_data_state != SSL_EARLY_DATA_FINISHED_READING
- && s->early_data_state != SSL_EARLY_DATA_WRITING) {
+ 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;
- }
-
switch (s->early_data_state) {
case SSL_EARLY_DATA_NONE:
- if (!SSL_in_before(s)
+ if (s->server
+ || !SSL_in_before(s)
|| s->session == NULL
|| s->session->ext.max_early_data == 0) {
- 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;
}
/* fall through */
s->early_data_state = SSL_EARLY_DATA_WRITE_RETRY;
return ret;
- default:
- SSLerr(SSL_F_SSL_WRITE_EARLY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
-}
-
-int SSL_write_early_finish(SSL *s)
-{
- int ret;
-
- if (s->early_data_state != SSL_EARLY_DATA_WRITE_RETRY) {
- SSLerr(SSL_F_SSL_WRITE_EARLY_FINISH, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
+ case SSL_EARLY_DATA_FINISHED_READING:
+ 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;
- s->early_data_state = SSL_EARLY_DATA_WRITING;
- ret = ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_END_OF_EARLY_DATA);
- if (ret <= 0) {
- s->early_data_state = SSL_EARLY_DATA_WRITE_RETRY;
+ default:
+ SSLerr(SSL_F_SSL_WRITE_EARLY_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
- s->early_data_state = SSL_EARLY_DATA_FINISHED_WRITING;
- /*
- * We set the enc_write_ctx back to NULL because we may end up writing
- * in cleartext again if we get a HelloRetryRequest from the server.
- */
- EVP_CIPHER_CTX_free(s->enc_write_ctx);
- s->enc_write_ctx = NULL;
- ossl_statem_set_in_init(s, 1);
- return 1;
}
int SSL_shutdown(SSL *s)
}
/*
- * SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from
- * |ssl|. On return it sets |*data| to point to |*len| bytes of protocol name
+ * SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|.
+ * On return it sets |*data| to point to |*len| bytes of protocol name
* (not including the leading length-prefix byte). If the server didn't
* respond with a negotiated protocol then |*len| will be zero.
*/
}
if (SSL_want_write(s)) {
- /*
- * Access wbio directly - in order to use the buffered bio if
- * present
- */
+ /* Access wbio directly - in order to use the buffered bio if present */
bio = s->wbio;
if (BIO_should_write(bio))
return (SSL_ERROR_WANT_WRITE);
return -1;
}
- if (s->early_data_state != SSL_EARLY_DATA_NONE
- && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING
- && s->early_data_state != SSL_EARLY_DATA_FINISHED_READING
- && s->early_data_state != SSL_EARLY_DATA_ACCEPTING
- && s->early_data_state != SSL_EARLY_DATA_CONNECTING) {
- SSLerr(SSL_F_SSL_WRITE_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return 0;
- }
-
+ ossl_statem_check_finish_init(s, -1);
s->method->ssl_renegotiate_check(s, 0);
/*
* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
* variable, freeing EVP_MD_CTX previously stored in that variable, if any.
- * If EVP_MD pointer is passed, initializes ctx with this md.
+ * If EVP_MD pointer is passed, initializes ctx with this |md|.
* Returns the newly allocated ctx;
*/
return 1;
}
-uint32_t SSL_get_max_early_data(const SSL_CTX *s)
+uint32_t SSL_get_max_early_data(const SSL *s)
{
return s->max_early_data;
}