X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_lib.c;h=28b71082ab37b54dd1578b135e9c8d6a2c7bec7c;hp=0a2c04e7414098d6109abd67b780ac8651fd6248;hb=df6da24bda457b724ba3e894e6c329a9b93d536f;hpb=16f8d4ebf0fd4847fa83d9c61f4150273cb4f533 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 0a2c04e741..28b71082ab 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -147,7 +147,6 @@ #endif #include #include "ssl_locl.h" -#include "kssl_lcl.h" #include #include #include @@ -160,7 +159,7 @@ # include #endif -const char *SSL_version_str = OPENSSL_VERSION_TEXT; +const char SSL_version_str[] = OPENSSL_VERSION_TEXT; SSL3_ENC_METHOD ssl3_undef_enc_method = { /* @@ -187,6 +186,14 @@ SSL3_ENC_METHOD ssl3_undef_enc_method = { int use_context))ssl_undefined_function, }; +static void clear_ciphers(SSL *s) +{ + /* clear the current cipher */ + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); +} + int SSL_clear(SSL *s) { if (s->method == NULL) { @@ -218,9 +225,7 @@ int SSL_clear(SSL *s) BUF_MEM_free(s->init_buf); s->init_buf = NULL; - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); + clear_ciphers(s); s->first_packet = 0; /* @@ -272,17 +277,12 @@ SSL *SSL_new(SSL_CTX *ctx) return (NULL); } - s = OPENSSL_malloc(sizeof(*s)); + s = OPENSSL_zalloc(sizeof(*s)); if (s == NULL) goto err; - memset(s, 0, sizeof(*s)); RECORD_LAYER_init(&s->rlayer, s); -#ifndef OPENSSL_NO_KRB5 - s->kssl_ctx = kssl_ctx_new(); -#endif /* OPENSSL_NO_KRB5 */ - s->options = ctx->options; s->mode = ctx->mode; s->max_cert_list = ctx->max_cert_list; @@ -320,7 +320,6 @@ SSL *SSL_new(SSL_CTX *ctx) CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); s->ctx = ctx; -#ifndef OPENSSL_NO_TLSEXT s->tlsext_debug_cb = 0; s->tlsext_debug_arg = NULL; s->tlsext_ticket_expected = 0; @@ -365,7 +364,6 @@ SSL *SSL_new(SSL_CTX *ctx) s->ctx->alpn_client_proto_list_len); s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len; } -#endif s->verify_result = X509_V_OK; @@ -555,25 +553,21 @@ void SSL_free(SSL *s) SSL_SESSION_free(s->session); } - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); + clear_ciphers(s); ssl_cert_free(s->cert); /* Free up if allocated */ -#ifndef OPENSSL_NO_TLSEXT OPENSSL_free(s->tlsext_hostname); SSL_CTX_free(s->initial_ctx); -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC OPENSSL_free(s->tlsext_ecpointformatlist); OPENSSL_free(s->tlsext_ellipticcurvelist); -# endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_NO_EC */ sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free); sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); OPENSSL_free(s->tlsext_ocsp_resp); OPENSSL_free(s->alpn_client_proto_list); -#endif sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free); @@ -584,12 +578,7 @@ void SSL_free(SSL *s) SSL_CTX_free(s->ctx); -#ifndef OPENSSL_NO_KRB5 - if (s->kssl_ctx != NULL) - kssl_ctx_free(s->kssl_ctx); -#endif /* OPENSSL_NO_KRB5 */ - -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) +#if !defined(OPENSSL_NO_NEXTPROTONEG) OPENSSL_free(s->next_proto_negotiated); #endif @@ -835,7 +824,7 @@ X509 *SSL_get_peer_certificate(const SSL *s) if (r == NULL) return (r); - CRYPTO_add(&r->references, 1, CRYPTO_LOCK_X509); + X509_up_ref(r); return (r); } @@ -844,11 +833,10 @@ STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) { STACK_OF(X509) *r; - if ((s == NULL) || (s->session == NULL) - || (s->session->sess_cert == NULL)) + if ((s == NULL) || (s->session == NULL)) r = NULL; else - r = s->session->sess_cert->cert_chain; + r = s->session->peer_chain; /* * If we are a client, cert_chain includes the peer's own certificate; if @@ -1086,10 +1074,10 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) case SSL_CTRL_GET_RAW_CIPHERLIST: if (parg) { - if (s->cert->ciphers_raw == NULL) + if (s->s3->tmp.ciphers_raw == NULL) return 0; - *(unsigned char **)parg = s->cert->ciphers_raw; - return (int)s->cert->ciphers_rawlen; + *(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); case SSL_CTRL_GET_EXTMS_SUPPORT: @@ -1272,6 +1260,13 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) return (NULL); } +STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s) +{ + if ((s == NULL) || (s->session == NULL) || !s->server) + return NULL; + return s->session->ciphers; +} + STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s) { STACK_OF(SSL_CIPHER) *sk = NULL, *ciphers; @@ -1404,161 +1399,6 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len) return (buf); } -int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, - unsigned char *p, - int (*put_cb) (const SSL_CIPHER *, - unsigned char *)) -{ - int i, j = 0; - SSL_CIPHER *c; - unsigned char *q; - int empty_reneg_info_scsv = !s->renegotiate; - /* Set disabled masks for this session */ - ssl_set_client_disabled(s); - - if (sk == NULL) - return (0); - q = p; - if (put_cb == NULL) - put_cb = s->method->put_cipher_by_char; - - for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { - c = sk_SSL_CIPHER_value(sk, i); - /* Skip disabled ciphers */ - if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED)) - continue; -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - if (c->id == SSL3_CK_SCSV) { - if (!empty_reneg_info_scsv) - continue; - else - empty_reneg_info_scsv = 0; - } -#endif - j = put_cb(c, p); - p += j; - } - /* - * If p == q, no ciphers; caller indicates an error. Otherwise, add - * applicable SCSVs. - */ - if (p != q) { - if (empty_reneg_info_scsv) { - static SSL_CIPHER scsv = { - 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - j = put_cb(&scsv, p); - p += j; -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, - "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n"); -#endif - } - if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) { - static SSL_CIPHER scsv = { - 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - j = put_cb(&scsv, p); - p += j; - } - } - - return (p - q); -} - -STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, - int num, - STACK_OF(SSL_CIPHER) **skp) -{ - const SSL_CIPHER *c; - STACK_OF(SSL_CIPHER) *sk; - int i, n; - - if (s->s3) - s->s3->send_connection_binding = 0; - - n = ssl_put_cipher_by_char(s, NULL, NULL); - if (n == 0 || (num % n) != 0) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); - return (NULL); - } - if ((skp == NULL) || (*skp == NULL)) - sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */ - else { - sk = *skp; - sk_SSL_CIPHER_zero(sk); - } - - OPENSSL_free(s->cert->ciphers_raw); - s->cert->ciphers_raw = BUF_memdup(p, num); - if (s->cert->ciphers_raw == NULL) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - goto err; - } - s->cert->ciphers_rawlen = (size_t)num; - - for (i = 0; i < num; i += n) { - /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ - if (s->s3 && (n != 3 || !p[0]) && - (p[n - 2] == ((SSL3_CK_SCSV >> 8) & 0xff)) && - (p[n - 1] == (SSL3_CK_SCSV & 0xff))) { - /* SCSV fatal if renegotiating */ - if (s->renegotiate) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - goto err; - } - s->s3->send_connection_binding = 1; - p += n; -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, "SCSV received by server\n"); -#endif - continue; - } - - /* Check for TLS_FALLBACK_SCSV */ - if ((n != 3 || !p[0]) && - (p[n - 2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) && - (p[n - 1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) { - /* - * The SCSV indicates that the client previously tried a higher - * version. Fail if the current version is an unexpected - * downgrade. - */ - if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_INAPPROPRIATE_FALLBACK); - if (s->s3) - ssl3_send_alert(s, SSL3_AL_FATAL, - SSL_AD_INAPPROPRIATE_FALLBACK); - goto err; - } - p += n; - continue; - } - - c = ssl_get_cipher_by_char(s, p); - p += n; - if (c != NULL) { - if (!sk_SSL_CIPHER_push(sk, c)) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - goto err; - } - } - } - - if (skp != NULL) - *skp = sk; - return (sk); - err: - if ((skp == NULL) || (*skp == NULL)) - sk_SSL_CIPHER_free(sk); - return (NULL); -} - -#ifndef OPENSSL_NO_TLSEXT /** return a servername extension value if provided in Client Hello, or NULL. * So far, only host_name types are defined (RFC 3546). */ @@ -1640,7 +1480,7 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, return status; } -# ifndef OPENSSL_NO_NEXTPROTONEG +#ifndef OPENSSL_NO_NEXTPROTONEG /* * SSL_get0_next_proto_negotiated sets *data and *len to point to the * client's requested protocol for this connection and returns 0. If the @@ -1701,7 +1541,7 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, ctx->next_proto_select_cb = cb; ctx->next_proto_select_cb_arg = arg; } -# endif +#endif /* * SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|. @@ -1774,7 +1614,6 @@ void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, *len = ssl->s3->alpn_selected_len; } -#endif /* !OPENSSL_NO_TLSEXT */ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, const char *label, size_t llen, @@ -1844,51 +1683,21 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); goto err; } - ret = OPENSSL_malloc(sizeof(*ret)); + ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) goto err; - memset(ret, 0, sizeof(*ret)); - ret->method = meth; - - ret->cert_store = NULL; ret->session_cache_mode = SSL_SESS_CACHE_SERVER; ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT; - ret->session_cache_head = NULL; - ret->session_cache_tail = NULL; - - /* We take the system default */ + /* We take the system default. */ ret->session_timeout = meth->get_timeout(); - - ret->new_session_cb = 0; - ret->remove_session_cb = 0; - ret->get_session_cb = 0; - ret->generate_session_id = 0; - - memset(&ret->stats, 0, sizeof(ret->stats)); - ret->references = 1; - ret->quiet_shutdown = 0; - 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; - ret->sid_ctx_length = 0; - ret->default_verify_callback = NULL; if ((ret->cert = ssl_cert_new()) == NULL) goto err; - ret->default_passwd_callback = 0; - ret->default_passwd_callback_userdata = NULL; - ret->client_cert_cb = 0; - ret->app_gen_cookie_cb = 0; - ret->app_verify_cookie_cb = 0; - ret->sessions = lh_SSL_SESSION_new(); if (ret->sessions == NULL) goto err; @@ -1922,41 +1731,23 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data); - ret->extra_certs = NULL; /* No compression for DTLS */ if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)) ret->comp_methods = SSL_COMP_get_compression_methods(); ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; -#ifndef OPENSSL_NO_TLSEXT - ret->tlsext_servername_callback = 0; - ret->tlsext_servername_arg = NULL; /* Setup RFC4507 ticket keys */ 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; - ret->tlsext_status_cb = 0; - ret->tlsext_status_arg = NULL; - -# ifndef OPENSSL_NO_NEXTPROTONEG - ret->next_protos_advertised_cb = 0; - ret->next_proto_select_cb = 0; -# endif -#endif -#ifndef OPENSSL_NO_PSK - ret->psk_identity_hint = NULL; - ret->psk_client_callback = NULL; - ret->psk_server_callback = NULL; -#endif #ifndef OPENSSL_NO_SRP if (!SSL_CTX_SRP_CTX_init(ret)) goto err; #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) @@ -2034,9 +1825,6 @@ void SSL_CTX_free(SSL_CTX *a) #ifndef OPENSSL_NO_SRTP sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles); #endif -#ifndef OPENSSL_NO_PSK - OPENSSL_free(a->psk_identity_hint); -#endif #ifndef OPENSSL_NO_SRP SSL_CTX_SRP_CTX_free(a); #endif @@ -2045,13 +1833,11 @@ void SSL_CTX_free(SSL_CTX *a) ENGINE_finish(a->client_cert_engine); #endif -#ifndef OPENSSL_NO_TLSEXT -# ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_EC OPENSSL_free(a->tlsext_ecpointformatlist); OPENSSL_free(a->tlsext_ellipticcurvelist); -# endif - OPENSSL_free(a->alpn_client_proto_list); #endif + OPENSSL_free(a->alpn_client_proto_list); OPENSSL_free(a); } @@ -2097,9 +1883,11 @@ void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg) ssl_cert_set_cert_cb(s->cert, cb, arg); } -void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) +void ssl_set_masks(SSL *s, const SSL_CIPHER *cipher) { CERT_PKEY *cpk; + CERT *c = s->cert; + uint32_t *pvalid = s->s3->tmp.valid_flags; int rsa_enc, rsa_tmp, rsa_sign, dh_tmp, dh_rsa, dh_dsa, dsa_sign; int rsa_enc_export, dh_rsa_export, dh_dsa_export; int rsa_tmp_export, dh_tmp_export, kl; @@ -2109,7 +1897,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) int have_ecdh_tmp, ecdh_ok; X509 *x = NULL; EVP_PKEY *ecc_pkey = NULL; - int signature_nid = 0, pk_nid = 0, md_nid = 0; + int pk_nid = 0, md_nid = 0; #endif if (c == NULL) return; @@ -2136,22 +1924,21 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) have_ecdh_tmp = (c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto); #endif cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]); - rsa_enc = cpk->valid_flags & CERT_PKEY_VALID; + rsa_enc = pvalid[SSL_PKEY_RSA_ENC] & CERT_PKEY_VALID; rsa_enc_export = (rsa_enc && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); cpk = &(c->pkeys[SSL_PKEY_RSA_SIGN]); - rsa_sign = cpk->valid_flags & CERT_PKEY_SIGN; + rsa_sign = pvalid[SSL_PKEY_RSA_SIGN] & CERT_PKEY_SIGN; cpk = &(c->pkeys[SSL_PKEY_DSA_SIGN]); - dsa_sign = cpk->valid_flags & CERT_PKEY_SIGN; + dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_SIGN; cpk = &(c->pkeys[SSL_PKEY_DH_RSA]); - dh_rsa = cpk->valid_flags & CERT_PKEY_VALID; + dh_rsa = pvalid[SSL_PKEY_DH_RSA] & CERT_PKEY_VALID; dh_rsa_export = (dh_rsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); cpk = &(c->pkeys[SSL_PKEY_DH_DSA]); -/* FIX THIS EAY EAY EAY */ - dh_dsa = cpk->valid_flags & CERT_PKEY_VALID; + dh_dsa = pvalid[SSL_PKEY_DH_DSA] & CERT_PKEY_VALID; dh_dsa_export = (dh_dsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); cpk = &(c->pkeys[SSL_PKEY_ECC]); #ifndef OPENSSL_NO_EC - have_ecc_cert = cpk->valid_flags & CERT_PKEY_VALID; + have_ecc_cert = pvalid[SSL_PKEY_ECC] & CERT_PKEY_VALID; #endif mask_k = 0; mask_a = 0; @@ -2170,11 +1957,6 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) 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; @@ -2197,7 +1979,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) if (dh_dsa_export) emask_k |= SSL_kDHd; - if (emask_k & (SSL_kDHr | SSL_kDHd)) + if (mask_k & (SSL_kDHr | SSL_kDHd)) mask_a |= SSL_aDH; if (rsa_enc || rsa_sign) { @@ -2213,36 +1995,24 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) mask_a |= SSL_aNULL; emask_a |= SSL_aNULL; -#ifndef OPENSSL_NO_KRB5 - mask_k |= SSL_kKRB5; - mask_a |= SSL_aKRB5; - emask_k |= SSL_kKRB5; - emask_a |= SSL_aKRB5; -#endif - /* * An ECC certificate may be usable for ECDH and/or ECDSA cipher suites * depending on the key usage extension. */ #ifndef OPENSSL_NO_EC if (have_ecc_cert) { + uint32_t ex_kusage; cpk = &c->pkeys[SSL_PKEY_ECC]; x = cpk->x509; - /* This call populates extension flags (ex_flags) */ - X509_check_purpose(x, -1, 0); - ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ? - (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1; - ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ? - (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1; - if (!(cpk->valid_flags & CERT_PKEY_SIGN)) + ex_kusage = X509_get_key_usage(x); + ecdh_ok = ex_kusage & X509v3_KU_KEY_AGREEMENT; + ecdsa_ok = ex_kusage & X509v3_KU_DIGITAL_SIGNATURE; + if (!(pvalid[SSL_PKEY_ECC] & CERT_PKEY_SIGN)) ecdsa_ok = 0; ecc_pkey = X509_get_pubkey(x); ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0; EVP_PKEY_free(ecc_pkey); - if ((x->sig_alg) && (x->sig_alg->algorithm)) { - signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); - OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); - } + OBJ_find_sigid_algs(X509_get_signature_nid(x), &md_nid, &pk_nid); if (ecdh_ok) { if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa) { @@ -2282,19 +2052,20 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) mask_a |= SSL_aPSK; emask_k |= SSL_kPSK; emask_a |= SSL_aPSK; + if (mask_k & SSL_kRSA) + mask_k |= SSL_kRSAPSK; + if (mask_k & SSL_kDHE) + mask_k |= SSL_kDHEPSK; + if (mask_k & SSL_kECDHE) + mask_k |= SSL_kECDHEPSK; #endif - c->mask_k = mask_k; - c->mask_a = mask_a; - c->export_mask_k = emask_k; - c->export_mask_a = emask_a; - c->valid = 1; + s->s3->tmp.mask_k = mask_k; + s->s3->tmp.mask_a = mask_a; + s->s3->tmp.export_mask_k = emask_k; + s->s3->tmp.export_mask_a = emask_a; } -/* This handy macro borrowed from crypto/x509v3/v3_purp.c */ -#define ku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) - #ifndef OPENSSL_NO_EC int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) @@ -2302,8 +2073,9 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) unsigned long alg_k, alg_a; EVP_PKEY *pkey = NULL; int keysize = 0; - int signature_nid = 0, md_nid = 0, pk_nid = 0; + int md_nid = 0, pk_nid = 0; const SSL_CIPHER *cs = s->s3->tmp.new_cipher; + uint32_t ex_kusage = X509_get_key_usage(x); alg_k = cs->algorithm_mkey; alg_a = cs->algorithm_auth; @@ -2319,15 +2091,11 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) return 0; } - /* This call populates the ex_flags field correctly */ - X509_check_purpose(x, -1, 0); - if ((x->sig_alg) && (x->sig_alg->algorithm)) { - signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); - OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); - } + OBJ_find_sigid_algs(X509_get_signature_nid(x), &md_nid, &pk_nid); + if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr) { /* key usage, if present, must allow key agreement */ - if (ku_reject(x, X509v3_KU_KEY_AGREEMENT)) { + if (!(ex_kusage & X509v3_KU_KEY_AGREEMENT)) { SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT); return 0; @@ -2352,7 +2120,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) } if (alg_a & SSL_aECDSA) { /* key usage, if present, must allow signing */ - if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) { + if (!(ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)) { SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_NOT_FOR_SIGNING); return 0; @@ -2375,7 +2143,7 @@ static int ssl_get_server_cert_index(const SSL *s) return idx; } -CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) +CERT_PKEY *ssl_get_server_send_pkey(SSL *s) { CERT *c; int i; @@ -2383,7 +2151,7 @@ CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) c = s->cert; if (!s->s3 || !s->s3->tmp.new_cipher) return NULL; - ssl_set_cert_masks(c, s->s3->tmp.new_cipher); + ssl_set_masks(s, s->s3->tmp.new_cipher); #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL /* @@ -2440,11 +2208,10 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, return (NULL); } if (pmd) - *pmd = c->pkeys[idx].digest; + *pmd = s->s3->tmp.md[idx]; return c->pkeys[idx].privatekey; } -#ifndef OPENSSL_NO_TLSEXT int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, size_t *serverinfo_length) { @@ -2464,7 +2231,6 @@ int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, *serverinfo_length = c->pkeys[i].serverinfo_length; return 1; } -#endif void ssl_update_cache(SSL *s, int mode) { @@ -2626,20 +2392,13 @@ int SSL_do_handshake(SSL *s) return (ret); } -/* - * For the next 2 functions, SSL_clear() sets shutdown and so one of these - * calls will reset it - */ void SSL_set_accept_state(SSL *s) { s->server = 1; s->shutdown = 0; s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE; s->handshake_func = s->method->ssl_accept; - /* clear the current cipher */ - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); + clear_ciphers(s); } void SSL_set_connect_state(SSL *s) @@ -2648,10 +2407,7 @@ void SSL_set_connect_state(SSL *s) s->shutdown = 0; s->state = SSL_ST_CONNECT | SSL_ST_BEFORE; s->handshake_func = s->method->ssl_connect; - /* clear the current cipher */ - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); + clear_ciphers(s); } int ssl_undefined_function(SSL *s) @@ -2878,32 +2634,23 @@ const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) return (NULL); } -#ifdef OPENSSL_NO_COMP -const void *SSL_get_current_compression(SSL *s) -{ - return NULL; -} - -const void *SSL_get_current_expansion(SSL *s) -{ - return NULL; -} -#else - const COMP_METHOD *SSL_get_current_compression(SSL *s) { - if (s->compress != NULL) - return (s->compress->meth); - return (NULL); +#ifndef OPENSSL_NO_COMP + return s->compress ? COMP_CTX_get_method(s->compress) : NULL; +#else + return NULL; +#endif } const COMP_METHOD *SSL_get_current_expansion(SSL *s) { - if (s->expand != NULL) - return (s->expand->meth); - return (NULL); -} +#ifndef OPENSSL_NO_COMP + return s->expand ? COMP_CTX_get_method(s->expand) : NULL; +#else + return NULL; #endif +} int ssl_init_wbio_buffer(SSL *s, int push) { @@ -2998,23 +2745,12 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) CERT *new_cert; if (ssl->ctx == ctx) return ssl->ctx; -#ifndef OPENSSL_NO_TLSEXT if (ctx == NULL) ctx = ssl->initial_ctx; -#endif 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; @@ -3093,6 +2829,41 @@ long SSL_get_verify_result(const SSL *ssl) return (ssl->verify_result); } +size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, size_t outlen) +{ + if (outlen == 0) + return sizeof(ssl->s3->client_random); + if (outlen > sizeof(ssl->s3->client_random)) + outlen = sizeof(ssl->s3->client_random); + memcpy(out, ssl->s3->client_random, outlen); + return outlen; +} + +size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, size_t outlen) +{ + if (outlen == 0) + return sizeof(ssl->s3->server_random); + if (outlen > sizeof(ssl->s3->server_random)) + outlen = sizeof(ssl->s3->server_random); + memcpy(out, ssl->s3->server_random, outlen); + return outlen; +} + +size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, + unsigned char *out, size_t outlen) +{ + if (session->master_key_length < 0) { + /* Should never happen */ + return 0; + } + if (outlen == 0) + return session->master_key_length; + if (outlen > (size_t)session->master_key_length) + outlen = session->master_key_length; + memcpy(out, session->master_key, outlen); + return outlen; +} + int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { @@ -3233,13 +3004,13 @@ int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) SSL_R_DATA_LENGTH_TOO_LONG); return 0; } - OPENSSL_free(ctx->psk_identity_hint); + OPENSSL_free(ctx->cert->psk_identity_hint); if (identity_hint != NULL) { - ctx->psk_identity_hint = BUF_strdup(identity_hint); - if (ctx->psk_identity_hint == NULL) + ctx->cert->psk_identity_hint = BUF_strdup(identity_hint); + if (ctx->cert->psk_identity_hint == NULL) return 0; } else - ctx->psk_identity_hint = NULL; + ctx->cert->psk_identity_hint = NULL; return 1; } @@ -3248,20 +3019,17 @@ int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) if (s == NULL) return 0; - if (s->session == NULL) - return 1; /* session not created yet, ignored */ - if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG); return 0; } - OPENSSL_free(s->session->psk_identity_hint); + OPENSSL_free(s->cert->psk_identity_hint); if (identity_hint != NULL) { - s->session->psk_identity_hint = BUF_strdup(identity_hint); - if (s->session->psk_identity_hint == NULL) + s->cert->psk_identity_hint = BUF_strdup(identity_hint); + if (s->cert->psk_identity_hint == NULL) return 0; } else - s->session->psk_identity_hint = NULL; + s->cert->psk_identity_hint = NULL; return 1; }