X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_lib.c;h=a038b99cd14a31bf19853c7f810ef049d052483b;hp=bcb6be133a755d63a4dee50a4a13786639cf1c59;hb=ab97b2cd4301074fd88fd2f13b8c79342593dae4;hpb=156a872233b56558c72561789b8f33ff71a88fa7 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index bcb6be133a..a038b99cd1 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -189,6 +189,9 @@ SSL3_ENC_METHOD ssl3_undef_enc_method = { int SSL_clear(SSL *s) { + unsigned char *rp, *wp; + size_t rlen, wlen; + int read_ahead; if (s->method == NULL) { SSLerr(SSL_F_SSL_CLEAR, SSL_R_NO_METHOD_SPECIFIED); @@ -204,23 +207,10 @@ int SSL_clear(SSL *s) s->hit = 0; s->shutdown = 0; -#if 0 - /* - * Disabled since version 1.10 of this file (early return not - * needed because SSL_clear is not called when doing renegotiation) - */ - /* - * This is set if we are doing dynamic renegotiation so keep - * the old cipher. It is sort of a SSL_clear_lite :-) - */ - if (s->renegotiate) - return (1); -#else if (s->renegotiate) { SSLerr(SSL_F_SSL_CLEAR, ERR_R_INTERNAL_ERROR); return 0; } -#endif s->type = 0; @@ -230,9 +220,6 @@ int SSL_clear(SSL *s) s->client_version = s->version; s->rwstate = SSL_NOTHING; s->rstate = SSL_ST_READ_HEADER; -#if 0 - s->read_ahead = s->ctx->read_ahead; -#endif if (s->init_buf != NULL) { BUF_MEM_free(s->init_buf); @@ -245,7 +232,6 @@ int SSL_clear(SSL *s) s->first_packet = 0; -#if 1 /* * Check to see if we were changed into a different method, if so, revert * back if we are not doing session-id reuse. @@ -257,8 +243,26 @@ int SSL_clear(SSL *s) if (!s->method->ssl_new(s)) return (0); } else -#endif s->method->ssl_clear(s); + + read_ahead = RECORD_LAYER_get_read_ahead(&s->rlayer); + rp = SSL3_BUFFER_get_buf(RECORD_LAYER_get_rbuf(&s->rlayer)); + rlen = SSL3_BUFFER_get_len(RECORD_LAYER_get_rbuf(&s->rlayer)); + wp = SSL3_BUFFER_get_buf(RECORD_LAYER_get_wbuf(&s->rlayer)); + wlen = SSL3_BUFFER_get_len(RECORD_LAYER_get_wbuf(&s->rlayer)); + memset(&s->rlayer, 0, sizeof s->rlayer); + SSL3_BUFFER_set_buf(RECORD_LAYER_get_rbuf(&s->rlayer), rp); + SSL3_BUFFER_set_len(RECORD_LAYER_get_rbuf(&s->rlayer), rlen); + SSL3_BUFFER_set_buf(RECORD_LAYER_get_wbuf(&s->rlayer), wp); + SSL3_BUFFER_set_len(RECORD_LAYER_get_wbuf(&s->rlayer), wlen); + + /* Do I need to do this? As far as I can tell read_ahead did not + * previously get reset by SSL_clear...so I'll keep it that way..but is + * that right? + */ + RECORD_LAYER_set_read_ahead(&s->rlayer, read_ahead); + RECORD_LAYER_set_ssl(&s->rlayer, s); + return (1); } @@ -298,6 +302,8 @@ SSL *SSL_new(SSL_CTX *ctx) goto err; memset(s, 0, sizeof(SSL)); + RECORD_LAYER_set_ssl(&s->rlayer, s); + #ifndef OPENSSL_NO_KRB5 s->kssl_ctx = kssl_ctx_new(); #endif /* OPENSSL_NO_KRB5 */ @@ -306,31 +312,24 @@ SSL *SSL_new(SSL_CTX *ctx) s->mode = ctx->mode; s->max_cert_list = ctx->max_cert_list; - if (ctx->cert != NULL) { - /* - * Earlier library versions used to copy the pointer to the CERT, not - * its contents; only when setting new parameters for the per-SSL - * copy, ssl_cert_new would be called (and the direct reference to - * the per-SSL_CTX settings would be lost, but those still were - * indirectly accessed for various purposes, and for that reason they - * used to be known as s->ctx->default_cert). Now we don't look at the - * SSL_CTX's CERT after having duplicated it once. - */ - - s->cert = ssl_cert_dup(ctx->cert); - if (s->cert == NULL) - goto err; - } else - s->cert = NULL; /* Cannot really happen (see SSL_CTX_new) */ + /* + * Earlier library versions used to copy the pointer to the CERT, not + * its contents; only when setting new parameters for the per-SSL + * copy, ssl_cert_new would be called (and the direct reference to + * the per-SSL_CTX settings would be lost, but those still were + * indirectly accessed for various purposes, and for that reason they + * used to be known as s->ctx->default_cert). Now we don't look at the + * SSL_CTX's CERT after having duplicated it once. + */ + s->cert = ssl_cert_dup(ctx->cert); + if (s->cert == NULL) + goto err; - s->read_ahead = ctx->read_ahead; + RECORD_LAYER_set_read_ahead(&s->rlayer, ctx->read_ahead); s->msg_callback = ctx->msg_callback; s->msg_callback_arg = ctx->msg_callback_arg; s->verify_mode = ctx->verify_mode; s->not_resumable_session_cb = ctx->not_resumable_session_cb; -#if 0 - s->verify_depth = ctx->verify_depth; -#endif s->sid_ctx_length = ctx->sid_ctx_length; OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx); memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx)); @@ -341,10 +340,6 @@ SSL *SSL_new(SSL_CTX *ctx) if (!s->param) goto err; X509_VERIFY_PARAM_inherit(s->param, ctx->param); -#if 0 - s->purpose = ctx->purpose; - s->trust = ctx->trust; -#endif s->quiet_shutdown = ctx->quiet_shutdown; s->max_send_fragment = ctx->max_send_fragment; @@ -407,7 +402,8 @@ SSL *SSL_new(SSL_CTX *ctx) s->references = 1; s->server = (ctx->method->ssl_accept == ssl_undefined_function) ? 0 : 1; - SSL_clear(s); + if(!SSL_clear(s)) + goto err; CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); @@ -571,9 +567,8 @@ void SSL_free(SSL *s) BIO_free(s->bbio); s->bbio = NULL; } - if (s->rbio != NULL) - BIO_free_all(s->rbio); - if ((s->wbio != NULL) && (s->wbio != s->rbio)) + BIO_free_all(s->rbio); + if (s->wbio != s->rbio) BIO_free_all(s->wbio); if (s->init_buf != NULL) @@ -626,6 +621,11 @@ void SSL_free(SSL *s) if (s->method != NULL) s->method->ssl_free(s); + if (SSL3_BUFFER_is_initialised(RECORD_LAYER_get_rbuf(&s->rlayer))) + ssl3_release_read_buffer(s); + if (SSL3_BUFFER_is_initialised(RECORD_LAYER_get_wbuf(&s->rlayer))) + ssl3_release_write_buffer(s); + if (s->ctx) SSL_CTX_free(s->ctx); @@ -647,7 +647,14 @@ void SSL_free(SSL *s) OPENSSL_free(s); } -void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) +void SSL_set_rbio(SSL *s, BIO *rbio) +{ + if (s->rbio != rbio) + BIO_free_all(s->rbio); + s->rbio = rbio; +} + +void SSL_set_wbio(SSL *s, BIO *wbio) { /* * If the output buffering BIO is still in place, remove it @@ -658,14 +665,17 @@ void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) s->bbio->next_bio = NULL; } } - if ((s->rbio != NULL) && (s->rbio != rbio)) - BIO_free_all(s->rbio); - if ((s->wbio != NULL) && (s->wbio != wbio) && (s->rbio != s->wbio)) + if (s->wbio != wbio && s->rbio != s->wbio) BIO_free_all(s->wbio); - s->rbio = rbio; s->wbio = wbio; } +void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) +{ + SSL_set_wbio(s, wbio); + SSL_set_rbio(s, rbio); +} + BIO *SSL_get_rbio(const SSL *s) { return (s->rbio); @@ -840,12 +850,12 @@ void SSL_set_verify_depth(SSL *s, int depth) void SSL_set_read_ahead(SSL *s, int yes) { - s->read_ahead = yes; + RECORD_LAYER_set_read_ahead(&s->rlayer, yes); } int SSL_get_read_ahead(const SSL *s) { - return (s->read_ahead); + return RECORD_LAYER_get_read_ahead(&s->rlayer); } int SSL_pending(const SSL *s) @@ -899,12 +909,12 @@ STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) * Now in theory, since the calling process own 't' it should be safe to * modify. We need to be able to read f without being hassled */ -void SSL_copy_session_id(SSL *t, const SSL *f) +int SSL_copy_session_id(SSL *t, const SSL *f) { - CERT *tmp; - /* Do we need to to SSL locking? */ - SSL_set_session(t, SSL_get_session(f)); + if(!SSL_set_session(t, SSL_get_session(f))) { + return 0; + } /* * what if we are setup as SSLv2 but want to talk SSLv3 or vice-versa @@ -915,22 +925,21 @@ void SSL_copy_session_id(SSL *t, const SSL *f) t->method->ssl_new(t); /* setup new */ } - tmp = t->cert; - if (f->cert != NULL) { - CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT); - t->cert = f->cert; - } else - t->cert = NULL; - if (tmp != NULL) - ssl_cert_free(tmp); - SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length); + CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT); + ssl_cert_free(t->cert); + t->cert = f->cert; + if(!SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length)) { + return 0; + } + + return 1; } /* Fix this so it checks all the valid key/cert options */ int SSL_CTX_check_private_key(const SSL_CTX *ctx) { if ((ctx == NULL) || - (ctx->cert == NULL) || (ctx->cert->key->x509 == NULL)) { + (ctx->cert->key->x509 == NULL)) { SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); return (0); @@ -951,10 +960,6 @@ int SSL_check_private_key(const SSL *ssl) SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, ERR_R_PASSED_NULL_PARAMETER); return (0); } - if (ssl->cert == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); - return 0; - } if (ssl->cert->key->x509 == NULL) { SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); return (0); @@ -1087,10 +1092,10 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) switch (cmd) { case SSL_CTRL_GET_READ_AHEAD: - return (s->read_ahead); + return (RECORD_LAYER_get_read_ahead(&s->rlayer)); case SSL_CTRL_SET_READ_AHEAD: - l = s->read_ahead; - s->read_ahead = larg; + l = RECORD_LAYER_get_read_ahead(&s->rlayer); + RECORD_LAYER_set_read_ahead(&s->rlayer, larg); return (l); case SSL_CTRL_SET_MSG_CALLBACK_ARG: @@ -1917,26 +1922,14 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->references = 1; ret->quiet_shutdown = 0; - -/* ret->cipher=NULL;*/ -/*- - ret->s2->challenge=NULL; - ret->master_key=NULL; - ret->s2->conn_id=NULL; */ - ret->info_callback = NULL; - ret->app_verify_callback = 0; ret->app_verify_arg = NULL; - ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT; ret->read_ahead = 0; ret->msg_callback = 0; ret->msg_callback_arg = NULL; ret->verify_mode = SSL_VERIFY_NONE; -#if 0 - ret->verify_depth = -1; /* Don't impose a limit (but x509_lu.c does) */ -#endif ret->sid_ctx_length = 0; ret->default_verify_callback = NULL; if ((ret->cert = ssl_cert_new()) == NULL) @@ -1955,10 +1948,10 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) if (ret->cert_store == NULL) goto err; - ssl_create_cipher_list(ret->method, + if(!ssl_create_cipher_list(ret->method, &ret->cipher_list, &ret->cipher_list_by_id, - SSL_DEFAULT_CIPHER_LIST, ret->cert); - if (ret->cipher_list == NULL || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { + SSL_DEFAULT_CIPHER_LIST, ret->cert) + || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_LIBRARY_HAS_NO_CIPHERS); goto err2; } @@ -1992,7 +1985,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->tlsext_servername_callback = 0; ret->tlsext_servername_arg = NULL; /* Setup RFC4507 ticket keys */ - if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16) <= 0) + if ((RAND_bytes(ret->tlsext_tick_key_name, 16) <= 0) || (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0) || (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0)) ret->options |= SSL_OP_NO_TICKET; @@ -2011,7 +2004,8 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->psk_server_callback = NULL; #endif #ifndef OPENSSL_NO_SRP - SSL_CTX_SRP_CTX_init(ret); + if(!SSL_CTX_SRP_CTX_init(ret)) + goto err; #endif #ifndef OPENSSL_NO_ENGINE ret->client_cert_engine = NULL; @@ -2099,13 +2093,7 @@ void SSL_CTX_free(SSL_CTX *a) sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free); if (a->extra_certs != NULL) sk_X509_pop_free(a->extra_certs, X509_free); -#if 0 /* This should never be done, since it - * removes a global database */ - if (a->comp_methods != NULL) - sk_SSL_COMP_pop_free(a->comp_methods, SSL_COMP_free); -#else a->comp_methods = NULL; -#endif #ifndef OPENSSL_NO_SRTP if (a->srtp_profiles) @@ -2186,13 +2174,9 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) int rsa_enc_export, dh_rsa_export, dh_dsa_export; int rsa_tmp_export, dh_tmp_export, kl; unsigned long mask_k, mask_a, emask_k, emask_a; -#ifndef OPENSSL_NO_ECDSA +#ifndef OPENSSL_NO_EC int have_ecc_cert, ecdsa_ok, ecc_pkey_size; -#endif -#ifndef OPENSSL_NO_ECDH int have_ecdh_tmp, ecdh_ok; -#endif -#ifndef OPENSSL_NO_EC X509 *x = NULL; EVP_PKEY *ecc_pkey = NULL; int signature_nid = 0, pk_nid = 0, md_nid = 0; @@ -2218,7 +2202,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) dh_tmp = dh_tmp_export = 0; #endif -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC have_ecdh_tmp = (c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto); #endif cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]); @@ -2267,15 +2251,6 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc))) emask_k |= SSL_kRSA; -#if 0 - /* The match needs to be both kDHE and aRSA or aDSA, so don't worry */ - if ((dh_tmp || dh_rsa || dh_dsa) && (rsa_enc || rsa_sign || dsa_sign)) - mask_k |= SSL_kDHE; - if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) && - (rsa_enc || rsa_sign || dsa_sign)) - emask_k |= SSL_kDHE; -#endif - if (dh_tmp_export) emask_k |= SSL_kDHE; @@ -2325,10 +2300,8 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) x = cpk->x509; /* This call populates extension flags (ex_flags) */ X509_check_purpose(x, -1, 0); -# ifndef OPENSSL_NO_ECDH ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ? (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1; -# endif ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ? (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1; if (!(cpk->valid_flags & CERT_PKEY_SIGN)) @@ -2340,7 +2313,6 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); } -# ifndef OPENSSL_NO_ECDH if (ecdh_ok) { if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa) { @@ -2361,17 +2333,14 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) } } } -# endif -# ifndef OPENSSL_NO_ECDSA if (ecdsa_ok) { mask_a |= SSL_aECDSA; emask_a |= SSL_aECDSA; } -# endif } #endif -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC if (have_ecdh_tmp) { mask_k |= SSL_kECDHE; emask_k |= SSL_kECDHE; @@ -2791,6 +2760,12 @@ const char *SSL_get_version(const SSL *s) return ("TLSv1"); else if (s->version == SSL3_VERSION) return ("SSLv3"); + else if (s->version == DTLS1_BAD_VER) + return ("DTLSv0.9"); + else if (s->version == DTLS1_VERSION) + return ("DTLSv1"); + else if (s->version == DTLS1_2_VERSION) + return ("DTLSv1.2"); else return ("unknown"); } @@ -2811,7 +2786,8 @@ SSL *SSL_dup(SSL *s) if (s->session != NULL) { /* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */ - SSL_copy_session_id(ret, s); + if(!SSL_copy_session_id(ret, s)) + goto err; } else { /* * No session has been established yet, so we have to expect that @@ -2833,7 +2809,8 @@ SSL *SSL_dup(SSL *s) goto err; } - SSL_set_session_id_context(ret, s->sid_ctx, s->sid_ctx_length); + if(!SSL_set_session_id_context(ret, s->sid_ctx, s->sid_ctx_length)) + goto err; } ret->options = s->options; @@ -3096,26 +3073,28 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) { - CERT *ocert = ssl->cert; + CERT *new_cert; if (ssl->ctx == ctx) return ssl->ctx; #ifndef OPENSSL_NO_TLSEXT if (ctx == NULL) ctx = ssl->initial_ctx; #endif - ssl->cert = ssl_cert_dup(ctx->cert); - if (ocert) { - /* Preserve any already negotiated parameters */ - if (ssl->server) { - ssl->cert->peer_sigalgs = ocert->peer_sigalgs; - ssl->cert->peer_sigalgslen = ocert->peer_sigalgslen; - ocert->peer_sigalgs = NULL; - ssl->cert->ciphers_raw = ocert->ciphers_raw; - ssl->cert->ciphers_rawlen = ocert->ciphers_rawlen; - ocert->ciphers_raw = NULL; - } - ssl_cert_free(ocert); + new_cert = ssl_cert_dup(ctx->cert); + if (new_cert == NULL) { + return NULL; } + /* Preserve any already negotiated parameters */ + if (ssl->server) { + new_cert->peer_sigalgs = ssl->cert->peer_sigalgs; + new_cert->peer_sigalgslen = ssl->cert->peer_sigalgslen; + ssl->cert->peer_sigalgs = NULL; + new_cert->ciphers_raw = ssl->cert->ciphers_raw; + new_cert->ciphers_rawlen = ssl->cert->ciphers_rawlen; + ssl->cert->ciphers_raw = NULL; + } + ssl_cert_free(ssl->cert); + ssl->cert = new_cert; /* * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH), @@ -3309,7 +3288,7 @@ void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh) (SSL *ssl, int is_export, } #endif -#ifndef OPENSSL_NO_ECDH +#ifndef OPENSSL_NO_EC void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, EC_KEY *(*ecdh) (SSL *ssl, int is_export, int keylength)) @@ -3601,8 +3580,4 @@ void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx) return ctx->cert->sec_ex; } -IMPLEMENT_STACK_OF(SSL_CIPHER) - -IMPLEMENT_STACK_OF(SSL_COMP) - IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id);