#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 */
return 0;
}
- s->type = 0;
-
- s->state = SSL_ST_BEFORE | ((s->server) ? SSL_ST_ACCEPT : SSL_ST_CONNECT);
+ ossl_statem_clear(s);
s->version = s->method->version;
s->client_version = s->version;
* Check to see if we were changed into a different method, if so, revert
* back if we are not doing session-id reuse.
*/
- if (!s->in_handshake && (s->session == NULL)
+ if (!ossl_statem_get_in_handshake(s) && (s->session == NULL)
&& (s->method != s->ctx->method)) {
s->method->ssl_free(s);
s->method = s->ctx->method;
s->generate_session_id = ctx->generate_session_id;
s->param = X509_VERIFY_PARAM_new();
- if (!s->param)
+ if (s->param == NULL)
goto err;
X509_VERIFY_PARAM_inherit(s->param, ctx->param);
s->quiet_shutdown = ctx->quiet_shutdown;
s->verify_result = X509_V_OK;
+ s->default_passwd_callback = ctx->default_passwd_callback;
+ s->default_passwd_callback_userdata = ctx->default_passwd_callback_userdata;
+
s->method = ctx->method;
if (!s->method->ssl_new(s))
s->psk_server_callback = ctx->psk_server_callback;
#endif
+ s->job = NULL;
+
return (s);
err:
SSL_free(s);
}
/*
- * what if we are setup as SSLv2 but want to talk SSLv3 or vice-versa
+ * what if we are setup for one protocol version but want to talk another
*/
if (t->method != f->method) {
t->method->ssl_free(t); /* cleanup current */
ssl->cert->key->privatekey));
}
+int SSL_waiting_for_async(SSL *s)
+{
+ if(s->job)
+ return 1;
+
+ return 0;
+}
+
+int SSL_get_async_wait_fd(SSL *s)
+{
+ if (!s->job)
+ return 0;
+
+ 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 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)
return -1;
}
- if ((s != NULL) && !SSL_in_init(s))
+ if (!SSL_in_init(s))
return (s->method->ssl_shutdown(s));
else
return (1);
return TLS_CIPHER_LEN;
}
case SSL_CTRL_GET_EXTMS_SUPPORT:
- if (!s->session || SSL_in_init(s) || s->in_handshake)
+ if (!s->session || SSL_in_init(s) || ossl_statem_get_in_handshake(s))
return -1;
if (s->session->flags & SSL_SESS_FLAG_EXTMS)
return 1;
int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b)
{
- long l;
-
- l = a->id - b->id;
- if (l == 0L)
- return (0);
- else
- return ((l > 0) ? 1 : -1);
+ if (a->id > b->id)
+ return 1;
+ if (a->id < b->id)
+ return -1;
+ return 0;
}
int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap,
const SSL_CIPHER *const *bp)
{
- long l;
-
- l = (*ap)->id - (*bp)->id;
- if (l == 0L)
- return (0);
- else
- return ((l > 0) ? 1 : -1);
+ if ((*ap)->id > (*bp)->id)
+ return 1;
+ if ((*ap)->id < (*bp)->id)
+ return -1;
+ return 0;
}
/** return a STACK of the ciphers available for the SSL and in order of
return 1;
}
-/* works well for SSLv2, not so good for SSLv3 */
char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len)
{
char *p;
{
OPENSSL_free(ctx->alpn_client_proto_list);
ctx->alpn_client_proto_list = OPENSSL_malloc(protos_len);
- if (!ctx->alpn_client_proto_list)
+ if (ctx->alpn_client_proto_list == NULL)
return 1;
memcpy(ctx->alpn_client_proto_list, protos, protos_len);
ctx->alpn_client_proto_list_len = protos_len;
{
OPENSSL_free(ssl->alpn_client_proto_list);
ssl->alpn_client_proto_list = OPENSSL_malloc(protos_len);
- if (!ssl->alpn_client_proto_list)
+ if (ssl->alpn_client_proto_list == NULL)
return 1;
memcpy(ssl->alpn_client_proto_list, protos, protos_len);
ssl->alpn_client_proto_list_len = protos_len;
}
ret->param = X509_VERIFY_PARAM_new();
- if (!ret->param)
+ if (ret->param == NULL)
goto err;
if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) {
ctx->default_passwd_callback_userdata = u;
}
+void SSL_set_default_passwd_cb(SSL *s, pem_password_cb *cb)
+{
+ s->default_passwd_callback = cb;
+}
+
+void SSL_set_default_passwd_cb_userdata(SSL *s, void *u)
+{
+ s->default_passwd_callback_userdata = u;
+}
+
void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
int (*cb) (X509_STORE_CTX *, void *),
void *arg)
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) &&
{
s->server = 1;
s->shutdown = 0;
- s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE;
+ ossl_statem_clear(s);
s->handshake_func = s->method->ssl_accept;
clear_ciphers(s);
}
{
s->server = 0;
s->shutdown = 0;
- s->state = SSL_ST_CONNECT | SSL_ST_BEFORE;
+ ossl_statem_clear(s);
s->handshake_func = s->method->ssl_connect;
clear_ciphers(s);
}
int ssl_undefined_const_function(const SSL *s)
{
- SSLerr(SSL_F_SSL_UNDEFINED_CONST_FUNCTION,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return (0);
}
return (NULL);
ret->version = s->version;
- ret->type = s->type;
ret->method = s->method;
if (s->session != NULL) {
ret->wbio = ret->rbio;
}
ret->rwstate = s->rwstate;
- ret->in_handshake = s->in_handshake;
ret->handshake_func = s->handshake_func;
ret->server = s->server;
ret->renegotiate = s->renegotiate;
ret->new_session = s->new_session;
ret->quiet_shutdown = s->quiet_shutdown;
ret->shutdown = s->shutdown;
- ret->state = s->state; /* SSL_dup does not really work at any state,
- * though */
+ ret->statem = s->statem; /* SSL_dup does not really work at any state,
+ * though */
RECORD_LAYER_dup(&ret->rlayer, &s->rlayer);
ret->init_num = 0; /* would have to copy ret->init_buf,
* ret->init_msg, ret->init_num,
* ret->init_off */
ret->hit = s->hit;
+ ret->default_passwd_callback = s->default_passwd_callback;
+ ret->default_passwd_callback_userdata = s->default_passwd_callback_userdata;
+
X509_VERIFY_PARAM_inherit(ret->param, s->param);
/* dup the cipher_list and cipher_list_by_id stacks */
return (ssl->ctx);
}
-#ifndef OPENSSL_NO_STDIO
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
{
return (X509_STORE_set_default_paths(ctx->cert_store));
{
return (X509_STORE_load_locations(ctx->cert_store, CAfile, CApath));
}
-#endif
void SSL_set_info_callback(SSL *ssl,
void (*cb) (const SSL *ssl, int type, int val))
return ssl->info_callback;
}
-int SSL_state(const SSL *ssl)
-{
- return (ssl->state);
-}
-
-void SSL_set_state(SSL *ssl, int state)
-{
- ssl->state = state;
-}
-
void SSL_set_verify_result(SSL *ssl, long arg)
{
ssl->verify_result = arg;
{
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;
}