X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_lib.c;h=17fc536636715b85d0e4d879211786ac416f577a;hp=00a93eeee9c518e4fdaf72668d7d8fd919fa4e9d;hb=7587347bc48e7e8a1e800e48bb0a658f1557c424;hpb=761772d7e19145fa9afb2a0c830ead69a33f3fa5 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 00a93eeee9..17fc536636 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -152,9 +152,13 @@ #include #include #include +#include #ifndef OPENSSL_NO_DH #include #endif +#ifndef OPENSSL_NO_ENGINE +#include +#endif const char *SSL_version_str=OPENSSL_VERSION_TEXT; @@ -340,6 +344,12 @@ SSL *SSL_new(SSL_CTX *ctx) s->tlsext_debug_cb = 0; s->tlsext_debug_arg = NULL; s->tlsext_ticket_expected = 0; + s->tlsext_status_type = -1; + s->tlsext_status_expected = 0; + s->tlsext_ocsp_ids = NULL; + s->tlsext_ocsp_exts = NULL; + s->tlsext_ocsp_resp = NULL; + s->tlsext_ocsp_resplen = -1; CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); s->initial_ctx=ctx; #endif @@ -450,7 +460,7 @@ int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, } CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); - p = (SSL_SESSION *)lh_retrieve(ssl->ctx->sessions, &r); + p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r); CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); return (p != NULL); } @@ -537,12 +547,21 @@ void SSL_free(SSL *s) if (s->ctx) SSL_CTX_free(s->ctx); #ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_hostname) + OPENSSL_free(s->tlsext_hostname); if (s->initial_ctx) SSL_CTX_free(s->initial_ctx); #ifndef OPENSSL_NO_EC if (s->tlsext_ecpointformatlist) OPENSSL_free(s->tlsext_ecpointformatlist); if (s->tlsext_ellipticcurvelist) OPENSSL_free(s->tlsext_ellipticcurvelist); #endif /* OPENSSL_NO_EC */ if (s->tlsext_opaque_prf_input) OPENSSL_free(s->tlsext_opaque_prf_input); + if (s->tlsext_ocsp_exts) + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, + X509_EXTENSION_free); + if (s->tlsext_ocsp_ids) + sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); + if (s->tlsext_ocsp_resp) + OPENSSL_free(s->tlsext_ocsp_resp); #endif if (s->client_CA != NULL) @@ -1048,7 +1067,7 @@ long SSL_callback_ctrl(SSL *s, int cmd, void (*fp)(void)) } } -struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx) +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) { return ctx->sessions; } @@ -1091,7 +1110,7 @@ long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,void *parg) return(ctx->session_cache_mode); case SSL_CTRL_SESS_NUMBER: - return(ctx->sessions->num_items); + return(lh_SSL_SESSION_num_items(ctx->sessions)); case SSL_CTRL_SESS_CONNECT: return(ctx->stats.sess_connect); case SSL_CTRL_SESS_CONNECT_GOOD: @@ -1263,7 +1282,6 @@ int SSL_set_cipher_list(SSL *s,const char *str) char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len) { char *p; - const char *cp; STACK_OF(SSL_CIPHER) *sk; SSL_CIPHER *c; int i; @@ -1276,20 +1294,21 @@ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len) sk=s->session->ciphers; for (i=0; iname; *cp; ) + n=strlen(c->name); + if (n+1 > len) { - if (len-- <= 0) - { - *p='\0'; - return(buf); - } - else - *(p++)= *(cp++); + if (p != buf) + --p; + *p='\0'; + return buf; } + strcpy(p,c->name); + p+=n; *(p++)=':'; + len-=n+1; } p[-1]='\0'; return(buf); @@ -1331,7 +1350,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p, STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num, STACK_OF(SSL_CIPHER) **skp) { - SSL_CIPHER *c; + const SSL_CIPHER *c; STACK_OF(SSL_CIPHER) *sk; int i,n; @@ -1396,7 +1415,7 @@ int SSL_get_servername_type(const SSL *s) } #endif -unsigned long SSL_SESSION_hash(const SSL_SESSION *a) +static unsigned long ssl_session_hash(const SSL_SESSION *a) { unsigned long l; @@ -1413,7 +1432,7 @@ unsigned long SSL_SESSION_hash(const SSL_SESSION *a) * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being * able to construct an SSL_SESSION that will collide with any existing session * with a matching session ID. */ -int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b) +static int ssl_session_cmp(const SSL_SESSION *a,const SSL_SESSION *b) { if (a->ssl_version != b->ssl_version) return(1); @@ -1426,13 +1445,13 @@ int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b) * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each * variable. The reason is that the functions aren't static, they're exposed via * ssl.h. */ -static IMPLEMENT_LHASH_HASH_FN(SSL_SESSION_hash, SSL_SESSION *) -static IMPLEMENT_LHASH_COMP_FN(SSL_SESSION_cmp, SSL_SESSION *) +static IMPLEMENT_LHASH_HASH_FN(ssl_session, SSL_SESSION) +static IMPLEMENT_LHASH_COMP_FN(ssl_session, SSL_SESSION) SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) { SSL_CTX *ret=NULL; - + if (meth == NULL) { SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_NULL_SSL_METHOD_PASSED); @@ -1501,8 +1520,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->app_gen_cookie_cb=0; ret->app_verify_cookie_cb=0; - ret->sessions=lh_new(LHASH_HASH_FN(SSL_SESSION_hash), - LHASH_COMP_FN(SSL_SESSION_cmp)); + ret->sessions=lh_SSL_SESSION_new(); if (ret->sessions == NULL) goto err; ret->cert_store=X509_STORE_new(); if (ret->cert_store == NULL) goto err; @@ -1556,12 +1574,54 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) || (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0)) ret->options |= SSL_OP_NO_TICKET; + ret->tlsext_status_cb = 0; + ret->tlsext_status_arg = NULL; + #endif #ifndef OPENSSL_NO_PSK ret->psk_identity_hint=NULL; ret->psk_client_callback=NULL; ret->psk_server_callback=NULL; #endif +#ifndef OPENSSL_NO_BUF_FREELISTS + ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT; + ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); + if (!ret->rbuf_freelist) + goto err; + ret->rbuf_freelist->chunklen = 0; + ret->rbuf_freelist->len = 0; + ret->rbuf_freelist->head = NULL; + ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); + if (!ret->wbuf_freelist) + { + OPENSSL_free(ret->rbuf_freelist); + goto err; + } + ret->wbuf_freelist->chunklen = 0; + ret->wbuf_freelist->len = 0; + ret->wbuf_freelist->head = NULL; +#endif +#ifndef OPENSSL_NO_ENGINE + ret->client_cert_engine = NULL; +#ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO +#define eng_strx(x) #x +#define eng_str(x) eng_strx(x) + /* Use specific client engine automatically... ignore errors */ + { + ENGINE *eng; + eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); + if (!eng) + { + ERR_clear_error(); + ENGINE_load_builtin_engines(); + eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); + } + if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng)) + ERR_clear_error(); + } +#endif +#endif + return(ret); err: SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE); @@ -1575,6 +1635,20 @@ static void SSL_COMP_free(SSL_COMP *comp) { OPENSSL_free(comp); } #endif +#ifndef OPENSSL_NO_BUF_FREELISTS +static void +ssl_buf_freelist_free(SSL3_BUF_FREELIST *list) + { + SSL3_BUF_FREELIST_ENTRY *ent, *next; + for (ent = list->head; ent; ent = next) + { + next = ent->next; + OPENSSL_free(ent); + } + OPENSSL_free(list); + } +#endif + void SSL_CTX_free(SSL_CTX *a) { int i; @@ -1612,7 +1686,7 @@ void SSL_CTX_free(SSL_CTX *a) CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data); if (a->sessions != NULL) - lh_free(a->sessions); + lh_SSL_SESSION_free(a->sessions); if (a->cert_store != NULL) X509_STORE_free(a->cert_store); @@ -1637,6 +1711,18 @@ void SSL_CTX_free(SSL_CTX *a) if (a->psk_identity_hint) OPENSSL_free(a->psk_identity_hint); #endif +#ifndef OPENSSL_NO_ENGINE + if (a->client_cert_engine) + ENGINE_finish(a->client_cert_engine); +#endif + +#ifndef OPENSSL_NO_BUF_FREELISTS + if (a->wbuf_freelist) + ssl_buf_freelist_free(a->wbuf_freelist); + if (a->rbuf_freelist) + ssl_buf_freelist_free(a->rbuf_freelist); +#endif + OPENSSL_free(a); } @@ -1667,7 +1753,7 @@ void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth) X509_VERIFY_PARAM_set_depth(ctx->param, depth); } -void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher) +void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) { CERT_PKEY *cpk; int rsa_enc,rsa_tmp,rsa_sign,dh_tmp,dh_rsa,dh_dsa,dsa_sign; @@ -1725,11 +1811,24 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher) emask_k=0; emask_a=0; + + #ifdef CIPHER_DEBUG printf("rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n", rsa_tmp,rsa_tmp_export,dh_tmp,have_ecdh_tmp, rsa_enc,rsa_enc_export,rsa_sign,dsa_sign,dh_rsa,dh_dsa); #endif + + cpk = &(c->pkeys[SSL_PKEY_GOST01]); + if (cpk->x509 != NULL && cpk->privatekey !=NULL) { + mask_k |= SSL_kGOST; + mask_a |= SSL_aGOST01; + } + cpk = &(c->pkeys[SSL_PKEY_GOST94]); + if (cpk->x509 != NULL && cpk->privatekey !=NULL) { + mask_k |= SSL_kGOST; + mask_a |= SSL_aGOST94; + } if (rsa_enc || (rsa_tmp && rsa_sign)) mask_k|=SSL_kRSA; @@ -1866,7 +1965,7 @@ void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher) #define ku_reject(x, usage) \ (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) -int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs) +int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs) { unsigned long alg_k, alg_a; EVP_PKEY *pkey = NULL; @@ -1998,6 +2097,10 @@ X509 *ssl_get_server_send_cert(SSL *s) /* VRS something else here? */ return(NULL); } + else if (alg_a & SSL_aGOST94) + i=SSL_PKEY_GOST94; + else if (alg_a & SSL_aGOST01) + i=SSL_PKEY_GOST01; else /* if (alg_a & SSL_aNULL) */ { SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR); @@ -2008,7 +2111,7 @@ X509 *ssl_get_server_send_cert(SSL *s) return(c->pkeys[i].x509); } -EVP_PKEY *ssl_get_sign_pkey(SSL *s,SSL_CIPHER *cipher) +EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher) { unsigned long alg_a; CERT *c; @@ -2446,7 +2549,7 @@ EVP_PKEY *SSL_get_privatekey(SSL *s) return(NULL); } -SSL_CIPHER *SSL_get_current_cipher(const SSL *s) +const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) { if ((s->session != NULL) && (s->session->cipher != NULL)) return(s->session->cipher); @@ -2861,7 +2964,7 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con * vairable, freeing EVP_MD_CTX previously stored in that variable, if * any. If EVP_MD pointer is passed, initializes ctx with this md * Returns newly allocated ctx; - */ + */ EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash,const EVP_MD *md) {