return 1;
}
+static void ssl_clear_error_state(SSL *s)
+{
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+ if (sc != NULL)
+ sc->statem.error_state = ERROR_STATE_NOERROR;
+ ERR_set_mark();
+}
+
+static void ssl_check_error_stack(SSL *s)
+{
+ SSL_CONNECTION *sc;
+ unsigned long l;
+ if (ERR_count_to_mark() > 0) {
+ sc = SSL_CONNECTION_FROM_SSL(s);
+ l = ERR_peek_error();
+ if (sc != NULL && l != 0) {
+ if (ERR_GET_LIB(l) == ERR_LIB_SYS)
+ sc->statem.error_state = ERROR_STATE_SYSCALL;
+ else
+ sc->statem.error_state = ERROR_STATE_SSL;
+ }
+ }
+ ERR_clear_last_mark();
+}
+
int SSL_accept(SSL *s)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ ssl_clear_error_state(s);
+
#ifndef OPENSSL_NO_QUIC
- if (IS_QUIC(s))
- return s->method->ssl_accept(s);
+ if (IS_QUIC(s)) {
+ int ret = s->method->ssl_accept(s);
+ ssl_check_error_stack(s);
+ return ret;
+ }
#endif
- if (sc == NULL)
+ if (sc == NULL) {
+ ERR_clear_last_mark();
return 0;
+ }
if (sc->handshake_func == NULL) {
/* Not properly initialized yet */
SSL_set_accept_state(s);
}
+ ssl_check_error_stack(s);
+
return SSL_do_handshake(s);
}
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ ssl_clear_error_state(s);
+
#ifndef OPENSSL_NO_QUIC
- if (IS_QUIC(s))
- return s->method->ssl_connect(s);
+ if (IS_QUIC(s)) {
+ int ret = s->method->ssl_connect(s);
+ ssl_check_error_stack(s);
+ return ret;
+ }
#endif
- if (sc == NULL)
+ if (sc == NULL) {
+ ERR_clear_last_mark();
return 0;
+ }
if (sc->handshake_func == NULL) {
/* Not properly initialized yet */
SSL_set_connect_state(s);
}
+ ssl_check_error_stack(s);
+
return SSL_do_handshake(s);
}
int ret;
size_t readbytes;
+ ssl_clear_error_state(s);
+
if (num < 0) {
ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH);
+ ssl_check_error_stack(s);
return -1;
}
if (ret > 0)
ret = (int)readbytes;
+ ssl_check_error_stack(s);
+
return ret;
}
int SSL_read_ex(SSL *s, void *buf, size_t num, size_t *readbytes)
{
- int ret = ssl_read_internal(s, buf, num, readbytes);
+ int ret;
+
+ ssl_clear_error_state(s);
+ ret = ssl_read_internal(s, buf, num, readbytes);
if (ret < 0)
ret = 0;
+
+ ssl_check_error_stack(s);
+
return ret;
}
int ret;
size_t readbytes;
+ ssl_clear_error_state(s);
+
if (num < 0) {
ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH);
+ ssl_check_error_stack(s);
return -1;
}
if (ret > 0)
ret = (int)readbytes;
+ ssl_check_error_stack(s);
+
return ret;
}
int SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *readbytes)
{
- int ret = ssl_peek_internal(s, buf, num, readbytes);
+ int ret;
+
+ ssl_clear_error_state(s);
+ ret = ssl_peek_internal(s, buf, num, readbytes);
if (ret < 0)
ret = 0;
+
+ ssl_check_error_stack(s);
+
return ret;
}
int ret;
size_t written;
+ ssl_clear_error_state(s);
+
if (num < 0) {
ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH);
+ ssl_check_error_stack(s);
return -1;
}
if (ret > 0)
ret = (int)written;
+ ssl_check_error_stack(s);
+
return ret;
}
int SSL_write_ex2(SSL *s, const void *buf, size_t num, uint64_t flags,
size_t *written)
{
- int ret = ssl_write_internal(s, buf, num, flags, written);
+ int ret;
+
+ ssl_clear_error_state(s);
+ ret = ssl_write_internal(s, buf, num, flags, written);
if (ret < 0)
ret = 0;
+
+ ssl_check_error_stack(s);
+
return ret;
}
* (see ssl3_shutdown).
*/
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ int ret;
+
+ ssl_clear_error_state(s);
#ifndef OPENSSL_NO_QUIC
- if (IS_QUIC(s))
- return ossl_quic_conn_shutdown(s, 0, NULL, 0);
+ if (IS_QUIC(s)) {
+ ret = ossl_quic_conn_shutdown(s, 0, NULL, 0);
+ goto end;
+ }
#endif
- if (sc == NULL)
- return -1;
+ if (sc == NULL) {
+ ret = -1;
+ goto end;
+ }
if (sc->handshake_func == NULL) {
ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED);
- return -1;
+ ret = -1;
+ goto end;
}
if (!SSL_in_init(s)) {
args.type = OTHERFUNC;
args.f.func_other = s->method->ssl_shutdown;
- return ssl_start_async_job(s, &args, ssl_io_intern);
+ ret = ssl_start_async_job(s, &args, ssl_io_intern);
} else {
- return s->method->ssl_shutdown(s);
+ ret = s->method->ssl_shutdown(s);
}
} else {
ERR_raise(ERR_LIB_SSL, SSL_R_SHUTDOWN_WHILE_IN_INIT);
- return -1;
+ ret = -1;
}
+
+end:
+ ssl_check_error_stack(s);
+ return ret;
}
int SSL_key_update(SSL *s, int updatetype)
int ossl_ssl_get_error(const SSL *s, int i, int check_err)
{
int reason;
- unsigned long l;
BIO *bio;
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
if (sc == NULL)
return SSL_ERROR_SSL;
- /*
- * Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
- * where we do encode the error
- */
- if (check_err && (l = ERR_peek_error()) != 0) {
- if (ERR_GET_LIB(l) == ERR_LIB_SYS)
- return SSL_ERROR_SYSCALL;
- else
+ if (check_err != 0) {
+ if (sc->statem.error_state == ERROR_STATE_SSL)
return SSL_ERROR_SSL;
+ if (sc->statem.error_state == ERROR_STATE_SYSCALL)
+ return SSL_ERROR_SYSCALL;
}
#ifndef OPENSSL_NO_QUIC
int ret = 1;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ ssl_clear_error_state(s);
+
#ifndef OPENSSL_NO_QUIC
- if (IS_QUIC(s))
- return ossl_quic_do_handshake(s);
+ if (IS_QUIC(s)) {
+ ret = ossl_quic_do_handshake(s);
+ goto end;
+ }
#endif
- if (sc == NULL)
- return -1;
+ if (sc == NULL) {
+ ret = -1;
+ goto end;
+ }
if (sc->handshake_func == NULL) {
ERR_raise(ERR_LIB_SSL, SSL_R_CONNECTION_TYPE_NOT_SET);
- return -1;
+ ret = -1;
+ goto end;
}
- if (!ossl_statem_check_finish_init(sc, -1))
- return -1;
+ if (!ossl_statem_check_finish_init(sc, -1)) {
+ ret = -1;
+ goto end;
+ }
s->method->ssl_renegotiate_check(s, 0);
}
}
+end:
+ ssl_check_error_stack(s);
return ret;
}