#ifndef OPENSSL_NO_ENGINE
# include <openssl/engine.h>
#endif
+#include <openssl/async.h>
const char SSL_version_str[] = OPENSSL_VERSION_TEXT;
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 */
s->psk_server_callback = ctx->psk_server_callback;
#endif
+ s->job = NULL;
+
return (s);
err:
SSL_free(s);
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)
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;
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)
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;
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)
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) &&
int ssl_undefined_const_function(const SSL *s)
{
- SSLerr(SSL_F_SSL_UNDEFINED_CONST_FUNCTION,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return (0);
}
{
ssl_clear_hash_ctx(hash);
*hash = EVP_MD_CTX_create();
- if (md)
- EVP_DigestInit_ex(*hash, md, NULL);
+ if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) {
+ EVP_MD_CTX_destroy(*hash);
+ *hash = NULL;
+ return NULL;
+ }
return *hash;
}