Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / boringssl / src / ssl / ssl_lib.c
index 182b9eb..720ab54 100644 (file)
@@ -172,6 +172,13 @@ SSL3_ENC_METHOD ssl3_undef_enc_method={
                 int use_context)) ssl_undefined_function,
        };
 
+/* Some error codes are special. Ensure the make_errors.go script
+ * never regresses this. */
+OPENSSL_COMPILE_ASSERT(
+       SSL_R_TLSV1_ALERT_NO_RENEGOTIATION ==
+               SSL_AD_NO_RENEGOTIATION + SSL_AD_REASON_OFFSET,
+       ssl_alert_reason_code_mismatch);
+
 int SSL_clear(SSL *s)
        {
 
@@ -187,7 +194,6 @@ int SSL_clear(SSL *s)
                s->session=NULL;
                }
 
-       s->error=0;
        s->hit=0;
        s->shutdown=0;
 
@@ -337,15 +343,8 @@ 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;
-#ifndef OPENSSL_NO_EC
        if (ctx->tlsext_ecpointformatlist)
                {
                s->tlsext_ecpointformatlist =
@@ -366,10 +365,7 @@ SSL *SSL_new(SSL_CTX *ctx)
                s->tlsext_ellipticcurvelist_length = 
                                        ctx->tlsext_ellipticcurvelist_length;
                }
-#endif
-# ifndef OPENSSL_NO_NEXTPROTONEG
        s->next_proto_negotiated = NULL;
-# endif
 
        if (s->ctx->alpn_client_proto_list)
                {
@@ -405,6 +401,12 @@ SSL *SSL_new(SSL_CTX *ctx)
        s->psk_client_callback=ctx->psk_client_callback;
        s->psk_server_callback=ctx->psk_server_callback;
 
+       if (!s->server)
+               {
+               s->signed_cert_timestamps_enabled = s->ctx->signed_cert_timestamps_enabled;
+               s->ocsp_stapling_enabled = s->ctx->ocsp_stapling_enabled;
+               }
+
        return(s);
 err:
        if (s != NULL)
@@ -670,20 +672,8 @@ void SSL_free(SSL *s)
        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_ocsp_exts)
-               sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
-                                               X509_EXTENSION_free);
-        /* TODO(fork): OCSP support */
-#if 0
-       if (s->tlsext_ocsp_ids)
-               sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
-#endif
-       if (s->tlsext_ocsp_resp)
-               OPENSSL_free(s->tlsext_ocsp_resp);
        if (s->alpn_client_proto_list)
                OPENSSL_free(s->alpn_client_proto_list);
        if (s->tlsext_channel_id_private)
@@ -699,14 +689,17 @@ void SSL_free(SSL *s)
 
        if (s->ctx) SSL_CTX_free(s->ctx);
 
-#if !defined(OPENSSL_NO_NEXTPROTONEG)
        if (s->next_proto_negotiated)
                OPENSSL_free(s->next_proto_negotiated);
-#endif
 
         if (s->srtp_profiles)
             sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
 
+       if (s->tlsext_session_ticket)
+               {
+               OPENSSL_free(s->tlsext_session_ticket);
+               }
+
        OPENSSL_free(s);
        }
 
@@ -1028,7 +1021,7 @@ int SSL_connect(SSL *s)
 
 long SSL_get_default_timeout(const SSL *s)
        {
-       return(s->method->get_timeout());
+       return SSL_DEFAULT_SESSION_TIMEOUT;
        }
 
 int SSL_read(SSL *s,void *buf,int num)
@@ -1093,7 +1086,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);
@@ -1158,11 +1151,8 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
                s->max_cert_list=larg;
                return(l);
        case SSL_CTRL_SET_MTU:
-#ifndef OPENSSL_NO_DTLS1
                if (larg < (long)dtls1_min_mtu())
                        return 0;
-#endif
-
                if (SSL_IS_DTLS(s))
                        {
                        s->d1->mtu = larg;
@@ -1393,7 +1383,7 @@ STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s)
 /** The old interface to get the same thing as SSL_get_ciphers() */
 const char *SSL_get_cipher_list(const SSL *s,int n)
        {
-       SSL_CIPHER *c;
+       const SSL_CIPHER *c;
        STACK_OF(SSL_CIPHER) *sk;
 
        if (s == NULL) return(NULL);
@@ -1467,7 +1457,7 @@ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
        {
        char *p;
        STACK_OF(SSL_CIPHER) *sk;
-       SSL_CIPHER *c;
+       const SSL_CIPHER *c;
        int i;
 
        if ((s->session == NULL) || (s->session->ciphers == NULL) ||
@@ -1505,7 +1495,7 @@ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
 int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p)
        {
        int i;
-       SSL_CIPHER *c;
+       const SSL_CIPHER *c;
        CERT *ct = s->cert;
        unsigned char *q;
        int no_scsv = s->renegotiate;
@@ -1541,7 +1531,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p)
                {
                if (!no_scsv)
                        {
-                       static SSL_CIPHER scsv =
+                       static const SSL_CIPHER scsv =
                                {
                                0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
                                };
@@ -1552,7 +1542,7 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p)
                        }
                if (s->fallback_scsv)
                        {
-                       static SSL_CIPHER fallback_scsv =
+                       static const SSL_CIPHER fallback_scsv =
                                {
                                0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
                                };
@@ -1671,6 +1661,63 @@ int SSL_get_servername_type(const SSL *s)
        return -1;
        }
 
+void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx)
+       {
+       ctx->signed_cert_timestamps_enabled = 1;
+       }
+
+int SSL_enable_signed_cert_timestamps(SSL *ssl)
+       {
+       /* Currently not implemented server-side. */
+       if (ssl->server)
+               return 0;
+
+       ssl->signed_cert_timestamps_enabled = 1;
+       return 1;
+       }
+
+void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx)
+       {
+       ctx->ocsp_stapling_enabled = 1;
+       }
+
+int SSL_enable_ocsp_stapling(SSL *ssl)
+       {
+       /* Currently not implemented server-side. */
+       if (ssl->server)
+               return 0;
+       ssl->ocsp_stapling_enabled = 1;
+       return 1;
+       }
+
+void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, uint8_t **out, size_t *out_len)
+       {
+       SSL_SESSION *session = ssl->session;
+
+       *out_len = 0;
+       *out = NULL;
+       if (ssl->server)
+               return;
+       if (!session || !session->tlsext_signed_cert_timestamp_list)
+               return;
+       *out = session->tlsext_signed_cert_timestamp_list;
+       *out_len = session->tlsext_signed_cert_timestamp_list_length;
+       }
+
+void SSL_get0_ocsp_response(const SSL *ssl, uint8_t **out, size_t *out_len)
+       {
+       SSL_SESSION *session = ssl->session;
+
+       *out_len = 0;
+       *out = NULL;
+       if (ssl->server)
+               return;
+       if (!session || !session->ocsp_response)
+               return;
+       *out = session->ocsp_response;
+       *out_len = session->ocsp_response_length;
+       }
+
 /* SSL_select_next_proto implements the standard protocol selection. It is
  * expected that this function is called from the callback set by
  * SSL_CTX_set_next_proto_select_cb.
@@ -1737,7 +1784,6 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, const unsi
        return status;
        }
 
-# 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 client didn't
  * request any protocol, then *data is set to NULL.
@@ -1786,7 +1832,6 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, int (*cb) (SSL *s, unsigned
        ctx->next_proto_select_cb = cb;
        ctx->next_proto_select_cb_arg = arg;
        }
-# endif
 
 /* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
  * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
@@ -1924,7 +1969,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
        ret->session_cache_tail=NULL;
 
        /* We take the system default */
-       ret->session_timeout=meth->get_timeout();
+       ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
 
        ret->new_session_cb=0;
        ret->remove_session_cb=0;
@@ -1979,10 +2024,6 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
        if (!ret->param)
                goto err;
 
-       ret->rsa_md5 = EVP_md5();
-       ret->md5 = EVP_md5();
-       ret->sha1 = EVP_sha1();
-
        if ((ret->client_CA=sk_X509_NAME_new_null()) == NULL)
                goto err;
 
@@ -2003,33 +2044,12 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
        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
        ret->psk_identity_hint=NULL;
        ret->psk_client_callback=NULL;
        ret->psk_server_callback=NULL;
-#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
+
        /* Default is to connect to non-RI servers. When RI is more widely
         * deployed might change this.
         */
@@ -2104,26 +2124,19 @@ void SSL_CTX_free(SSL_CTX *a)
        if (a->psk_identity_hint)
                OPENSSL_free(a->psk_identity_hint);
 
-       /* TODO(fork): remove. */
-#if 0
-#ifndef OPENSSL_NO_ENGINE
-       if (a->client_cert_engine)
-               ENGINE_finish(a->client_cert_engine);
-#endif
-#endif
-
-# ifndef OPENSSL_NO_EC
        if (a->tlsext_ecpointformatlist)
                OPENSSL_free(a->tlsext_ecpointformatlist);
        if (a->tlsext_ellipticcurvelist)
                OPENSSL_free(a->tlsext_ellipticcurvelist);
-# endif /* OPENSSL_NO_EC */
        if (a->alpn_client_proto_list != NULL)
                OPENSSL_free(a->alpn_client_proto_list);
 
        if (a->tlsext_channel_id_private)
                EVP_PKEY_free(a->tlsext_channel_id_private);
 
+       if (a->keylog_bio)
+               BIO_free(a->keylog_bio);
+
        OPENSSL_free(a);
        }
 
@@ -2167,45 +2180,22 @@ void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg), void *arg)
 void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
        {
        CERT_PKEY *cpk;
-       int rsa_enc,rsa_sign,dh_tmp,dh_rsa,dh_dsa,dsa_sign;
+       int rsa_enc,rsa_sign,dh_tmp;
        unsigned long mask_k,mask_a;
-#ifndef OPENSSL_NO_ECDSA
        int have_ecc_cert, ecdsa_ok;
-#endif
-#ifndef OPENSSL_NO_ECDH
-       int have_ecdh_tmp, ecdh_ok;
-#endif
-#ifndef OPENSSL_NO_EC
+       int have_ecdh_tmp;
        X509 *x = NULL;
-       EVP_PKEY *ecc_pkey = NULL;
-       int signature_nid = 0, pk_nid = 0, md_nid = 0;
-#endif
        if (c == NULL) return;
 
-#ifndef OPENSSL_NO_DH
        dh_tmp=(c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
-#else
-       dh_tmp=0;
-#endif
 
-#ifndef OPENSSL_NO_ECDH
        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;
        cpk= &(c->pkeys[SSL_PKEY_RSA_SIGN]);
        rsa_sign= cpk->valid_flags & CERT_PKEY_SIGN;
-       cpk= &(c->pkeys[SSL_PKEY_DSA_SIGN]);
-       dsa_sign= cpk->valid_flags & CERT_PKEY_SIGN;
-       cpk= &(c->pkeys[SSL_PKEY_DH_RSA]);
-       dh_rsa=  cpk->valid_flags & CERT_PKEY_VALID;
-       cpk= &(c->pkeys[SSL_PKEY_DH_DSA]);
-/* FIX THIS EAY EAY EAY */
-       dh_dsa=  cpk->valid_flags & CERT_PKEY_VALID;
        cpk= &(c->pkeys[SSL_PKEY_ECC]);
-#ifndef OPENSSL_NO_EC
        have_ecc_cert= cpk->valid_flags & CERT_PKEY_VALID;
-#endif
        mask_k=0;
        mask_a=0;
 
@@ -2218,90 +2208,38 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
        if (rsa_enc)
                mask_k|=SSL_kRSA;
 
-#if 0
-       /* The match needs to be both kEDH and aRSA or aDSA, so don't worry */
-       if (    (dh_tmp || dh_rsa || dh_dsa) &&
-               (rsa_enc || rsa_sign || dsa_sign))
-               mask_k|=SSL_kEDH;
-#endif
-
        if (dh_tmp)
                mask_k|=SSL_kEDH;
 
-       if (dh_rsa) mask_k|=SSL_kDHr;
-
-       if (dh_dsa) mask_k|=SSL_kDHd;
-
-       if (mask_k & (SSL_kDHr|SSL_kDHd))
-               mask_a |= SSL_aDH;
-
        if (rsa_enc || rsa_sign)
                {
                mask_a|=SSL_aRSA;
                }
 
-       if (dsa_sign)
-               {
-               mask_a|=SSL_aDSS;
-               }
-
        mask_a|=SSL_aNULL;
 
-       /* An ECC certificate may be usable for ECDH and/or
-        * ECDSA cipher suites depending on the key usage extension.
-        */
-#ifndef OPENSSL_NO_EC
+       /* An ECC certificate may be usable for ECDSA cipher suites depending on
+         * the key usage extension. */
        if (have_ecc_cert)
                {
                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))
                        ecdsa_ok = 0;
-               ecc_pkey = X509_get_pubkey(x);
-               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);
-                       }
-#ifndef OPENSSL_NO_ECDH
-               if (ecdh_ok)
-                       {
-
-                       if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa)
-                               {
-                               mask_k|=SSL_kECDHr;
-                               mask_a|=SSL_aECDH;
-                               }
-
-                       if (pk_nid == NID_X9_62_id_ecPublicKey)
-                               {
-                               mask_k|=SSL_kECDHe;
-                               mask_a|=SSL_aECDH;
-                               }
-                       }
-#endif
-#ifndef OPENSSL_NO_ECDSA
                if (ecdsa_ok)
                        {
                        mask_a|=SSL_aECDSA;
                        }
-#endif
                }
-#endif
 
-#ifndef OPENSSL_NO_ECDH
        if (have_ecdh_tmp)
                {
                mask_k|=SSL_kEECDH;
                }
-#endif
 
        mask_k |= SSL_kPSK;
        mask_a |= SSL_aPSK;
@@ -2315,15 +2253,13 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
 #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)
        {
-       unsigned long alg_k, alg_a;
+       unsigned long alg_a;
        int signature_nid = 0, md_nid = 0, pk_nid = 0;
        const SSL_CIPHER *cs = s->s3->tmp.new_cipher;
 
-       alg_k = cs->algorithm_mkey;
        alg_a = cs->algorithm_auth;
 
        /* This call populates the ex_flags field correctly */
@@ -2333,34 +2269,6 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
                signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
                OBJ_find_sigid_algs(signature_nid, &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))
-                       {
-                       OPENSSL_PUT_ERROR(SSL, ssl_check_srvr_ecc_cert_and_alg, SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT);
-                       return 0;
-                       }
-               if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < TLS1_2_VERSION)
-                       {
-                       /* signature alg must be ECDSA */
-                       if (pk_nid != NID_X9_62_id_ecPublicKey)
-                               {
-                               OPENSSL_PUT_ERROR(SSL, ssl_check_srvr_ecc_cert_and_alg, SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE);
-                               return 0;
-                               }
-                       }
-               if ((alg_k & SSL_kECDHr) && TLS1_get_version(s) < TLS1_2_VERSION)
-                       {
-                       /* signature alg must be RSA */
-
-                       if (pk_nid != NID_rsaEncryption && pk_nid != NID_rsa)
-                               {
-                               OPENSSL_PUT_ERROR(SSL, ssl_check_srvr_ecc_cert_and_alg, SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE);
-                               return 0;
-                               }
-                       }
-               }
        if (alg_a & SSL_aECDSA)
                {
                /* key usage, if present, must allow signing */
@@ -2374,7 +2282,6 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
        return 1;  /* all checks are ok */
        }
 
-#endif
 
 static int ssl_get_server_cert_index(const SSL *s)
        {
@@ -2431,10 +2338,7 @@ EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd)
        else
 #endif
 
-       if ((alg_a & SSL_aDSS) &&
-               (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))
-               idx = SSL_PKEY_DSA_SIGN;
-       else if (alg_a & SSL_aRSA)
+       if (alg_a & SSL_aRSA)
                {
                if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL)
                        idx = SSL_PKEY_RSA_SIGN;
@@ -2462,14 +2366,14 @@ void ssl_update_cache(SSL *s,int mode)
         * and it would be rather hard to do anyway :-) */
        if (s->session->session_id_length == 0) return;
 
-       i=s->session_ctx->session_cache_mode;
+       i=s->initial_ctx->session_cache_mode;
        if ((i & mode) && (!s->hit)
                && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE)
-                   || SSL_CTX_add_session(s->session_ctx,s->session))
-               && (s->session_ctx->new_session_cb != NULL))
+                   || SSL_CTX_add_session(s->initial_ctx,s->session))
+               && (s->initial_ctx->new_session_cb != NULL))
                {
                CRYPTO_add(&s->session->references,1,CRYPTO_LOCK_SSL_SESSION);
-               if (!s->session_ctx->new_session_cb(s,s->session))
+               if (!s->initial_ctx->new_session_cb(s,s->session))
                        SSL_SESSION_free(s->session);
                }
 
@@ -2478,10 +2382,10 @@ void ssl_update_cache(SSL *s,int mode)
                ((i & mode) == mode))
                {
                if (  (((mode & SSL_SESS_CACHE_CLIENT)
-                       ?s->session_ctx->stats.sess_connect_good
-                       :s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff)
+                       ?s->initial_ctx->stats.sess_connect_good
+                       :s->initial_ctx->stats.sess_accept_good) & 0xff) == 0xff)
                        {
-                       SSL_CTX_flush_sessions(s->session_ctx,(unsigned long)time(NULL));
+                       SSL_CTX_flush_sessions(s->initial_ctx,(unsigned long)time(NULL));
                        }
                }
        }
@@ -2689,22 +2593,32 @@ SSL_METHOD *ssl_bad_method(int ver)
        return(NULL);
        }
 
-const char *SSL_get_version(const SSL *s)
+static const char *ssl_get_version(int version)
        {
-       if (s->version == TLS1_2_VERSION)
+       if (version == TLS1_2_VERSION)
                return("TLSv1.2");
-       else if (s->version == TLS1_1_VERSION)
+       else if (version == TLS1_1_VERSION)
                return("TLSv1.1");
-       else if (s->version == TLS1_VERSION)
+       else if (version == TLS1_VERSION)
                return("TLSv1");
-       else if (s->version == SSL3_VERSION)
+       else if (version == SSL3_VERSION)
                return("SSLv3");
-       else if (s->version == SSL2_VERSION)
+       else if (version == SSL2_VERSION)
                return("SSLv2");
        else
                return("unknown");
        }
 
+const char *SSL_get_version(const SSL *s)
+       {
+       return ssl_get_version(s->version);
+       }
+
+const char *SSL_SESSION_get_version(const SSL_SESSION *sess)
+       {
+       return ssl_get_version(sess->ssl_version);
+       }
+
 void ssl_clear_cipher_ctx(SSL *s)
        {
        if (s->enc_read_ctx != NULL)
@@ -3036,7 +2950,6 @@ RSA *cb(SSL *ssl,int is_export,int keylength)
  * \param dh the callback
  */
 
-#ifndef OPENSSL_NO_DH
 void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int is_export,
                                                         int keylength))
        {
@@ -3048,9 +2961,7 @@ void SSL_set_tmp_dh_callback(SSL *ssl,DH *(*dh)(SSL *ssl,int is_export,
        {
        SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh);
        }
-#endif
 
-#ifndef OPENSSL_NO_ECDH
 void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,EC_KEY *(*ecdh)(SSL *ssl,int is_export,
                                                                 int keylength))
        {
@@ -3062,7 +2973,6 @@ void SSL_set_tmp_ecdh_callback(SSL *ssl,EC_KEY *(*ecdh)(SSL *ssl,int is_export,
        {
        SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH_CB,(void (*)(void))ecdh);
        }
-#endif
 
 int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint)
        {
@@ -3185,6 +3095,122 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con
        SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
        }
 
+void SSL_CTX_set_keylog_bio(SSL_CTX *ctx, BIO *keylog_bio)
+       {
+       if (ctx->keylog_bio != NULL)
+               BIO_free(ctx->keylog_bio);
+       ctx->keylog_bio = keylog_bio;
+       }
+
+static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len)
+       {
+       static const char hextable[] = "0123456789abcdef";
+       uint8_t *out;
+       size_t i;
+
+       if (!CBB_add_space(cbb, &out, in_len * 2))
+               {
+               return 0;
+               }
+
+       for (i = 0; i < in_len; i++)
+               {
+               *(out++) = (uint8_t)hextable[in[i] >> 4];
+               *(out++) = (uint8_t)hextable[in[i] & 0xf];
+               }
+       return 1;
+       }
+
+int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx,
+       const uint8_t *encrypted_premaster, size_t encrypted_premaster_len,
+       const uint8_t *premaster, size_t premaster_len)
+       {
+       BIO *bio = ctx->keylog_bio;
+       CBB cbb;
+       uint8_t *out;
+       size_t out_len;
+       int ret;
+
+       if (bio == NULL)
+               {
+               return 1;
+               }
+
+       if (encrypted_premaster_len < 8)
+               {
+               OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_rsa_client_key_exchange, ERR_R_INTERNAL_ERROR);
+               return 0;
+               }
+
+       if (!CBB_init(&cbb, 4 + 16 + 1 + premaster_len*2 + 1))
+               {
+               return 0;
+               }
+       if (!CBB_add_bytes(&cbb, (const uint8_t*)"RSA ", 4) ||
+               /* Only the first 8 bytes of the encrypted premaster secret are
+                * logged. */
+               !cbb_add_hex(&cbb, encrypted_premaster, 8) ||
+               !CBB_add_bytes(&cbb, (const uint8_t*)" ", 1) ||
+               !cbb_add_hex(&cbb, premaster, premaster_len) ||
+               !CBB_add_bytes(&cbb, (const uint8_t*)"\n", 1) ||
+               !CBB_finish(&cbb, &out, &out_len))
+               {
+               CBB_cleanup(&cbb);
+               return 0;
+               }
+
+       CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+       ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio);
+       CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+
+       OPENSSL_free(out);
+       return ret;
+       }
+
+int ssl_ctx_log_master_secret(SSL_CTX *ctx,
+       const uint8_t *client_random, size_t client_random_len,
+       const uint8_t *master, size_t master_len)
+       {
+       BIO *bio = ctx->keylog_bio;
+       CBB cbb;
+       uint8_t *out;
+       size_t out_len;
+       int ret;
+
+       if (bio == NULL)
+               {
+               return 1;
+               }
+
+       if (client_random_len != 32)
+               {
+               OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_master_secret, ERR_R_INTERNAL_ERROR);
+               return 0;
+               }
+
+       if (!CBB_init(&cbb, 14 + 64 + 1 + master_len*2 + 1))
+               {
+               return 0;
+               }
+       if (!CBB_add_bytes(&cbb, (const uint8_t*)"CLIENT_RANDOM ", 14) ||
+               !cbb_add_hex(&cbb, client_random, 32) ||
+               !CBB_add_bytes(&cbb, (const uint8_t*)" ", 1) ||
+               !cbb_add_hex(&cbb, master, master_len) ||
+               !CBB_add_bytes(&cbb, (const uint8_t*)"\n", 1) ||
+               !CBB_finish(&cbb, &out, &out_len))
+               {
+               CBB_cleanup(&cbb);
+               return 0;
+               }
+
+       CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+       ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio);
+       CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+
+       OPENSSL_free(out);
+       return ret;
+       }
+
 int SSL_cutthrough_complete(const SSL *s)
        {
        return (!s->server &&                 /* cutthrough only applies to clients */
@@ -3216,11 +3242,7 @@ int ssl3_can_cutthrough(const SSL *s)
                return 0;
 
        /* require ALPN or NPN extension */
-       if (!s->s3->alpn_selected
-#ifndef OPENSSL_NO_NEXTPROTONEG
-               && !s->s3->next_proto_neg_seen
-#endif
-       )
+       if (!s->s3->alpn_selected && !s->s3->next_proto_neg_seen)
                {
                return 0;
                }