Commit 07bbc92c authored by Matt Caswell's avatar Matt Caswell
Browse files

Make libssl async aware



The following entry points have been made async aware:
SSL_accept
SSL_read
SSL_write

Also added is a new mode - SSL_MODE_ASYNC. Calling the above functions with
the async mode enabled will initiate a new async job. If an async pause is
encountered whilst executing the job (such as for example if using SHA1/RSA
with the Dummy Async engine), then the above functions return with
SSL_WANT_ASYNC. Calling the functions again (with exactly the same args
as per non-blocking IO), will resume the job where it left off.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
parent a14e9ff7
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -70,7 +70,8 @@ ct_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
ct_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
ct_err.o: ../../include/openssl/symhacks.h ../include/internal/ct_int.h
ct_err.o: ct_err.c
ct_lib.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
ct_lib.o: ../../e_os.h ../../include/openssl/asn1.h
ct_lib.o: ../../include/openssl/async.h ../../include/openssl/bio.h
ct_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
ct_lib.o: ../../include/openssl/comp.h ../../include/openssl/crypto.h
ct_lib.o: ../../include/openssl/dsa.h ../../include/openssl/dtls1.h
+14 −4
Original line number Diff line number Diff line
@@ -490,6 +490,10 @@ typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type,
 * draft-ietf-tls-downgrade-scsv-00.
 */
# define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080U
/*
 * Support Asynchronous operation
 */
# define SSL_MODE_ASYNC 0x00000100U

/* Cert related flags */
/*
@@ -878,12 +882,14 @@ __owur int SSL_extension_supported(unsigned int ext_type);
# define SSL_WRITING            2
# define SSL_READING            3
# define SSL_X509_LOOKUP        4
# define SSL_ASYNC_PAUSED       5

/* These will only be used when doing non-blocking IO */
# define SSL_want_nothing(s)     (SSL_want(s) == SSL_NOTHING)
# define SSL_want_read(s)        (SSL_want(s) == SSL_READING)
# define SSL_want_write(s)       (SSL_want(s) == SSL_WRITING)
# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
# define SSL_want_async(s)       (SSL_want(s) == SSL_ASYNC_PAUSED)

# define SSL_MAC_FLAG_READ_MAC_STREAM 1
# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
@@ -1102,6 +1108,7 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
# define SSL_ERROR_ZERO_RETURN           6
# define SSL_ERROR_WANT_CONNECT          7
# define SSL_ERROR_WANT_ACCEPT           8
# define SSL_ERROR_WANT_ASYNC            9
# define SSL_CTRL_NEED_TMP_RSA                   1
# define SSL_CTRL_SET_TMP_RSA                    2
# define SSL_CTRL_SET_TMP_DH                     3
@@ -1564,6 +1571,7 @@ __owur char *SSL_get_srp_userinfo(SSL *s);

void SSL_certs_clear(SSL *s);
void SSL_free(SSL *ssl);
__owur int SSL_waiting_for_async(SSL *s);
__owur int SSL_accept(SSL *ssl);
__owur int SSL_connect(SSL *ssl);
__owur int SSL_read(SSL *ssl, void *buf, int num);
@@ -2024,6 +2032,7 @@ void ERR_load_SSL_strings(void);
# define SSL_F_SSL3_SETUP_WRITE_BUFFER                    291
# define SSL_F_SSL3_WRITE_BYTES                           158
# define SSL_F_SSL3_WRITE_PENDING                         159
# define SSL_F_SSL_ACCEPT                                 351
# define SSL_F_SSL_ADD_CERT_CHAIN                         316
# define SSL_F_SSL_ADD_CERT_TO_BUF                        319
# define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT        298
@@ -2266,6 +2275,7 @@ void ERR_load_SSL_strings(void);
# define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST              151
# define SSL_R_EXCESSIVE_MESSAGE_SIZE                     152
# define SSL_R_EXTRA_DATA_IN_MESSAGE                      153
# define SSL_R_FAILED_TO_INIT_ASYNC                       405
# define SSL_R_FRAGMENTED_CLIENT_HELLO                    401
# define SSL_R_GOT_A_FIN_BEFORE_A_CCS                     154
# define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS                355
+645 −632

File changed.

Preview size limit exceeded, changes collapsed.

+2 −0
Original line number Diff line number Diff line
@@ -190,6 +190,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
    {ERR_FUNC(SSL_F_SSL3_SETUP_WRITE_BUFFER), "ssl3_setup_write_buffer"},
    {ERR_FUNC(SSL_F_SSL3_WRITE_BYTES), "ssl3_write_bytes"},
    {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "ssl3_write_pending"},
    {ERR_FUNC(SSL_F_SSL_ACCEPT), "SSL_accept"},
    {ERR_FUNC(SSL_F_SSL_ADD_CERT_CHAIN), "ssl_add_cert_chain"},
    {ERR_FUNC(SSL_F_SSL_ADD_CERT_TO_BUF), "ssl_add_cert_to_buf"},
    {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT),
@@ -521,6 +522,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
     "error in received cipher list"},
    {ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE), "excessive message size"},
    {ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE), "extra data in message"},
    {ERR_REASON(SSL_R_FAILED_TO_INIT_ASYNC), "failed to init async"},
    {ERR_REASON(SSL_R_FRAGMENTED_CLIENT_HELLO), "fragmented client hello"},
    {ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS), "got a fin before a ccs"},
    {ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS),
+147 −5
Original line number Diff line number Diff line
@@ -158,6 +158,7 @@
#ifndef OPENSSL_NO_ENGINE
# include <openssl/engine.h>
#endif
#include <openssl/async.h>

const char SSL_version_str[] = OPENSSL_VERSION_TEXT;

@@ -186,6 +187,12 @@ SSL3_ENC_METHOD ssl3_undef_enc_method = {
             int use_context))ssl_undefined_function,
};

struct ssl_async_args {
    SSL *s;
    void *buf;
    int num;
};

static void clear_ciphers(SSL *s)
{
    /* clear the current cipher */
@@ -386,6 +393,8 @@ SSL *SSL_new(SSL_CTX *ctx)
    s->psk_server_callback = ctx->psk_server_callback;
#endif

    s->job = NULL;

    return (s);
 err:
    SSL_free(s);
@@ -914,13 +923,55 @@ int SSL_check_private_key(const SSL *ssl)
                                   ssl->cert->key->privatekey));
}

int SSL_waiting_for_async(SSL *s)
{
    if(s->job) {
        return ASYNC_job_is_waiting(s->job);
    }
    return 0;
}

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 ret;
    struct ssl_async_args args;

    if (s->handshake_func == 0)
        /* Not properly initialized yet */
        SSL_set_accept_state(s);

    return (s->method->ssl_accept(s));
    args.s = s;

    if((s->mode & SSL_MODE_ASYNC) && !ASYNC_in_job()) {
        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);
    }
}

int SSL_connect(SSL *s)
@@ -937,8 +988,27 @@ long SSL_get_default_timeout(const SSL *s)
    return (s->method->get_timeout());
}


static int ssl_read_intern(void *vargs)
{
    struct ssl_async_args *args;
    SSL *s;
    void *buf;
    int num;

    args = (struct ssl_async_args *)vargs;
    s = args->s;
    buf = args->buf;
    num = args->num;

    return s->method->ssl_read(s, buf, num);
}

int SSL_read(SSL *s, void *buf, int num)
{
    int ret;
    struct ssl_async_args args;

    if (s->handshake_func == 0) {
        SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED);
        return -1;
@@ -948,7 +1018,33 @@ int SSL_read(SSL *s, void *buf, int num)
        s->rwstate = SSL_NOTHING;
        return (0);
    }
    return (s->method->ssl_read(s, buf, num));

    args.s = s;
    args.buf = buf;
    args.num = num;

    if((s->mode & SSL_MODE_ASYNC) && !ASYNC_in_job()) {
        switch(ASYNC_start_job(&s->job, &ret, ssl_read_intern, &args,
            sizeof(struct ssl_async_args))) {
        case ASYNC_ERR:
            s->rwstate = SSL_NOTHING;
            SSLerr(SSL_F_SSL_READ, 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_SSL_READ, ERR_R_INTERNAL_ERROR);
            /* Shouldn't happen */
            return -1;
        }
    } else {
        return s->method->ssl_read(s, buf, num);
    }
}

int SSL_peek(SSL *s, void *buf, int num)
@@ -964,8 +1060,27 @@ int SSL_peek(SSL *s, void *buf, int num)
    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 ret;
    struct ssl_async_args args;

    if (s->handshake_func == 0) {
        SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED);
        return -1;
@@ -976,7 +1091,33 @@ int SSL_write(SSL *s, const void *buf, int num)
        SSLerr(SSL_F_SSL_WRITE, SSL_R_PROTOCOL_IS_SHUTDOWN);
        return (-1);
    }
    return (s->method->ssl_write(s, buf, num));

    args.s = s;
    args.buf = (void *) buf;
    args.num = num;

    if((s->mode & SSL_MODE_ASYNC) && !ASYNC_in_job()) {
        switch(ASYNC_start_job(&s->job, &ret, ssl_write_intern, &args,
            sizeof(struct ssl_async_args))) {
        case ASYNC_ERR:
            s->rwstate = SSL_NOTHING;
            SSLerr(SSL_F_SSL_WRITE, 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_SSL_WRITE, ERR_R_INTERNAL_ERROR);
            /* Shouldn't happen */
            return -1;
        }
    } else {
        return s->method->ssl_write(s, buf, num);
    }
}

int SSL_shutdown(SSL *s)
@@ -2373,6 +2514,9 @@ int SSL_get_error(const SSL *s, int i)
    if ((i < 0) && SSL_want_x509_lookup(s)) {
        return (SSL_ERROR_WANT_X509_LOOKUP);
    }
    if ((i < 0) && SSL_want_async(s)) {
        return SSL_ERROR_WANT_ASYNC;
    }

    if (i == 0) {
        if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) &&
@@ -2432,8 +2576,6 @@ int ssl_undefined_void_function(void)

int ssl_undefined_const_function(const SSL *s)
{
    SSLerr(SSL_F_SSL_UNDEFINED_CONST_FUNCTION,
           ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return (0);
}

Loading