Check sk_SSL_CIPHER_new_null return value
[openssl.git] / ssl / ssl_lib.c
index 2a84ff248f7b5e3b68c2c06edc92d1932a48095e..8f74ef10b4f73a831d659828e5fc9aeed2188f92 100644 (file)
@@ -189,7 +189,6 @@ SSL3_ENC_METHOD ssl3_undef_enc_method = {
 
 int SSL_clear(SSL *s)
 {
-
     if (s->method == NULL) {
         SSLerr(SSL_F_SSL_CLEAR, SSL_R_NO_METHOD_SPECIFIED);
         return (0);
@@ -204,23 +203,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;
 
@@ -229,23 +215,14 @@ int SSL_clear(SSL *s)
     s->version = s->method->version;
     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);
-        s->init_buf = NULL;
-    }
 
+    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);
-
     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 +234,10 @@ int SSL_clear(SSL *s)
         if (!s->method->ssl_new(s))
             return (0);
     } else
-#endif
         s->method->ssl_clear(s);
+
+    RECORD_LAYER_clear(&s->rlayer);
+
     return (1);
 }
 
@@ -293,10 +272,12 @@ SSL *SSL_new(SSL_CTX *ctx)
         return (NULL);
     }
 
-    s = (SSL *)OPENSSL_malloc(sizeof(SSL));
+    s = OPENSSL_malloc(sizeof(*s));
     if (s == NULL)
         goto err;
-    memset(s, 0, sizeof(SSL));
+    memset(s, 0, sizeof(*s));
+
+    RECORD_LAYER_init(&s->rlayer, s);
 
 #ifndef OPENSSL_NO_KRB5
     s->kssl_ctx = kssl_ctx_new();
@@ -306,31 +287,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 +315,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 +377,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);
 
@@ -418,8 +389,7 @@ SSL *SSL_new(SSL_CTX *ctx)
 
     return (s);
  err:
-    if (s != NULL)
-        SSL_free(s);
+    SSL_free(s);
     SSLerr(SSL_F_SSL_NEW, ERR_R_MALLOC_FAILURE);
     return (NULL);
 }
@@ -558,9 +528,7 @@ void SSL_free(SSL *s)
     }
 #endif
 
-    if (s->param)
-        X509_VERIFY_PARAM_free(s->param);
-
+    X509_VERIFY_PARAM_free(s->param);
     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
 
     if (s->bbio != NULL) {
@@ -571,19 +539,15 @@ 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)
-        BUF_MEM_free(s->init_buf);
+    BUF_MEM_free(s->init_buf);
 
     /* add extra stuff */
-    if (s->cipher_list != NULL)
-        sk_SSL_CIPHER_free(s->cipher_list);
-    if (s->cipher_list_by_id != NULL)
-        sk_SSL_CIPHER_free(s->cipher_list_by_id);
+    sk_SSL_CIPHER_free(s->cipher_list);
+    sk_SSL_CIPHER_free(s->cipher_list_by_id);
 
     /* Make the next call work :-) */
     if (s->session != NULL) {
@@ -595,39 +559,30 @@ void SSL_free(SSL *s)
     ssl_clear_hash_ctx(&s->read_hash);
     ssl_clear_hash_ctx(&s->write_hash);
 
-    if (s->cert != NULL)
-        ssl_cert_free(s->cert);
+    ssl_cert_free(s->cert);
     /* Free up if allocated */
 
 #ifndef OPENSSL_NO_TLSEXT
-    if (s->tlsext_hostname)
-        OPENSSL_free(s->tlsext_hostname);
-    if (s->initial_ctx)
-        SSL_CTX_free(s->initial_ctx);
+    OPENSSL_free(s->tlsext_hostname);
+    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);
+    OPENSSL_free(s->tlsext_ecpointformatlist);
+    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);
-    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);
-    if (s->alpn_client_proto_list)
-        OPENSSL_free(s->alpn_client_proto_list);
+    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
 
-    if (s->client_CA != NULL)
-        sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
+    sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
 
     if (s->method != NULL)
         s->method->ssl_free(s);
 
-    if (s->ctx)
-        SSL_CTX_free(s->ctx);
+    RECORD_LAYER_release(&s->rlayer);
+
+    SSL_CTX_free(s->ctx);
 
 #ifndef OPENSSL_NO_KRB5
     if (s->kssl_ctx != NULL)
@@ -635,19 +590,24 @@ void SSL_free(SSL *s)
 #endif                          /* OPENSSL_NO_KRB5 */
 
 #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
-    if (s->next_proto_negotiated)
-        OPENSSL_free(s->next_proto_negotiated);
+    OPENSSL_free(s->next_proto_negotiated);
 #endif
 
 #ifndef OPENSSL_NO_SRTP
-    if (s->srtp_profiles)
-        sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
+    sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
 #endif
 
     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 +618,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 +803,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 +862,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 +878,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 +913,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 +1045,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:
@@ -1134,6 +1092,13 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
             return (int)s->cert->ciphers_rawlen;
         } else
             return ssl_put_cipher_by_char(s, NULL, NULL);
+    case SSL_CTRL_GET_EXTMS_SUPPORT:
+        if (!s->session || SSL_in_init(s) || s->in_handshake)
+               return -1;
+       if (s->session->flags & SSL_SESS_FLAG_EXTMS)
+            return 1;
+        else
+            return 0;
     default:
         return (s->method->ssl_ctrl(s, cmd, larg, parg));
     }
@@ -1518,15 +1483,18 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
                SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
         return (NULL);
     }
-    if ((skp == NULL) || (*skp == NULL))
+    if ((skp == NULL) || (*skp == NULL)) {
         sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */
-    else {
+        if(sk == NULL) {
+            SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+    } else {
         sk = *skp;
         sk_SSL_CIPHER_zero(sk);
     }
 
-    if (s->cert->ciphers_raw)
-        OPENSSL_free(s->cert->ciphers_raw);
+    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);
@@ -1747,9 +1715,7 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx,
 int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
                             unsigned protos_len)
 {
-    if (ctx->alpn_client_proto_list)
-        OPENSSL_free(ctx->alpn_client_proto_list);
-
+    OPENSSL_free(ctx->alpn_client_proto_list);
     ctx->alpn_client_proto_list = OPENSSL_malloc(protos_len);
     if (!ctx->alpn_client_proto_list)
         return 1;
@@ -1767,9 +1733,7 @@ int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
 int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos,
                         unsigned protos_len)
 {
-    if (ssl->alpn_client_proto_list)
-        OPENSSL_free(ssl->alpn_client_proto_list);
-
+    OPENSSL_free(ssl->alpn_client_proto_list);
     ssl->alpn_client_proto_list = OPENSSL_malloc(protos_len);
     if (!ssl->alpn_client_proto_list)
         return 1;
@@ -1884,11 +1848,11 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
         SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
         goto err;
     }
-    ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
+    ret = OPENSSL_malloc(sizeof(*ret));
     if (ret == NULL)
         goto err;
 
-    memset(ret, 0, sizeof(SSL_CTX));
+    memset(ret, 0, sizeof(*ret));
 
     ret->method = meth;
 
@@ -1906,30 +1870,18 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
     ret->get_session_cb = 0;
     ret->generate_session_id = 0;
 
-    memset((char *)&ret->stats, 0, sizeof(ret->stats));
+    memset(&ret->stats, 0, sizeof(ret->stats));
 
     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)
@@ -1948,10 +1900,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;
     }
@@ -1985,7 +1937,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;
@@ -2004,7 +1956,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;
@@ -2035,8 +1988,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
  err:
     SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE);
  err2:
-    if (ret != NULL)
-        SSL_CTX_free(ret);
+    SSL_CTX_free(ret);
     return (NULL);
 }
 
@@ -2060,8 +2012,7 @@ void SSL_CTX_free(SSL_CTX *a)
     }
 #endif
 
-    if (a->param)
-        X509_VERIFY_PARAM_free(a->param);
+    X509_VERIFY_PARAM_free(a->param);
 
     /*
      * Free internal session cache. However: the remove_cb() may reference
@@ -2076,38 +2027,19 @@ void SSL_CTX_free(SSL_CTX *a)
         SSL_CTX_flush_sessions(a, 0);
 
     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data);
-
-    if (a->sessions != NULL)
-        lh_SSL_SESSION_free(a->sessions);
-
-    if (a->cert_store != NULL)
-        X509_STORE_free(a->cert_store);
-    if (a->cipher_list != NULL)
-        sk_SSL_CIPHER_free(a->cipher_list);
-    if (a->cipher_list_by_id != NULL)
-        sk_SSL_CIPHER_free(a->cipher_list_by_id);
-    if (a->cert != NULL)
-        ssl_cert_free(a->cert);
-    if (a->client_CA != NULL)
-        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
+    lh_SSL_SESSION_free(a->sessions);
+    X509_STORE_free(a->cert_store);
+    sk_SSL_CIPHER_free(a->cipher_list);
+    sk_SSL_CIPHER_free(a->cipher_list_by_id);
+    ssl_cert_free(a->cert);
+    sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free);
+    sk_X509_pop_free(a->extra_certs, X509_free);
     a->comp_methods = NULL;
-#endif
-
 #ifndef OPENSSL_NO_SRTP
-    if (a->srtp_profiles)
-        sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
+    sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
 #endif
-
 #ifndef OPENSSL_NO_PSK
-    if (a->psk_identity_hint)
-        OPENSSL_free(a->psk_identity_hint);
+    OPENSSL_free(a->psk_identity_hint);
 #endif
 #ifndef OPENSSL_NO_SRP
     SSL_CTX_SRP_CTX_free(a);
@@ -2119,13 +2051,10 @@ void SSL_CTX_free(SSL_CTX *a)
 
 #ifndef OPENSSL_NO_TLSEXT
 # 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);
+    OPENSSL_free(a->tlsext_ecpointformatlist);
+    OPENSSL_free(a->tlsext_ellipticcurvelist);
+# endif
+    OPENSSL_free(a->alpn_client_proto_list);
 #endif
 
     OPENSSL_free(a);
@@ -2179,13 +2108,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;
@@ -2211,7 +2136,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]);
@@ -2260,15 +2185,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;
 
@@ -2318,10 +2234,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))
@@ -2333,7 +2247,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) {
@@ -2354,17 +2267,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;
@@ -2784,6 +2694,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");
 }
@@ -2804,7 +2720,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
@@ -2818,15 +2735,14 @@ SSL *SSL_dup(SSL *s)
         ret->method->ssl_new(ret);
 
         if (s->cert != NULL) {
-            if (ret->cert != NULL) {
-                ssl_cert_free(ret->cert);
-            }
+            ssl_cert_free(ret->cert);
             ret->cert = ssl_cert_dup(s->cert);
             if (ret->cert == NULL)
                 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;
@@ -2869,7 +2785,7 @@ SSL *SSL_dup(SSL *s)
     ret->shutdown = s->shutdown;
     ret->state = s->state;      /* SSL_dup does not really work at any state,
                                  * though */
-    ret->rstate = s->rstate;
+    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 */
@@ -2900,14 +2816,11 @@ SSL *SSL_dup(SSL *s)
             }
         }
     }
+    return ret;
 
-    if (0) {
  err:
-        if (ret != NULL)
-            SSL_free(ret);
-        ret = NULL;
-    }
-    return (ret);
+    SSL_free(ret);
+    return NULL;
 }
 
 void ssl_clear_cipher_ctx(SSL *s)
@@ -2923,14 +2836,10 @@ void ssl_clear_cipher_ctx(SSL *s)
         s->enc_write_ctx = NULL;
     }
 #ifndef OPENSSL_NO_COMP
-    if (s->expand != NULL) {
-        COMP_CTX_free(s->expand);
-        s->expand = NULL;
-    }
-    if (s->compress != NULL) {
-        COMP_CTX_free(s->compress);
-        s->compress = NULL;
-    }
+    COMP_CTX_free(s->expand);
+    s->expand = NULL;
+    COMP_CTX_free(s->compress);
+    s->compress = NULL;
 #endif
 }
 
@@ -3032,6 +2941,7 @@ int ssl_init_wbio_buffer(SSL *s, int push)
 
 void ssl_free_wbio_buffer(SSL *s)
 {
+    /* callers ensure s is never null */
     if (s->bbio == NULL)
         return;
 
@@ -3089,26 +2999,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),
@@ -3130,8 +3042,7 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
     }
 
     CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
-    if (ssl->ctx != NULL)
-        SSL_CTX_free(ssl->ctx); /* decrement reference count */
+    SSL_CTX_free(ssl->ctx); /* decrement reference count */
     ssl->ctx = ctx;
 
     return (ssl->ctx);
@@ -3233,8 +3144,7 @@ X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx)
 
 void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store)
 {
-    if (ctx->cert_store != NULL)
-        X509_STORE_free(ctx->cert_store);
+    X509_STORE_free(ctx->cert_store);
     ctx->cert_store = store;
 }
 
@@ -3302,7 +3212,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))
@@ -3327,8 +3237,7 @@ int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint)
                SSL_R_DATA_LENGTH_TOO_LONG);
         return 0;
     }
-    if (ctx->psk_identity_hint != NULL)
-        OPENSSL_free(ctx->psk_identity_hint);
+    OPENSSL_free(ctx->psk_identity_hint);
     if (identity_hint != NULL) {
         ctx->psk_identity_hint = BUF_strdup(identity_hint);
         if (ctx->psk_identity_hint == NULL)
@@ -3350,8 +3259,7 @@ int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint)
         SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG);
         return 0;
     }
-    if (s->session->psk_identity_hint != NULL)
-        OPENSSL_free(s->session->psk_identity_hint);
+    OPENSSL_free(s->session->psk_identity_hint);
     if (identity_hint != NULL) {
         s->session->psk_identity_hint = BUF_strdup(identity_hint);
         if (s->session->psk_identity_hint == NULL)
@@ -3479,6 +3387,35 @@ void ssl_clear_hash_ctx(EVP_MD_CTX **hash)
     *hash = NULL;
 }
 
+/* Retrieve handshake hashes */
+int ssl_handshake_hash(SSL *s, unsigned char *out, int outlen)
+{
+    unsigned char *p = out;
+    int idx, ret = 0;
+    long mask;
+    EVP_MD_CTX ctx;
+    const EVP_MD *md;
+    EVP_MD_CTX_init(&ctx);
+    for (idx = 0; ssl_get_handshake_digest(idx, &mask, &md); idx++) {
+        if (mask & ssl_get_algorithm2(s)) {
+            int hashsize = EVP_MD_size(md);
+            EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx];
+            if (!hdgst || hashsize < 0 || hashsize > outlen)
+                goto err;
+            if (!EVP_MD_CTX_copy_ex(&ctx, hdgst))
+                goto err;
+            if (!EVP_DigestFinal_ex(&ctx, p, NULL))
+                goto err;
+            p += hashsize;
+            outlen -= hashsize;
+        }
+    }
+    ret = p - out;
+ err:
+    EVP_MD_CTX_cleanup(&ctx);
+    return ret;
+}
+
 void SSL_set_debug(SSL *s, int debug)
 {
     s->debug = debug;
@@ -3565,8 +3502,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);