X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=ssl%2Fssl_lib.c;h=63a1a891f265ae81f07189a2dbdbbdb006604962;hb=07bbc92ccb96d48044220d2ed2cf818323baeb26;hp=e794d820585bb11b7d1f3bd065d41b9192ed0a38;hpb=0e04674e964b905e67e3d215bcf888932c92765f;p=openssl.git diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index e794d82058..63a1a891f2 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -158,6 +158,7 @@ #ifndef OPENSSL_NO_ENGINE # include #endif +#include 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 */ @@ -215,9 +222,7 @@ int SSL_clear(SSL *s) 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; @@ -232,7 +237,7 @@ int SSL_clear(SSL *s) * 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; @@ -313,7 +318,7 @@ SSL *SSL_new(SSL_CTX *ctx) 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; @@ -368,6 +373,9 @@ SSL *SSL_new(SSL_CTX *ctx) 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)) @@ -385,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); @@ -858,7 +868,7 @@ int SSL_copy_session_id(SSL *t, const SSL *f) } /* - * 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 */ @@ -913,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) @@ -936,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; @@ -947,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) @@ -963,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; @@ -975,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) @@ -992,7 +1134,7 @@ 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); @@ -1078,10 +1220,11 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) return 0; *(unsigned char **)parg = s->s3->tmp.ciphers_raw; return (int)s->s3->tmp.ciphers_rawlen; - } else - return ssl_put_cipher_by_char(s, NULL, NULL); + } else { + 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; @@ -1225,25 +1368,21 @@ long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) 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 @@ -1362,7 +1501,6 @@ int SSL_set_cipher_list(SSL *s, const char *str) 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; @@ -1553,7 +1691,7 @@ int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, { 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; @@ -1571,7 +1709,7 @@ int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, { 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; @@ -1714,7 +1852,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) } ret->param = X509_VERIFY_PARAM_new(); - if (!ret->param) + if (ret->param == NULL) goto err; if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) { @@ -1852,6 +1990,16 @@ void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) 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) @@ -2366,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) && @@ -2396,7 +2547,7 @@ void SSL_set_accept_state(SSL *s) { 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); } @@ -2405,7 +2556,7 @@ void SSL_set_connect_state(SSL *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); } @@ -2425,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); } @@ -2467,7 +2616,6 @@ SSL *SSL_dup(SSL *s) return (NULL); ret->version = s->version; - ret->type = s->type; ret->method = s->method; if (s->session != NULL) { @@ -2528,21 +2676,23 @@ SSL *SSL_dup(SSL *s) 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 */ @@ -2780,18 +2930,47 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) 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)); } +int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx) +{ + X509_LOOKUP *lookup; + + lookup = X509_STORE_add_lookup(ctx->cert_store, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + return 0; + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + + /* Clear any errors if the default directory does not exist */ + ERR_clear_error(); + + return 1; +} + +int SSL_CTX_set_default_verify_file(SSL_CTX *ctx) +{ + X509_LOOKUP *lookup; + + lookup = X509_STORE_add_lookup(ctx->cert_store, X509_LOOKUP_file()); + if (lookup == NULL) + return 0; + + X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + + /* Clear any errors if the default file does not exist */ + ERR_clear_error(); + + return 1; +} + int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath) { 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)) @@ -2809,16 +2988,6 @@ void (*SSL_get_info_callback(const SSL *ssl)) (const SSL * /* ssl */ , 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; @@ -3138,8 +3307,11 @@ EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md) { 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; }