Clean up libssl async calls
Tidy up the libssl async calls and make sure all IO functions are covered. Reviewed-by: Rich Salz <rsalz@openssl.org>
This commit is contained in:
parent
c742f56e94
commit
add2f5ca6d
@ -2139,6 +2139,7 @@ void ERR_load_SSL_strings(void);
|
|||||||
# define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206
|
# define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206
|
||||||
# define SSL_F_SSL_VERIFY_CERT_CHAIN 207
|
# define SSL_F_SSL_VERIFY_CERT_CHAIN 207
|
||||||
# define SSL_F_SSL_WRITE 208
|
# define SSL_F_SSL_WRITE 208
|
||||||
|
# define SSL_F_START_ASYNC_JOB 388
|
||||||
# define SSL_F_STATE_MACHINE 353
|
# define SSL_F_STATE_MACHINE 353
|
||||||
# define SSL_F_TLS12_CHECK_PEER_SIGALG 333
|
# define SSL_F_TLS12_CHECK_PEER_SIGALG 333
|
||||||
# define SSL_F_TLS1_CERT_VERIFY_MAC 286
|
# define SSL_F_TLS1_CERT_VERIFY_MAC 286
|
||||||
|
@ -335,6 +335,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
|
|||||||
"SSL_use_RSAPrivateKey_file"},
|
"SSL_use_RSAPrivateKey_file"},
|
||||||
{ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "ssl_verify_cert_chain"},
|
{ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "ssl_verify_cert_chain"},
|
||||||
{ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"},
|
{ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"},
|
||||||
|
{ERR_FUNC(SSL_F_START_ASYNC_JOB), "START_ASYNC_JOB"},
|
||||||
{ERR_FUNC(SSL_F_STATE_MACHINE), "STATE_MACHINE"},
|
{ERR_FUNC(SSL_F_STATE_MACHINE), "STATE_MACHINE"},
|
||||||
{ERR_FUNC(SSL_F_TLS12_CHECK_PEER_SIGALG), "tls12_check_peer_sigalg"},
|
{ERR_FUNC(SSL_F_TLS12_CHECK_PEER_SIGALG), "tls12_check_peer_sigalg"},
|
||||||
{ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC), "tls1_cert_verify_mac"},
|
{ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC), "tls1_cert_verify_mac"},
|
||||||
|
202
ssl/ssl_lib.c
202
ssl/ssl_lib.c
@ -191,6 +191,11 @@ struct ssl_async_args {
|
|||||||
SSL *s;
|
SSL *s;
|
||||||
void *buf;
|
void *buf;
|
||||||
int num;
|
int num;
|
||||||
|
int type;
|
||||||
|
union {
|
||||||
|
int (*func1)(SSL *, void *, int);
|
||||||
|
int (*func2)(SSL *, const void *, int);
|
||||||
|
} f;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void clear_ciphers(SSL *s)
|
static void clear_ciphers(SSL *s)
|
||||||
@ -939,56 +944,24 @@ int SSL_get_async_wait_fd(SSL *s)
|
|||||||
return ASYNC_get_wait_fd(s->job);
|
return ASYNC_get_wait_fd(s->job);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ssl_accept_intern(void *vargs)
|
|
||||||
{
|
|
||||||
struct ssl_async_args *args;
|
|
||||||
SSL *s;
|
|
||||||
|
|
||||||
args = (struct ssl_async_args *)vargs;
|
|
||||||
s = args->s;
|
|
||||||
|
|
||||||
return s->method->ssl_accept(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
int SSL_accept(SSL *s)
|
int SSL_accept(SSL *s)
|
||||||
{
|
{
|
||||||
int ret;
|
if (s->handshake_func == 0) {
|
||||||
struct ssl_async_args args;
|
|
||||||
|
|
||||||
if (s->handshake_func == 0)
|
|
||||||
/* Not properly initialized yet */
|
/* Not properly initialized yet */
|
||||||
SSL_set_accept_state(s);
|
SSL_set_accept_state(s);
|
||||||
|
|
||||||
args.s = s;
|
|
||||||
|
|
||||||
if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
|
|
||||||
switch(ASYNC_start_job(&s->job, &ret, ssl_accept_intern, &args,
|
|
||||||
sizeof(struct ssl_async_args))) {
|
|
||||||
case ASYNC_ERR:
|
|
||||||
SSLerr(SSL_F_SSL_ACCEPT, SSL_R_FAILED_TO_INIT_ASYNC);
|
|
||||||
return -1;
|
|
||||||
case ASYNC_PAUSE:
|
|
||||||
return -1;
|
|
||||||
case ASYNC_FINISH:
|
|
||||||
s->job = NULL;
|
|
||||||
return ret;
|
|
||||||
default:
|
|
||||||
SSLerr(SSL_F_SSL_ACCEPT, ERR_R_INTERNAL_ERROR);
|
|
||||||
/* Shouldn't happen */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return s->method->ssl_accept(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return SSL_do_handshake(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SSL_connect(SSL *s)
|
int SSL_connect(SSL *s)
|
||||||
{
|
{
|
||||||
if (s->handshake_func == 0)
|
if (s->handshake_func == 0) {
|
||||||
/* Not properly initialized yet */
|
/* Not properly initialized yet */
|
||||||
SSL_set_connect_state(s);
|
SSL_set_connect_state(s);
|
||||||
|
}
|
||||||
|
|
||||||
return (s->method->ssl_connect(s));
|
return SSL_do_handshake(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
long SSL_get_default_timeout(const SSL *s)
|
long SSL_get_default_timeout(const SSL *s)
|
||||||
@ -996,8 +969,30 @@ long SSL_get_default_timeout(const SSL *s)
|
|||||||
return (s->method->get_timeout());
|
return (s->method->get_timeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int start_async_job(SSL *s, struct ssl_async_args *args,
|
||||||
|
int (*func)(void *)) {
|
||||||
|
int ret;
|
||||||
|
switch(ASYNC_start_job(&s->job, &ret, func, args,
|
||||||
|
sizeof(struct ssl_async_args))) {
|
||||||
|
case ASYNC_ERR:
|
||||||
|
s->rwstate = SSL_NOTHING;
|
||||||
|
SSLerr(SSL_F_START_ASYNC_JOB, SSL_R_FAILED_TO_INIT_ASYNC);
|
||||||
|
return -1;
|
||||||
|
case ASYNC_PAUSE:
|
||||||
|
s->rwstate = SSL_ASYNC_PAUSED;
|
||||||
|
return -1;
|
||||||
|
case ASYNC_FINISH:
|
||||||
|
s->job = NULL;
|
||||||
|
return ret;
|
||||||
|
default:
|
||||||
|
s->rwstate = SSL_NOTHING;
|
||||||
|
SSLerr(SSL_F_START_ASYNC_JOB, ERR_R_INTERNAL_ERROR);
|
||||||
|
/* Shouldn't happen */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int ssl_read_intern(void *vargs)
|
static int ssl_io_intern(void *vargs)
|
||||||
{
|
{
|
||||||
struct ssl_async_args *args;
|
struct ssl_async_args *args;
|
||||||
SSL *s;
|
SSL *s;
|
||||||
@ -1008,15 +1003,14 @@ static int ssl_read_intern(void *vargs)
|
|||||||
s = args->s;
|
s = args->s;
|
||||||
buf = args->buf;
|
buf = args->buf;
|
||||||
num = args->num;
|
num = args->num;
|
||||||
|
if (args->type == 1)
|
||||||
return s->method->ssl_read(s, buf, num);
|
return args->f.func1(s, buf, num);
|
||||||
|
else
|
||||||
|
return args->f.func2(s, buf, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SSL_read(SSL *s, void *buf, int num)
|
int SSL_read(SSL *s, void *buf, int num)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
struct ssl_async_args args;
|
|
||||||
|
|
||||||
if (s->handshake_func == 0) {
|
if (s->handshake_func == 0) {
|
||||||
SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED);
|
SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED);
|
||||||
return -1;
|
return -1;
|
||||||
@ -1027,29 +1021,16 @@ int SSL_read(SSL *s, void *buf, int num)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
args.s = s;
|
|
||||||
args.buf = buf;
|
|
||||||
args.num = num;
|
|
||||||
|
|
||||||
if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
|
if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
|
||||||
switch(ASYNC_start_job(&s->job, &ret, ssl_read_intern, &args,
|
struct ssl_async_args args;
|
||||||
sizeof(struct ssl_async_args))) {
|
|
||||||
case ASYNC_ERR:
|
args.s = s;
|
||||||
s->rwstate = SSL_NOTHING;
|
args.buf = buf;
|
||||||
SSLerr(SSL_F_SSL_READ, SSL_R_FAILED_TO_INIT_ASYNC);
|
args.num = num;
|
||||||
return -1;
|
args.type = 1;
|
||||||
case ASYNC_PAUSE:
|
args.f.func1 = s->method->ssl_read;
|
||||||
s->rwstate = SSL_ASYNC_PAUSED;
|
|
||||||
return -1;
|
return start_async_job(s, &args, ssl_io_intern);
|
||||||
case ASYNC_FINISH:
|
|
||||||
s->job = NULL;
|
|
||||||
return ret;
|
|
||||||
default:
|
|
||||||
s->rwstate = SSL_NOTHING;
|
|
||||||
SSLerr(SSL_F_SSL_READ, ERR_R_INTERNAL_ERROR);
|
|
||||||
/* Shouldn't happen */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return s->method->ssl_read(s, buf, num);
|
return s->method->ssl_read(s, buf, num);
|
||||||
}
|
}
|
||||||
@ -1065,30 +1046,23 @@ int SSL_peek(SSL *s, void *buf, int num)
|
|||||||
if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
|
if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
return (s->method->ssl_peek(s, buf, num));
|
if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
|
||||||
|
struct ssl_async_args args;
|
||||||
|
|
||||||
|
args.s = s;
|
||||||
|
args.buf = buf;
|
||||||
|
args.num = num;
|
||||||
|
args.type = 1;
|
||||||
|
args.f.func1 = s->method->ssl_peek;
|
||||||
|
|
||||||
|
return start_async_job(s, &args, ssl_io_intern);
|
||||||
|
} else {
|
||||||
|
return s->method->ssl_peek(s, buf, num);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ssl_write_intern(void *vargs)
|
|
||||||
{
|
|
||||||
struct ssl_async_args *args;
|
|
||||||
SSL *s;
|
|
||||||
const void *buf;
|
|
||||||
int num;
|
|
||||||
|
|
||||||
args = (struct ssl_async_args *)vargs;
|
|
||||||
s = args->s;
|
|
||||||
buf = args->buf;
|
|
||||||
num = args->num;
|
|
||||||
|
|
||||||
return s->method->ssl_write(s, buf, num);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int SSL_write(SSL *s, const void *buf, int num)
|
int SSL_write(SSL *s, const void *buf, int num)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
struct ssl_async_args args;
|
|
||||||
|
|
||||||
if (s->handshake_func == 0) {
|
if (s->handshake_func == 0) {
|
||||||
SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED);
|
SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED);
|
||||||
return -1;
|
return -1;
|
||||||
@ -1100,29 +1074,16 @@ int SSL_write(SSL *s, const void *buf, int num)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
args.s = s;
|
|
||||||
args.buf = (void *) buf;
|
|
||||||
args.num = num;
|
|
||||||
|
|
||||||
if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
|
if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
|
||||||
switch(ASYNC_start_job(&s->job, &ret, ssl_write_intern, &args,
|
struct ssl_async_args args;
|
||||||
sizeof(struct ssl_async_args))) {
|
|
||||||
case ASYNC_ERR:
|
args.s = s;
|
||||||
s->rwstate = SSL_NOTHING;
|
args.buf = (void *)buf;
|
||||||
SSLerr(SSL_F_SSL_WRITE, SSL_R_FAILED_TO_INIT_ASYNC);
|
args.num = num;
|
||||||
return -1;
|
args.type = 2;
|
||||||
case ASYNC_PAUSE:
|
args.f.func2 = s->method->ssl_write;
|
||||||
s->rwstate = SSL_ASYNC_PAUSED;
|
|
||||||
return -1;
|
return start_async_job(s, &args, ssl_io_intern);
|
||||||
case ASYNC_FINISH:
|
|
||||||
s->job = NULL;
|
|
||||||
return ret;
|
|
||||||
default:
|
|
||||||
s->rwstate = SSL_NOTHING;
|
|
||||||
SSLerr(SSL_F_SSL_WRITE, ERR_R_INTERNAL_ERROR);
|
|
||||||
/* Shouldn't happen */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return s->method->ssl_write(s, buf, num);
|
return s->method->ssl_write(s, buf, num);
|
||||||
}
|
}
|
||||||
@ -2534,21 +2495,40 @@ int SSL_get_error(const SSL *s, int i)
|
|||||||
return (SSL_ERROR_SYSCALL);
|
return (SSL_ERROR_SYSCALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ssl_do_handshake_intern(void *vargs)
|
||||||
|
{
|
||||||
|
struct ssl_async_args *args;
|
||||||
|
SSL *s;
|
||||||
|
|
||||||
|
args = (struct ssl_async_args *)vargs;
|
||||||
|
s = args->s;
|
||||||
|
|
||||||
|
return s->handshake_func(s);
|
||||||
|
}
|
||||||
|
|
||||||
int SSL_do_handshake(SSL *s)
|
int SSL_do_handshake(SSL *s)
|
||||||
{
|
{
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
|
||||||
if (s->handshake_func == NULL) {
|
if (s->handshake_func == NULL) {
|
||||||
SSLerr(SSL_F_SSL_DO_HANDSHAKE, SSL_R_CONNECTION_TYPE_NOT_SET);
|
SSLerr(SSL_F_SSL_DO_HANDSHAKE, SSL_R_CONNECTION_TYPE_NOT_SET);
|
||||||
return (-1);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->method->ssl_renegotiate_check(s);
|
s->method->ssl_renegotiate_check(s);
|
||||||
|
|
||||||
if (SSL_in_init(s) || SSL_in_before(s)) {
|
if (SSL_in_init(s) || SSL_in_before(s)) {
|
||||||
ret = s->handshake_func(s);
|
if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
|
||||||
|
struct ssl_async_args args;
|
||||||
|
|
||||||
|
args.s = s;
|
||||||
|
|
||||||
|
ret = start_async_job(s, &args, ssl_do_handshake_intern);
|
||||||
|
} else {
|
||||||
|
ret = s->handshake_func(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (ret);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSL_set_accept_state(SSL *s)
|
void SSL_set_accept_state(SSL *s)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user