/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 * ECC cipher suite support in OpenSSL originally developed by 
 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
 */
/* ====================================================================
 * Copyright 2005 Nokia. All rights reserved.
 *
 * The portions of the attached software ("Contribution") is developed by
 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
 * license.
 *
 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
 * support (see RFC 4279) to OpenSSL.
 *
 * No patent licenses or other rights except those expressly stated in
 * the OpenSSL open source license shall be deemed granted or received
 * expressly, by implication, estoppel, or otherwise.
 *
 * No assurances are provided by Nokia that the Contribution does not
 * infringe the patent or other intellectual property rights of any third
 * party or that the license provides you with all the necessary rights
 * to make use of the Contribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
 * OTHERWISE. */

#include <stdio.h>
#include <assert.h>

#include <openssl/bytestring.h>
#include <openssl/dh.h>
#include <openssl/engine.h>
#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/rand.h>
#include <openssl/x509v3.h>

#include "ssl_locl.h"

/* 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) {
  if (s->method == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_clear, SSL_R_NO_METHOD_SPECIFIED);
    return 0;
  }

  if (ssl_clear_bad_session(s)) {
    SSL_SESSION_free(s->session);
    s->session = NULL;
  }

  s->hit = 0;
  s->shutdown = 0;

  if (s->renegotiate) {
    OPENSSL_PUT_ERROR(SSL, SSL_clear, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  /* SSL_clear may be called before or after the |s| is initialized in either
   * accept or connect state. In the latter case, SSL_clear should preserve the
   * half and reset |s->state| accordingly. */
  if (s->handshake_func != NULL) {
    if (s->server) {
      SSL_set_accept_state(s);
    } else {
      SSL_set_connect_state(s);
    }
  } else {
    assert(s->state == 0);
  }

  /* TODO(davidben): Some state on |s| is reset both in |SSL_new| and
   * |SSL_clear| because it is per-connection state rather than configuration
   * state. Per-connection state should be on |s->s3| and |s->d1| so it is
   * naturally reset at the right points between |SSL_new|, |SSL_clear|, and
   * |ssl3_new|. */

  s->rwstate = SSL_NOTHING;
  s->rstate = SSL_ST_READ_HEADER;

  if (s->init_buf != NULL) {
    BUF_MEM_free(s->init_buf);
    s->init_buf = NULL;
  }

  s->packet = NULL;
  s->packet_length = 0;

  ssl_clear_cipher_ctx(s);

  if (s->next_proto_negotiated) {
    OPENSSL_free(s->next_proto_negotiated);
    s->next_proto_negotiated = NULL;
    s->next_proto_negotiated_len = 0;
  }

  /* The s->d1->mtu is simultaneously configuration (preserved across
   * clear) and connection-specific state (gets reset).
   *
   * TODO(davidben): Avoid this. */
  unsigned mtu = 0;
  if (s->d1 != NULL) {
    mtu = s->d1->mtu;
  }

  s->method->ssl_free(s);
  if (!s->method->ssl_new(s)) {
    return 0;
  }
  s->enc_method = ssl3_get_enc_method(s->version);
  assert(s->enc_method != NULL);

  if (SSL_IS_DTLS(s) && (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
    s->d1->mtu = mtu;
  }

  s->client_version = s->version;

  return 1;
}

SSL *SSL_new(SSL_CTX *ctx) {
  SSL *s;

  if (ctx == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_new, SSL_R_NULL_SSL_CTX);
    return NULL;
  }
  if (ctx->method == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_new, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
    return NULL;
  }

  s = (SSL *)OPENSSL_malloc(sizeof(SSL));
  if (s == NULL) {
    goto err;
  }
  memset(s, 0, sizeof(SSL));

  s->min_version = ctx->min_version;
  s->max_version = ctx->max_version;

  s->options = ctx->options;
  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) */
  }

  s->read_ahead = ctx->read_ahead;
  s->msg_callback = ctx->msg_callback;
  s->msg_callback_arg = ctx->msg_callback_arg;
  s->verify_mode = ctx->verify_mode;
  s->sid_ctx_length = ctx->sid_ctx_length;
  assert(s->sid_ctx_length <= sizeof s->sid_ctx);
  memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx));
  s->verify_callback = ctx->default_verify_callback;
  s->generate_session_id = ctx->generate_session_id;

  s->param = X509_VERIFY_PARAM_new();
  if (!s->param) {
    goto err;
  }
  X509_VERIFY_PARAM_inherit(s->param, ctx->param);
  s->quiet_shutdown = ctx->quiet_shutdown;
  s->max_send_fragment = ctx->max_send_fragment;

  CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
  s->ctx = ctx;
  s->tlsext_debug_cb = 0;
  s->tlsext_debug_arg = NULL;
  s->tlsext_ticket_expected = 0;
  CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
  s->initial_ctx = ctx;
  if (ctx->tlsext_ecpointformatlist) {
    s->tlsext_ecpointformatlist = BUF_memdup(
        ctx->tlsext_ecpointformatlist, ctx->tlsext_ecpointformatlist_length);
    if (!s->tlsext_ecpointformatlist) {
      goto err;
    }
    s->tlsext_ecpointformatlist_length = ctx->tlsext_ecpointformatlist_length;
  }

  if (ctx->tlsext_ellipticcurvelist) {
    s->tlsext_ellipticcurvelist =
        BUF_memdup(ctx->tlsext_ellipticcurvelist,
                   ctx->tlsext_ellipticcurvelist_length * 2);
    if (!s->tlsext_ellipticcurvelist) {
      goto err;
    }
    s->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length;
  }
  s->next_proto_negotiated = NULL;

  if (s->ctx->alpn_client_proto_list) {
    s->alpn_client_proto_list = BUF_memdup(s->ctx->alpn_client_proto_list,
                                           s->ctx->alpn_client_proto_list_len);
    if (s->alpn_client_proto_list == NULL) {
      goto err;
    }
    s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
  }

  s->verify_result = X509_V_OK;
  s->method = ctx->method;

  if (!s->method->ssl_new(s)) {
    goto err;
  }
  s->enc_method = ssl3_get_enc_method(s->version);
  assert(s->enc_method != NULL);

  s->rwstate = SSL_NOTHING;
  s->rstate = SSL_ST_READ_HEADER;

  CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);

  s->psk_identity_hint = NULL;
  if (ctx->psk_identity_hint) {
    s->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint);
    if (s->psk_identity_hint == NULL) {
      goto err;
    }
  }
  s->psk_client_callback = ctx->psk_client_callback;
  s->psk_server_callback = ctx->psk_server_callback;

  s->tlsext_channel_id_enabled = ctx->tlsext_channel_id_enabled;
  if (ctx->tlsext_channel_id_private) {
    s->tlsext_channel_id_private = EVP_PKEY_dup(ctx->tlsext_channel_id_private);
  }

  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) {
    SSL_free(s);
  }
  OPENSSL_PUT_ERROR(SSL, SSL_new, ERR_R_MALLOC_FAILURE);

  return NULL;
}

int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx,
                                   unsigned int sid_ctx_len) {
  if (sid_ctx_len > sizeof ctx->sid_ctx) {
    OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_session_id_context,
                      SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
    return 0;
  }
  ctx->sid_ctx_length = sid_ctx_len;
  memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len);

  return 1;
}

int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
                               unsigned int sid_ctx_len) {
  if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
    OPENSSL_PUT_ERROR(SSL, SSL_set_session_id_context,
                      SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
    return 0;
  }
  ssl->sid_ctx_length = sid_ctx_len;
  memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len);

  return 1;
}

int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) {
  CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
  ctx->generate_session_id = cb;
  CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
  return 1;
}

int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) {
  ssl->generate_session_id = cb;
  return 1;
}

int SSL_has_matching_session_id(const SSL *ssl, const uint8_t *id,
                                unsigned int id_len) {
  /* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how we
   * can "construct" a session to give us the desired check - ie. to find if
   * there's a session in the hash table that would conflict with any new
   * session built out of this id/id_len and the ssl_version in use by this
   * SSL. */
  SSL_SESSION r, *p;

  if (id_len > sizeof r.session_id) {
    return 0;
  }

  r.ssl_version = ssl->version;
  r.session_id_length = id_len;
  memcpy(r.session_id, id, id_len);

  CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
  p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r);
  CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
  return p != NULL;
}

int SSL_CTX_set_purpose(SSL_CTX *s, int purpose) {
  return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
}

int SSL_set_purpose(SSL *s, int purpose) {
  return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
}

int SSL_CTX_set_trust(SSL_CTX *s, int trust) {
  return X509_VERIFY_PARAM_set_trust(s->param, trust);
}

int SSL_set_trust(SSL *s, int trust) {
  return X509_VERIFY_PARAM_set_trust(s->param, trust);
}

int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) {
  return X509_VERIFY_PARAM_set1(ctx->param, vpm);
}

int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) {
  return X509_VERIFY_PARAM_set1(ssl->param, vpm);
}

void ssl_cipher_preference_list_free(
    struct ssl_cipher_preference_list_st *cipher_list) {
  sk_SSL_CIPHER_free(cipher_list->ciphers);
  OPENSSL_free(cipher_list->in_group_flags);
  OPENSSL_free(cipher_list);
}

struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_dup(
    struct ssl_cipher_preference_list_st *cipher_list) {
  struct ssl_cipher_preference_list_st *ret = NULL;
  size_t n = sk_SSL_CIPHER_num(cipher_list->ciphers);

  ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
  if (!ret) {
    goto err;
  }

  ret->ciphers = NULL;
  ret->in_group_flags = NULL;
  ret->ciphers = sk_SSL_CIPHER_dup(cipher_list->ciphers);
  if (!ret->ciphers) {
    goto err;
  }
  ret->in_group_flags = BUF_memdup(cipher_list->in_group_flags, n);
  if (!ret->in_group_flags) {
    goto err;
  }

  return ret;

err:
  if (ret && ret->ciphers) {
    sk_SSL_CIPHER_free(ret->ciphers);
  }
  if (ret) {
    OPENSSL_free(ret);
  }
  return NULL;
}

struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_from_ciphers(
    STACK_OF(SSL_CIPHER) * ciphers) {
  struct ssl_cipher_preference_list_st *ret = NULL;
  size_t n = sk_SSL_CIPHER_num(ciphers);

  ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
  if (!ret) {
    goto err;
  }
  ret->ciphers = NULL;
  ret->in_group_flags = NULL;
  ret->ciphers = sk_SSL_CIPHER_dup(ciphers);
  if (!ret->ciphers) {
    goto err;
  }
  ret->in_group_flags = OPENSSL_malloc(n);
  if (!ret->in_group_flags) {
    goto err;
  }
  memset(ret->in_group_flags, 0, n);
  return ret;

err:
  if (ret && ret->ciphers) {
    sk_SSL_CIPHER_free(ret->ciphers);
  }
  if (ret) {
    OPENSSL_free(ret);
  }
  return NULL;
}

X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { return ctx->param; }

X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { return ssl->param; }

void SSL_certs_clear(SSL *s) { ssl_cert_clear_certs(s->cert); }

void SSL_free(SSL *s) {
  if (s == NULL) {
    return;
  }

  if (s->param) {
    X509_VERIFY_PARAM_free(s->param);
  }

  CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);

  if (s->bbio != NULL) {
    /* If the buffering BIO is in place, pop it off */
    if (s->bbio == s->wbio) {
      s->wbio = BIO_pop(s->wbio);
    }
    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->wbio);
  }

  if (s->init_buf != NULL) {
    BUF_MEM_free(s->init_buf);
  }

  /* add extra stuff */
  if (s->cipher_list != NULL) {
    ssl_cipher_preference_list_free(s->cipher_list);
  }
  if (s->cipher_list_by_id != NULL) {
    sk_SSL_CIPHER_free(s->cipher_list_by_id);
  }

  if (s->session != NULL) {
    ssl_clear_bad_session(s);
    SSL_SESSION_free(s->session);
  }

  ssl_clear_cipher_ctx(s);

  if (s->cert != NULL) {
    ssl_cert_free(s->cert);
  }

  if (s->tlsext_hostname) {
    OPENSSL_free(s->tlsext_hostname);
  }
  if (s->initial_ctx) {
    SSL_CTX_free(s->initial_ctx);
  }
  if (s->tlsext_ecpointformatlist) {
    OPENSSL_free(s->tlsext_ecpointformatlist);
  }
  if (s->tlsext_ellipticcurvelist) {
    OPENSSL_free(s->tlsext_ellipticcurvelist);
  }
  if (s->alpn_client_proto_list) {
    OPENSSL_free(s->alpn_client_proto_list);
  }
  if (s->tlsext_channel_id_private) {
    EVP_PKEY_free(s->tlsext_channel_id_private);
  }
  if (s->psk_identity_hint) {
    OPENSSL_free(s->psk_identity_hint);
  }
  if (s->client_CA != NULL) {
    sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
  }
  if (s->next_proto_negotiated) {
    OPENSSL_free(s->next_proto_negotiated);
  }
  if (s->srtp_profiles) {
    sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
  }

  if (s->method != NULL) {
    s->method->ssl_free(s);
  }
  if (s->ctx) {
    SSL_CTX_free(s->ctx);
  }

  OPENSSL_free(s);
}

void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) {
  /* If the output buffering BIO is still in place, remove it. */
  if (s->bbio != NULL) {
    if (s->wbio == s->bbio) {
      s->wbio = s->wbio->next_bio;
      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) {
    BIO_free_all(s->wbio);
  }
  s->rbio = rbio;
  s->wbio = wbio;
}

BIO *SSL_get_rbio(const SSL *s) { return s->rbio; }

BIO *SSL_get_wbio(const SSL *s) { return s->wbio; }

int SSL_get_fd(const SSL *s) { return SSL_get_rfd(s); }

int SSL_get_rfd(const SSL *s) {
  int ret = -1;
  BIO *b, *r;

  b = SSL_get_rbio(s);
  r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
  if (r != NULL) {
    BIO_get_fd(r, &ret);
  }
  return ret;
}

int SSL_get_wfd(const SSL *s) {
  int ret = -1;
  BIO *b, *r;

  b = SSL_get_wbio(s);
  r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
  if (r != NULL) {
    BIO_get_fd(r, &ret);
  }

  return ret;
}

int SSL_set_fd(SSL *s, int fd) {
  int ret = 0;
  BIO *bio = NULL;

  bio = BIO_new(BIO_s_fd());

  if (bio == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_set_fd, ERR_R_BUF_LIB);
    goto err;
  }
  BIO_set_fd(bio, fd, BIO_NOCLOSE);
  SSL_set_bio(s, bio, bio);
  ret = 1;

err:
  return ret;
}

int SSL_set_wfd(SSL *s, int fd) {
  int ret = 0;
  BIO *bio = NULL;

  if (s->rbio == NULL || BIO_method_type(s->rbio) != BIO_TYPE_FD ||
      (int)BIO_get_fd(s->rbio, NULL) != fd) {
    bio = BIO_new(BIO_s_fd());

    if (bio == NULL) {
      OPENSSL_PUT_ERROR(SSL, SSL_set_wfd, ERR_R_BUF_LIB);
      goto err;
    }
    BIO_set_fd(bio, fd, BIO_NOCLOSE);
    SSL_set_bio(s, SSL_get_rbio(s), bio);
  } else {
    SSL_set_bio(s, SSL_get_rbio(s), SSL_get_rbio(s));
  }

  ret = 1;

err:
  return ret;
}

int SSL_set_rfd(SSL *s, int fd) {
  int ret = 0;
  BIO *bio = NULL;

  if (s->wbio == NULL || BIO_method_type(s->wbio) != BIO_TYPE_FD ||
      (int)BIO_get_fd(s->wbio, NULL) != fd) {
    bio = BIO_new(BIO_s_fd());

    if (bio == NULL) {
      OPENSSL_PUT_ERROR(SSL, SSL_set_rfd, ERR_R_BUF_LIB);
      goto err;
    }
    BIO_set_fd(bio, fd, BIO_NOCLOSE);
    SSL_set_bio(s, bio, SSL_get_wbio(s));
  } else {
    SSL_set_bio(s, SSL_get_wbio(s), SSL_get_wbio(s));
  }
  ret = 1;

err:
  return ret;
}

/* return length of latest Finished message we sent, copy to 'buf' */
size_t SSL_get_finished(const SSL *s, void *buf, size_t count) {
  size_t ret = 0;

  if (s->s3 != NULL) {
    ret = s->s3->tmp.finish_md_len;
    if (count > ret) {
      count = ret;
    }
    memcpy(buf, s->s3->tmp.finish_md, count);
  }

  return ret;
}

/* return length of latest Finished message we expected, copy to 'buf' */
size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count) {
  size_t ret = 0;

  if (s->s3 != NULL) {
    ret = s->s3->tmp.peer_finish_md_len;
    if (count > ret) {
      count = ret;
    }
    memcpy(buf, s->s3->tmp.peer_finish_md, count);
  }

  return ret;
}

int SSL_get_verify_mode(const SSL *s) { return s->verify_mode; }

int SSL_get_verify_depth(const SSL *s) {
  return X509_VERIFY_PARAM_get_depth(s->param);
}

int (*SSL_get_verify_callback(const SSL *s))(int, X509_STORE_CTX *) {
  return s->verify_callback;
}

int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { return ctx->verify_mode; }

int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) {
  return X509_VERIFY_PARAM_get_depth(ctx->param);
}

int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int, X509_STORE_CTX *) {
  return ctx->default_verify_callback;
}

void SSL_set_verify(SSL *s, int mode,
                    int (*callback)(int ok, X509_STORE_CTX *ctx)) {
  s->verify_mode = mode;
  if (callback != NULL) {
    s->verify_callback = callback;
  }
}

void SSL_set_verify_depth(SSL *s, int depth) {
  X509_VERIFY_PARAM_set_depth(s->param, depth);
}

void SSL_set_read_ahead(SSL *s, int yes) { s->read_ahead = yes; }

int SSL_get_read_ahead(const SSL *s) { return s->read_ahead; }

int SSL_pending(const SSL *s) {
  /* SSL_pending cannot work properly if read-ahead is enabled
   * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)), and it is
   * impossible to fix since SSL_pending cannot report errors that may be
   * observed while scanning the new data. (Note that SSL_pending() is often
   * used as a boolean value, so we'd better not return -1.). */
  return s->method->ssl_pending(s);
}

X509 *SSL_get_peer_certificate(const SSL *s) {
  X509 *r;

  if (s == NULL || s->session == NULL) {
    r = NULL;
  } else {
    r = s->session->peer;
  }

  if (r == NULL) {
    return NULL;
  }

  return X509_up_ref(r);
}

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) {
    r = NULL;
  } else {
    r = s->session->sess_cert->cert_chain;
  }

  /* If we are a client, cert_chain includes the peer's own certificate; if we
   * are a server, it does not. */
  return r;
}

/* 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) {
    OPENSSL_PUT_ERROR(SSL, SSL_CTX_check_private_key,
                      SSL_R_NO_CERTIFICATE_ASSIGNED);
    return 0;
  }

  if (ctx->cert->key->privatekey == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_CTX_check_private_key,
                      SSL_R_NO_PRIVATE_KEY_ASSIGNED);
    return 0;
  }

  return X509_check_private_key(ctx->cert->key->x509,
                                ctx->cert->key->privatekey);
}

/* Fix this function so that it takes an optional type parameter */
int SSL_check_private_key(const SSL *ssl) {
  if (ssl == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_check_private_key, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  if (ssl->cert == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
                      SSL_R_NO_CERTIFICATE_ASSIGNED);
    return 0;
  }

  if (ssl->cert->key->x509 == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
                      SSL_R_NO_CERTIFICATE_ASSIGNED);
    return 0;
  }

  if (ssl->cert->key->privatekey == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
                      SSL_R_NO_PRIVATE_KEY_ASSIGNED);
    return 0;
  }

  return X509_check_private_key(ssl->cert->key->x509,
                                ssl->cert->key->privatekey);
}

int SSL_accept(SSL *s) {
  if (s->handshake_func == 0) {
    /* Not properly initialized yet */
    SSL_set_accept_state(s);
  }

  if (s->handshake_func != s->method->ssl_accept) {
    OPENSSL_PUT_ERROR(SSL, SSL_connect, ERR_R_INTERNAL_ERROR);
    return -1;
  }

  return s->handshake_func(s);
}

int SSL_connect(SSL *s) {
  if (s->handshake_func == 0) {
    /* Not properly initialized yet */
    SSL_set_connect_state(s);
  }

  if (s->handshake_func != s->method->ssl_connect) {
    OPENSSL_PUT_ERROR(SSL, SSL_connect, ERR_R_INTERNAL_ERROR);
    return -1;
  }

  return s->handshake_func(s);
}

long SSL_get_default_timeout(const SSL *s) {
  return SSL_DEFAULT_SESSION_TIMEOUT;
}

int SSL_read(SSL *s, void *buf, int num) {
  if (s->handshake_func == 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_read, SSL_R_UNINITIALIZED);
    return -1;
  }

  if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
    s->rwstate = SSL_NOTHING;
    return 0;
  }

  return s->method->ssl_read(s, buf, num);
}

int SSL_peek(SSL *s, void *buf, int num) {
  if (s->handshake_func == 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_peek, SSL_R_UNINITIALIZED);
    return -1;
  }

  if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
    return 0;
  }

  return s->method->ssl_peek(s, buf, num);
}

int SSL_write(SSL *s, const void *buf, int num) {
  if (s->handshake_func == 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_write, SSL_R_UNINITIALIZED);
    return -1;
  }

  if (s->shutdown & SSL_SENT_SHUTDOWN) {
    s->rwstate = SSL_NOTHING;
    OPENSSL_PUT_ERROR(SSL, SSL_write, SSL_R_PROTOCOL_IS_SHUTDOWN);
    return -1;
  }

  return s->method->ssl_write(s, buf, num);
}

int SSL_shutdown(SSL *s) {
  /* Note that this function behaves differently from what one might expect.
   * Return values are 0 for no success (yet), 1 for success; but calling it
   * once is usually not enough, even if blocking I/O is used (see
   * ssl3_shutdown). */

  if (s->handshake_func == 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_shutdown, SSL_R_UNINITIALIZED);
    return -1;
  }

  if (!SSL_in_init(s)) {
    return s->method->ssl_shutdown(s);
  }

  return 1;
}

int SSL_renegotiate(SSL *s) {
  if (SSL_IS_DTLS(s)) {
    /* Renegotiation is not supported for DTLS. */
    OPENSSL_PUT_ERROR(SSL, SSL_renegotiate, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }

  if (s->renegotiate == 0) {
    s->renegotiate = 1;
  }

  s->new_session = 1;
  return s->method->ssl_renegotiate(s);
}

int SSL_renegotiate_pending(SSL *s) {
  /* becomes true when negotiation is requested; false again once a handshake
   * has finished */
  return s->renegotiate != 0;
}

long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) {
  long l;

  switch (cmd) {
    case SSL_CTRL_GET_READ_AHEAD:
      return s->read_ahead;

    case SSL_CTRL_SET_READ_AHEAD:
      l = s->read_ahead;
      s->read_ahead = larg;
      return l;

    case SSL_CTRL_SET_MSG_CALLBACK_ARG:
      s->msg_callback_arg = parg;
      return 1;

    case SSL_CTRL_OPTIONS:
      return s->options |= larg;

    case SSL_CTRL_CLEAR_OPTIONS:
      return s->options &= ~larg;

    case SSL_CTRL_MODE:
      return s->mode |= larg;

    case SSL_CTRL_CLEAR_MODE:
      return s->mode &= ~larg;

    case SSL_CTRL_GET_MAX_CERT_LIST:
      return s->max_cert_list;

    case SSL_CTRL_SET_MAX_CERT_LIST:
      l = s->max_cert_list;
      s->max_cert_list = larg;
      return l;

    case SSL_CTRL_SET_MTU:
      if (larg < (long)dtls1_min_mtu()) {
        return 0;
      }
      if (SSL_IS_DTLS(s)) {
        s->d1->mtu = larg;
        return larg;
      }
      return 0;

    case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
      if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) {
        return 0;
      }
      s->max_send_fragment = larg;
      return 1;

    case SSL_CTRL_GET_RI_SUPPORT:
      if (s->s3) {
        return s->s3->send_connection_binding;
      }
      return 0;

    case SSL_CTRL_CERT_FLAGS:
      return s->cert->cert_flags |= larg;

    case SSL_CTRL_CLEAR_CERT_FLAGS:
      return s->cert->cert_flags &= ~larg;

    case SSL_CTRL_GET_RAW_CIPHERLIST:
      if (parg) {
        if (s->cert->ciphers_raw == NULL) {
          return 0;
        }
        *(uint8_t **)parg = s->cert->ciphers_raw;
        return (int)s->cert->ciphers_rawlen;
      }

      /* Passing a NULL |parg| returns the size of a single
       * cipher suite value. */
      return 2;

    default:
      return s->method->ssl_ctrl(s, cmd, larg, parg);
  }
}

long SSL_callback_ctrl(SSL *s, int cmd, void (*fp)(void)) {
  switch (cmd) {
    case SSL_CTRL_SET_MSG_CALLBACK:
      s->msg_callback =
          (void (*)(int write_p, int version, int content_type, const void *buf,
                    size_t len, SSL *ssl, void *arg))(fp);
      return 1;

    default:
      return s->method->ssl_callback_ctrl(s, cmd, fp);
  }
}

LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) { return ctx->sessions; }

long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) {
  long l;

  switch (cmd) {
    case SSL_CTRL_GET_READ_AHEAD:
      return ctx->read_ahead;

    case SSL_CTRL_SET_READ_AHEAD:
      l = ctx->read_ahead;
      ctx->read_ahead = larg;
      return l;

    case SSL_CTRL_SET_MSG_CALLBACK_ARG:
      ctx->msg_callback_arg = parg;
      return 1;

    case SSL_CTRL_GET_MAX_CERT_LIST:
      return ctx->max_cert_list;

    case SSL_CTRL_SET_MAX_CERT_LIST:
      l = ctx->max_cert_list;
      ctx->max_cert_list = larg;
      return l;

    case SSL_CTRL_SET_SESS_CACHE_SIZE:
      l = ctx->session_cache_size;
      ctx->session_cache_size = larg;
      return l;

    case SSL_CTRL_GET_SESS_CACHE_SIZE:
      return ctx->session_cache_size;

    case SSL_CTRL_SET_SESS_CACHE_MODE:
      l = ctx->session_cache_mode;
      ctx->session_cache_mode = larg;
      return l;

    case SSL_CTRL_GET_SESS_CACHE_MODE:
      return ctx->session_cache_mode;

    case SSL_CTRL_SESS_NUMBER:
      return lh_SSL_SESSION_num_items(ctx->sessions);

    case SSL_CTRL_SESS_CONNECT:
      return ctx->stats.sess_connect;

    case SSL_CTRL_SESS_CONNECT_GOOD:
      return ctx->stats.sess_connect_good;

    case SSL_CTRL_SESS_CONNECT_RENEGOTIATE:
      return ctx->stats.sess_connect_renegotiate;

    case SSL_CTRL_SESS_ACCEPT:
      return ctx->stats.sess_accept;

    case SSL_CTRL_SESS_ACCEPT_GOOD:
      return ctx->stats.sess_accept_good;

    case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE:
      return ctx->stats.sess_accept_renegotiate;

    case SSL_CTRL_SESS_HIT:
      return ctx->stats.sess_hit;

    case SSL_CTRL_SESS_CB_HIT:
      return ctx->stats.sess_cb_hit;

    case SSL_CTRL_SESS_MISSES:
      return ctx->stats.sess_miss;

    case SSL_CTRL_SESS_TIMEOUTS:
      return ctx->stats.sess_timeout;

    case SSL_CTRL_SESS_CACHE_FULL:
      return ctx->stats.sess_cache_full;

    case SSL_CTRL_OPTIONS:
      return ctx->options |= larg;

    case SSL_CTRL_CLEAR_OPTIONS:
      return ctx->options &= ~larg;

    case SSL_CTRL_MODE:
      return ctx->mode |= larg;

    case SSL_CTRL_CLEAR_MODE:
      return ctx->mode &= ~larg;

    case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
      if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) {
        return 0;
      }
      ctx->max_send_fragment = larg;
      return 1;

    case SSL_CTRL_CERT_FLAGS:
      return ctx->cert->cert_flags |= larg;

    case SSL_CTRL_CLEAR_CERT_FLAGS:
      return ctx->cert->cert_flags &= ~larg;

    default:
      return ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg);
  }
}

long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) {
  switch (cmd) {
    case SSL_CTRL_SET_MSG_CALLBACK:
      ctx->msg_callback =
          (void (*)(int write_p, int version, int content_type, const void *buf,
                    size_t len, SSL *ssl, void *arg))(fp);
      return 1;

    default:
      return ctx->method->ssl_ctx_callback_ctrl(ctx, cmd, fp);
  }
}

int ssl_cipher_id_cmp(const void *in_a, const void *in_b) {
  long l;
  const SSL_CIPHER *a = in_a;
  const SSL_CIPHER *b = in_b;
  const long a_id = a->id;
  const long b_id = b->id;

  l = a_id - b_id;
  if (l == 0L) {
    return 0;
  } else {
    return (l > 0) ? 1 : -1;
  }
}

int ssl_cipher_ptr_id_cmp(const SSL_CIPHER **ap, const SSL_CIPHER **bp) {
  long l;
  const long a_id = (*ap)->id;
  const long b_id = (*bp)->id;

  l = a_id - b_id;
  if (l == 0) {
    return 0;
  } else {
    return (l > 0) ? 1 : -1;
  }
}

/* return a STACK of the ciphers available for the SSL and in order of
 * preference */
STACK_OF(SSL_CIPHER) * SSL_get_ciphers(const SSL *s) {
  if (s == NULL) {
    return NULL;
  }

  if (s->cipher_list != NULL) {
    return s->cipher_list->ciphers;
  }

  if (s->version >= TLS1_1_VERSION && s->ctx != NULL &&
      s->ctx->cipher_list_tls11 != NULL) {
    return s->ctx->cipher_list_tls11->ciphers;
  }

  if (s->ctx != NULL && s->ctx->cipher_list != NULL) {
    return s->ctx->cipher_list->ciphers;
  }

  return NULL;
}

/* return a STACK of the ciphers available for the SSL and in order of
 * algorithm id */
STACK_OF(SSL_CIPHER) * ssl_get_ciphers_by_id(SSL *s) {
  if (s == NULL) {
    return NULL;
  }

  if (s->cipher_list_by_id != NULL) {
    return s->cipher_list_by_id;
  }

  if (s->ctx != NULL && s->ctx->cipher_list_by_id != NULL) {
    return s->ctx->cipher_list_by_id;
  }

  return NULL;
}

/* The old interface to get the same thing as SSL_get_ciphers() */
const char *SSL_get_cipher_list(const SSL *s, int n) {
  const SSL_CIPHER *c;
  STACK_OF(SSL_CIPHER) * sk;

  if (s == NULL) {
    return NULL;
  }

  sk = SSL_get_ciphers(s);
  if (sk == NULL || n < 0 || (size_t)n >= sk_SSL_CIPHER_num(sk)) {
    return NULL;
  }

  c = sk_SSL_CIPHER_value(sk, n);
  if (c == NULL) {
    return NULL;
  }

  return c->name;
}

/* specify the ciphers to be used by default by the SSL_CTX */
int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) {
  STACK_OF(SSL_CIPHER) *sk;

  sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list,
                              &ctx->cipher_list_by_id, str, ctx->cert);
  /* ssl_create_cipher_list may return an empty stack if it was unable to find
   * a cipher matching the given rule string (for example if the rule string
   * specifies a cipher which has been disabled). This is not an error as far
   * as ssl_create_cipher_list is concerned, and hence ctx->cipher_list and
   * ctx->cipher_list_by_id has been updated. */
  if (sk == NULL) {
    return 0;
  } else if (sk_SSL_CIPHER_num(sk) == 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_cipher_list, SSL_R_NO_CIPHER_MATCH);
    return 0;
  }

  return 1;
}

int SSL_CTX_set_cipher_list_tls11(SSL_CTX *ctx, const char *str) {
  STACK_OF(SSL_CIPHER) *sk;

  sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list_tls11, NULL, str,
                              ctx->cert);
  if (sk == NULL) {
    return 0;
  } else if (sk_SSL_CIPHER_num(sk) == 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_cipher_list_tls11,
                      SSL_R_NO_CIPHER_MATCH);
    return 0;
  }

  return 1;
}

/* specify the ciphers to be used by the SSL */
int SSL_set_cipher_list(SSL *s, const char *str) {
  STACK_OF(SSL_CIPHER) *sk;

  sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list,
                              &s->cipher_list_by_id, str, s->cert);

  /* see comment in SSL_CTX_set_cipher_list */
  if (sk == NULL) {
    return 0;
  } else if (sk_SSL_CIPHER_num(sk) == 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_set_cipher_list, SSL_R_NO_CIPHER_MATCH);
    return 0;
  }

  return 1;
}

int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p) {
  size_t i;
  const SSL_CIPHER *c;
  CERT *ct = s->cert;
  uint8_t *q;
  /* Set disabled masks for this session */
  ssl_set_client_disabled(s);

  if (sk == NULL) {
    return 0;
  }
  q = p;

  for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
    c = sk_SSL_CIPHER_value(sk, i);
    /* Skip disabled ciphers */
    if (c->algorithm_ssl & ct->mask_ssl ||
        c->algorithm_mkey & ct->mask_k ||
        c->algorithm_auth & ct->mask_a) {
      continue;
    }
    s2n(ssl3_get_cipher_value(c), p);
  }

  /* If all ciphers were disabled, return the error to the caller. */
  if (p == q) {
    return 0;
  }

  /* Add SCSVs. */
  if (!s->renegotiate) {
    s2n(SSL3_CK_SCSV & 0xffff, p);
  }

  if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) {
    s2n(SSL3_CK_FALLBACK_SCSV & 0xffff, p);
  }

  return p - q;
}

STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
  CBS cipher_suites = *cbs;
  const SSL_CIPHER *c;
  STACK_OF(SSL_CIPHER) * sk;

  if (s->s3) {
    s->s3->send_connection_binding = 0;
  }

  if (CBS_len(&cipher_suites) % 2 != 0) {
    OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
                      SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
    return NULL;
  }

  sk = sk_SSL_CIPHER_new_null();
  if (sk == NULL) {
    OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  if (!CBS_stow(&cipher_suites, &s->cert->ciphers_raw,
                &s->cert->ciphers_rawlen)) {
    OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  while (CBS_len(&cipher_suites) > 0) {
    uint16_t cipher_suite;

    if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
      OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_INTERNAL_ERROR);
      goto err;
    }

    /* Check for SCSV. */
    if (s->s3 && cipher_suite == (SSL3_CK_SCSV & 0xffff)) {
      /* SCSV is fatal if renegotiating. */
      if (s->renegotiate) {
        OPENSSL_PUT_ERROR(SSL, 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;
      continue;
    }

    /* Check for FALLBACK_SCSV. */
    if (s->s3 && cipher_suite == (SSL3_CK_FALLBACK_SCSV & 0xffff)) {
      uint16_t max_version = ssl3_get_max_server_version(s);
      if (SSL_IS_DTLS(s) ? (uint16_t)s->version > max_version
                         : (uint16_t)s->version < max_version) {
        OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
                          SSL_R_INAPPROPRIATE_FALLBACK);
        ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_INAPPROPRIATE_FALLBACK);
        goto err;
      }
      continue;
    }

    c = ssl3_get_cipher_by_value(cipher_suite);
    if (c != NULL && !sk_SSL_CIPHER_push(sk, c)) {
      OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
      goto err;
    }
  }

  return sk;

err:
  if (sk != NULL) {
    sk_SSL_CIPHER_free(sk);
  }
  return NULL;
}


/* return a servername extension value if provided in Client Hello, or NULL. So
 * far, only host_name types are defined (RFC 3546). */
const char *SSL_get_servername(const SSL *s, const int type) {
  if (type != TLSEXT_NAMETYPE_host_name) {
    return NULL;
  }

  return s->session && !s->tlsext_hostname ? s->session->tlsext_hostname
                                           : s->tlsext_hostname;
}

int SSL_get_servername_type(const SSL *s) {
  if (s->session &&
      (!s->tlsext_hostname ? s->session->tlsext_hostname : s->tlsext_hostname)) {
    return TLSEXT_NAMETYPE_host_name;
  }

  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) {
  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) {
  ssl->ocsp_stapling_enabled = 1;
  return 1;
}

void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out,
                                         size_t *out_len) {
  SSL_SESSION *session = ssl->session;

  *out_len = 0;
  *out = NULL;
  if (ssl->server || !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, const uint8_t **out,
                            size_t *out_len) {
  SSL_SESSION *session = ssl->session;

  *out_len = 0;
  *out = NULL;
  if (ssl->server || !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.
 *
 * The protocol data is assumed to be a vector of 8-bit, length prefixed byte
 * strings. The length byte itself is not included in the length. A byte
 * string of length 0 is invalid. No byte string may be truncated.
 *
 * The current, but experimental algorithm for selecting the protocol is:
 *
 * 1) If the server doesn't support NPN then this is indicated to the
 * callback. In this case, the client application has to abort the connection
 * or have a default application level protocol.
 *
 * 2) If the server supports NPN, but advertises an empty list then the
 * client selects the first protcol in its list, but indicates via the
 * API that this fallback case was enacted.
 *
 * 3) Otherwise, the client finds the first protocol in the server's list
 * that it supports and selects this protocol. This is because it's
 * assumed that the server has better information about which protocol
 * a client should use.
 *
 * 4) If the client doesn't support any of the server's advertised
 * protocols, then this is treated the same as case 2.
 *
 * It returns either
 * OPENSSL_NPN_NEGOTIATED if a common protocol was found, or
 * OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
 */
int SSL_select_next_proto(uint8_t **out, uint8_t *outlen, const uint8_t *server,
                          unsigned int server_len, const uint8_t *client,
                          unsigned int client_len) {
  unsigned int i, j;
  const uint8_t *result;
  int status = OPENSSL_NPN_UNSUPPORTED;

  /* For each protocol in server preference order, see if we support it. */
  for (i = 0; i < server_len;) {
    for (j = 0; j < client_len;) {
      if (server[i] == client[j] &&
          memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) {
        /* We found a match */
        result = &server[i];
        status = OPENSSL_NPN_NEGOTIATED;
        goto found;
      }
      j += client[j];
      j++;
    }
    i += server[i];
    i++;
  }

  /* There's no overlap between our protocols and the server's list. */
  result = client;
  status = OPENSSL_NPN_NO_OVERLAP;

found:
  *out = (uint8_t *)result + 1;
  *outlen = result[0];
  return status;
}

/* 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.
 *
 * Note that the client can request any protocol it chooses. The value returned
 * from this function need not be a member of the list of supported protocols
 * provided by the callback. */
void SSL_get0_next_proto_negotiated(const SSL *s, const uint8_t **data,
                                    unsigned *len) {
  *data = s->next_proto_negotiated;
  if (!*data) {
    *len = 0;
  } else {
    *len = s->next_proto_negotiated_len;
  }
}

/* SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when a
 * TLS server needs a list of supported protocols for Next Protocol
 * Negotiation. The returned list must be in wire format.  The list is returned
 * by setting |out| to point to it and |outlen| to its length. This memory will
 * not be modified, but one should assume that the SSL* keeps a reference to
 * it.
 *
 * The callback should return SSL_TLSEXT_ERR_OK if it wishes to advertise.
 * Otherwise, no such extension will be included in the ServerHello. */
void SSL_CTX_set_next_protos_advertised_cb(
    SSL_CTX *ctx,
    int (*cb)(SSL *ssl, const uint8_t **out, unsigned int *outlen, void *arg),
    void *arg) {
  ctx->next_protos_advertised_cb = cb;
  ctx->next_protos_advertised_cb_arg = arg;
}

/* SSL_CTX_set_next_proto_select_cb sets a callback that is called when a
 * client needs to select a protocol from the server's provided list. |out|
 * must be set to point to the selected protocol (which may be within |in|).
 * The length of the protocol name must be written into |outlen|. The server's
 * advertised protocols are provided in |in| and |inlen|. The callback can
 * assume that |in| is syntactically valid.
 *
 * The client must select a protocol. It is fatal to the connection if this
 * callback returns a value other than SSL_TLSEXT_ERR_OK.
 */
void SSL_CTX_set_next_proto_select_cb(
    SSL_CTX *ctx, int (*cb)(SSL *s, uint8_t **out, uint8_t *outlen,
                            const uint8_t *in, unsigned int inlen, void *arg),
    void *arg) {
  ctx->next_proto_select_cb = cb;
  ctx->next_proto_select_cb_arg = arg;
}

int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos,
                            unsigned protos_len) {
  if (ctx->alpn_client_proto_list) {
    OPENSSL_free(ctx->alpn_client_proto_list);
  }

  ctx->alpn_client_proto_list = BUF_memdup(protos, protos_len);
  if (!ctx->alpn_client_proto_list) {
    return 1;
  }
  ctx->alpn_client_proto_list_len = protos_len;

  return 0;
}

int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) {
  if (ssl->alpn_client_proto_list) {
    OPENSSL_free(ssl->alpn_client_proto_list);
  }

  ssl->alpn_client_proto_list = BUF_memdup(protos, protos_len);
  if (!ssl->alpn_client_proto_list) {
    return 1;
  }
  ssl->alpn_client_proto_list_len = protos_len;

  return 0;
}

/* SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called
 * during ClientHello processing in order to select an ALPN protocol from the
 * client's list of offered protocols. */
void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
                                int (*cb)(SSL *ssl, const uint8_t **out,
                                          uint8_t *outlen, const uint8_t *in,
                                          unsigned int inlen, void *arg),
                                void *arg) {
  ctx->alpn_select_cb = cb;
  ctx->alpn_select_cb_arg = arg;
}

/* SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|.
 * On return it sets |*data| to point to |*len| bytes of protocol name (not
 * including the leading length-prefix byte). If the server didn't respond with
 * a negotiated protocol then |*len| will be zero. */
void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **data,
                            unsigned *len) {
  *data = NULL;
  if (ssl->s3) {
    *data = ssl->s3->alpn_selected;
  }
  if (*data == NULL) {
    *len = 0;
  } else {
    *len = ssl->s3->alpn_selected_len;
  }
}

int SSL_export_keying_material(SSL *s, uint8_t *out, size_t olen,
                               const char *label, size_t llen, const uint8_t *p,
                               size_t plen, int use_context) {
  if (s->version < TLS1_VERSION) {
    return -1;
  }

  return s->enc_method->export_keying_material(s, out, olen, label, llen, p,
                                               plen, use_context);
}

static uint32_t ssl_session_hash(const SSL_SESSION *a) {
  uint32_t hash =
      ((uint32_t)a->session_id[0]) ||
      ((uint32_t)a->session_id[1] << 8) ||
      ((uint32_t)a->session_id[2] << 16) ||
      ((uint32_t)a->session_id[3] << 24);

  return hash;
}

/* NB: If this function (or indeed the hash function which uses a sort of
 * coarser function than this one) is changed, ensure
 * 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. */
static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) {
  if (a->ssl_version != b->ssl_version) {
    return 1;
  }

  if (a->session_id_length != b->session_id_length) {
    return 1;
  }

  return memcmp(a->session_id, b->session_id, a->session_id_length);
}

SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) {
  SSL_CTX *ret = NULL;

  if (meth == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_NULL_SSL_METHOD_PASSED);
    return NULL;
  }

  if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
    goto err;
  }

  ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
  if (ret == NULL) {
    goto err;
  }

  memset(ret, 0, sizeof(SSL_CTX));

  ret->method = meth->method;

  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 */
  ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;

  ret->new_session_cb = 0;
  ret->remove_session_cb = 0;
  ret->get_session_cb = 0;
  ret->generate_session_id = 0;

  memset((char *)&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;
  ret->cert = ssl_cert_new();
  if (ret->cert == NULL) {
    goto err;
  }

  ret->default_passwd_callback = 0;
  ret->default_passwd_callback_userdata = NULL;
  ret->client_cert_cb = 0;

  ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
  if (ret->sessions == NULL) {
    goto err;
  }
  ret->cert_store = X509_STORE_new();
  if (ret->cert_store == NULL) {
    goto err;
  }

  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->ciphers) <= 0) {
    OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_LIBRARY_HAS_NO_CIPHERS);
    goto err2;
  }

  ret->param = X509_VERIFY_PARAM_new();
  if (!ret->param) {
    goto err;
  }

  ret->client_CA = sk_X509_NAME_new_null();
  if (ret->client_CA == NULL) {
    goto err;
  }

  CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data);

  ret->extra_certs = NULL;

  ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;

  ret->tlsext_servername_callback = 0;
  ret->tlsext_servername_arg = NULL;
  /* Setup RFC4507 ticket keys */
  if (!RAND_bytes(ret->tlsext_tick_key_name, 16) ||
      !RAND_bytes(ret->tlsext_tick_hmac_key, 16) ||
      !RAND_bytes(ret->tlsext_tick_aes_key, 16)) {
    ret->options |= SSL_OP_NO_TICKET;
  }

  ret->tlsext_status_cb = 0;
  ret->tlsext_status_arg = NULL;

  ret->next_protos_advertised_cb = 0;
  ret->next_proto_select_cb = 0;
  ret->psk_identity_hint = NULL;
  ret->psk_client_callback = NULL;
  ret->psk_server_callback = NULL;

  /* Default is to connect to non-RI servers. When RI is more widely deployed
   * might change this. */
  ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;

  /* Lock the SSL_CTX to the specified version, for compatibility with legacy
   * uses of SSL_METHOD. */
  if (meth->version != 0) {
    SSL_CTX_set_max_version(ret, meth->version);
    SSL_CTX_set_min_version(ret, meth->version);
  }

  return ret;

err:
  OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, ERR_R_MALLOC_FAILURE);
err2:
  if (ret != NULL) {
    SSL_CTX_free(ret);
  }
  return NULL;
}

void SSL_CTX_free(SSL_CTX *a) {
  int i;

  if (a == NULL) {
    return;
  }

  i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_SSL_CTX);
  if (i > 0) {
    return;
  }

  if (a->param) {
    X509_VERIFY_PARAM_free(a->param);
  }

  /* Free internal session cache. However: the remove_cb() may reference the
   * ex_data of SSL_CTX, thus the ex_data store can only be removed after the
   * sessions were flushed. As the ex_data handling routines might also touch
   * the session cache, the most secure solution seems to be: empty (flush) the
   * cache, then free ex_data, then finally free the cache. (See ticket
   * [openssl.org #212].) */
  if (a->sessions != NULL) {
    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) {
    ssl_cipher_preference_list_free(a->cipher_list);
  }
  if (a->cipher_list_by_id != NULL) {
    sk_SSL_CIPHER_free(a->cipher_list_by_id);
  }
  if (a->cipher_list_tls11 != NULL) {
    ssl_cipher_preference_list_free(a->cipher_list_tls11);
  }
  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 (a->srtp_profiles) {
    sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
  }
  if (a->psk_identity_hint) {
    OPENSSL_free(a->psk_identity_hint);
  }
  if (a->tlsext_ecpointformatlist) {
    OPENSSL_free(a->tlsext_ecpointformatlist);
  }
  if (a->tlsext_ellipticcurvelist) {
    OPENSSL_free(a->tlsext_ellipticcurvelist);
  }
  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);
}

void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) {
  ctx->default_passwd_callback = cb;
}

void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) {
  ctx->default_passwd_callback_userdata = u;
}

void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
                                      int (*cb)(X509_STORE_CTX *, void *),
                                      void *arg) {
  ctx->app_verify_callback = cb;
  ctx->app_verify_arg = arg;
}

void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
                        int (*cb)(int, X509_STORE_CTX *)) {
  ctx->verify_mode = mode;
  ctx->default_verify_callback = cb;
}

void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) {
  X509_VERIFY_PARAM_set_depth(ctx->param, depth);
}

void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb)(SSL *ssl, void *arg),
                         void *arg) {
  ssl_cert_set_cert_cb(c->cert, cb, arg);
}

void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg), void *arg) {
  ssl_cert_set_cert_cb(s->cert, cb, arg);
}

static int ssl_has_key(SSL *s, size_t idx) {
  CERT_PKEY *cpk = &s->cert->pkeys[idx];
  return cpk->x509 && cpk->privatekey;
}

void ssl_get_compatible_server_ciphers(SSL *s, unsigned long *out_mask_k,
                                       unsigned long *out_mask_a) {
  CERT *c = s->cert;
  int rsa_enc, rsa_sign, dh_tmp;
  unsigned long mask_k, mask_a;
  int have_ecc_cert, ecdsa_ok;
  int have_ecdh_tmp;
  X509 *x;

  if (c == NULL) {
    /* TODO(davidben): Is this codepath possible? */
    *out_mask_k = 0;
    *out_mask_a = 0;
    return;
  }

  dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL);

  have_ecdh_tmp = (c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto);
  rsa_enc = ssl_has_key(s, SSL_PKEY_RSA_ENC);
  rsa_sign = ssl_has_key(s, SSL_PKEY_RSA_SIGN);
  have_ecc_cert = ssl_has_key(s, SSL_PKEY_ECC);
  mask_k = 0;
  mask_a = 0;

  if (rsa_enc) {
    mask_k |= SSL_kRSA;
  }
  if (dh_tmp) {
    mask_k |= SSL_kEDH;
  }
  if (rsa_enc || rsa_sign) {
    mask_a |= SSL_aRSA;
  }

  mask_a |= SSL_aNULL;

  /* An ECC certificate may be usable for ECDSA cipher suites depending on the
   * key usage extension and on the client's curve preferences. */
  if (have_ecc_cert) {
    x = c->pkeys[SSL_PKEY_ECC].x509;
    /* This call populates extension flags (ex_flags). */
    X509_check_purpose(x, -1, 0);
    ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE)
                   ? (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)
                   : 1;
    if (!tls1_check_ec_cert(s, x)) {
      ecdsa_ok = 0;
    }
    if (ecdsa_ok) {
      mask_a |= SSL_aECDSA;
    }
  }

  /* If we are considering an ECC cipher suite that uses an ephemeral EC
   * key, check it. */
  if (have_ecdh_tmp && tls1_check_ec_tmp_key(s)) {
    mask_k |= SSL_kEECDH;
  }

  /* PSK requires a server callback. */
  if (s->psk_server_callback != NULL) {
    mask_k |= SSL_kPSK;
    mask_a |= SSL_aPSK;
  }

  *out_mask_k = mask_k;
  *out_mask_a = mask_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)))

int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) {
  unsigned long alg_a;
  int signature_nid = 0, md_nid = 0, pk_nid = 0;
  const SSL_CIPHER *cs = s->s3->tmp.new_cipher;

  alg_a = cs->algorithm_auth;

  /* 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);
  }
  if (alg_a & SSL_aECDSA) {
    /* key usage, if present, must allow signing */
    if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) {
      OPENSSL_PUT_ERROR(SSL, ssl_check_srvr_ecc_cert_and_alg,
                        SSL_R_ECC_CERT_NOT_FOR_SIGNING);
      return 0;
    }
  }

  return 1; /* all checks are ok */
}

static int ssl_get_server_cert_index(const SSL *s) {
  int idx;
  idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
  if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509) {
    idx = SSL_PKEY_RSA_SIGN;
  }
  if (idx == -1) {
    OPENSSL_PUT_ERROR(SSL, ssl_get_server_cert_index, ERR_R_INTERNAL_ERROR);
  }
  return idx;
}

CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) {
  int i = ssl_get_server_cert_index(s);

  /* This may or may not be an error. */
  if (i < 0) {
    return NULL;
  }

  /* May be NULL. */
  return &s->cert->pkeys[i];
}

EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher) {
  unsigned long alg_a;
  CERT *c;
  int idx = -1;

  alg_a = cipher->algorithm_auth;
  c = s->cert;

  if (alg_a & SSL_aRSA) {
    if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) {
      idx = SSL_PKEY_RSA_SIGN;
    } else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) {
      idx = SSL_PKEY_RSA_ENC;
    }
  } else if ((alg_a & SSL_aECDSA) &&
             (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) {
    idx = SSL_PKEY_ECC;
  }

  if (idx == -1) {
    OPENSSL_PUT_ERROR(SSL, ssl_get_sign_pkey, ERR_R_INTERNAL_ERROR);
    return NULL;
  }

  return c->pkeys[idx].privatekey;
}

void ssl_update_cache(SSL *s, int mode) {
  int i;

  /* If the session_id_length is 0, we are not supposed to cache it, and it
   * would be rather hard to do anyway :-) */
  if (s->session->session_id_length == 0) {
    return;
  }

  i = s->initial_ctx->session_cache_mode;
  if ((i & mode) && !s->hit &&
      ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) ||
       SSL_CTX_add_session(s->initial_ctx, s->session)) &&
      s->initial_ctx->new_session_cb != NULL) {
    if (!s->initial_ctx->new_session_cb(s, SSL_SESSION_up_ref(s->session))) {
      SSL_SESSION_free(s->session);
    }
  }

  /* auto flush every 255 connections */
  if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && ((i & mode) == mode)) {
    if ((((mode & SSL_SESS_CACHE_CLIENT)
              ? s->initial_ctx->stats.sess_connect_good
              : s->initial_ctx->stats.sess_accept_good) &
         0xff) == 0xff) {
      SSL_CTX_flush_sessions(s->initial_ctx, (unsigned long)time(NULL));
    }
  }
}

int SSL_get_error(const SSL *s, int ret_code) {
  int reason;
  uint32_t err;
  BIO *bio;

  if (ret_code > 0) {
    return SSL_ERROR_NONE;
  }

  /* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
   * where we do encode the error */
  err = ERR_peek_error();
  if (err != 0) {
    if (ERR_GET_LIB(err) == ERR_LIB_SYS) {
      return SSL_ERROR_SYSCALL;
    }
    return SSL_ERROR_SSL;
  }

  if (ret_code == 0) {
    if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) &&
        (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) {
      /* The socket was cleanly shut down with a close_notify. */
      return SSL_ERROR_ZERO_RETURN;
    }
    /* An EOF was observed which violates the protocol, and the underlying
     * transport does not participate in the error queue. Bubble up to the
     * caller. */
    return SSL_ERROR_SYSCALL;
  }

  if (SSL_want_session(s)) {
    return SSL_ERROR_PENDING_SESSION;
  }

  if (SSL_want_certificate(s)) {
    return SSL_ERROR_PENDING_CERTIFICATE;
  }

  if (SSL_want_read(s)) {
    bio = SSL_get_rbio(s);
    if (BIO_should_read(bio)) {
      return SSL_ERROR_WANT_READ;
    }

    if (BIO_should_write(bio)) {
      /* This one doesn't make too much sense ... We never try to write to the
       * rbio, and an application program where rbio and wbio are separate
       * couldn't even know what it should wait for. However if we ever set
       * s->rwstate incorrectly (so that we have SSL_want_read(s) instead of
       * SSL_want_write(s)) and rbio and wbio *are* the same, this test works
       * around that bug; so it might be safer to keep it. */
      return SSL_ERROR_WANT_WRITE;
    }

    if (BIO_should_io_special(bio)) {
      reason = BIO_get_retry_reason(bio);
      if (reason == BIO_RR_CONNECT) {
        return SSL_ERROR_WANT_CONNECT;
      }

      if (reason == BIO_RR_ACCEPT) {
        return SSL_ERROR_WANT_ACCEPT;
      }

      return SSL_ERROR_SYSCALL; /* unknown */
    }
  }

  if (SSL_want_write(s)) {
    bio = SSL_get_wbio(s);
    if (BIO_should_write(bio)) {
      return SSL_ERROR_WANT_WRITE;
    }

    if (BIO_should_read(bio)) {
      /* See above (SSL_want_read(s) with BIO_should_write(bio)) */
      return SSL_ERROR_WANT_READ;
    }

    if (BIO_should_io_special(bio)) {
      reason = BIO_get_retry_reason(bio);
      if (reason == BIO_RR_CONNECT) {
        return SSL_ERROR_WANT_CONNECT;
      }

      if (reason == BIO_RR_ACCEPT) {
        return SSL_ERROR_WANT_ACCEPT;
      }

      return SSL_ERROR_SYSCALL;
    }
  }

  if (SSL_want_x509_lookup(s)) {
    return SSL_ERROR_WANT_X509_LOOKUP;
  }

  if (SSL_want_channel_id_lookup(s)) {
    return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP;
  }

  return SSL_ERROR_SYSCALL;
}

int SSL_do_handshake(SSL *s) {
  int ret = 1;

  if (s->handshake_func == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_do_handshake, SSL_R_CONNECTION_TYPE_NOT_SET);
    return -1;
  }

  s->method->ssl_renegotiate_check(s);

  if (SSL_in_init(s)) {
    ret = s->handshake_func(s);
  }
  return ret;
}

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);
}

void SSL_set_connect_state(SSL *s) {
  s->server = 0;
  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);
}

int ssl_undefined_function(SSL *s) {
  OPENSSL_PUT_ERROR(SSL, ssl_undefined_function,
                    ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  return 0;
}

int ssl_undefined_void_function(void) {
  OPENSSL_PUT_ERROR(SSL, ssl_undefined_void_function,
                    ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  return 0;
}

int ssl_undefined_const_function(const SSL *s) {
  OPENSSL_PUT_ERROR(SSL, ssl_undefined_const_function,
                    ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
  return 0;
}

static const char *ssl_get_version(int version) {
  switch (version) {
    case TLS1_2_VERSION:
      return "TLSv1.2";

    case TLS1_1_VERSION:
      return "TLSv1.1";

    case TLS1_VERSION:
      return "TLSv1";

    case SSL3_VERSION:
      return "SSLv3";

    default:
      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->aead_read_ctx != NULL) {
    EVP_AEAD_CTX_cleanup(&s->aead_read_ctx->ctx);
    OPENSSL_free(s->aead_read_ctx);
    s->aead_read_ctx = NULL;
  }

  if (s->aead_write_ctx != NULL) {
    EVP_AEAD_CTX_cleanup(&s->aead_write_ctx->ctx);
    OPENSSL_free(s->aead_write_ctx);
    s->aead_write_ctx = NULL;
  }
}

X509 *SSL_get_certificate(const SSL *s) {
  if (s->cert != NULL) {
    return s->cert->key->x509;
  }

  return NULL;
}

EVP_PKEY *SSL_get_privatekey(const SSL *s) {
  if (s->cert != NULL) {
    return s->cert->key->privatekey;
  }

  return NULL;
}

X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
  if (ctx->cert != NULL) {
    return ctx->cert->key->x509;
  }

  return NULL;
}

EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) {
  if (ctx->cert != NULL) {
    return ctx->cert->key->privatekey;
  }

  return NULL;
}

const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) {
  if (s->session != NULL && s->session->cipher != NULL) {
    return s->session->cipher;
  }

  return NULL;
}

const void *SSL_get_current_compression(SSL *s) { return NULL; }

const void *SSL_get_current_expansion(SSL *s) { return NULL; }

int ssl_init_wbio_buffer(SSL *s, int push) {
  BIO *bbio;

  if (s->bbio == NULL) {
    bbio = BIO_new(BIO_f_buffer());
    if (bbio == NULL) {
      return 0;
    }
    s->bbio = bbio;
  } else {
    bbio = s->bbio;
    if (s->bbio == s->wbio) {
      s->wbio = BIO_pop(s->wbio);
    }
  }

  BIO_reset(bbio);
  if (!BIO_set_read_buffer_size(bbio, 1)) {
    OPENSSL_PUT_ERROR(SSL, ssl_init_wbio_buffer, ERR_R_BUF_LIB);
    return 0;
  }

  if (push) {
    if (s->wbio != bbio) {
      s->wbio = BIO_push(bbio, s->wbio);
    }
  } else {
    if (s->wbio == bbio) {
      s->wbio = BIO_pop(bbio);
    }
  }

  return 1;
}

void ssl_free_wbio_buffer(SSL *s) {
  if (s->bbio == NULL) {
    return;
  }

  if (s->bbio == s->wbio) {
    /* remove buffering */
    s->wbio = BIO_pop(s->wbio);
  }

  BIO_free(s->bbio);
  s->bbio = NULL;
}

void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) {
  ctx->quiet_shutdown = mode;
}

int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) {
  return ctx->quiet_shutdown;
}

void SSL_set_quiet_shutdown(SSL *s, int mode) { s->quiet_shutdown = mode; }

int SSL_get_quiet_shutdown(const SSL *s) { return s->quiet_shutdown; }

void SSL_set_shutdown(SSL *s, int mode) { s->shutdown = mode; }

int SSL_get_shutdown(const SSL *s) { return s->shutdown; }

int SSL_version(const SSL *s) { return s->version; }

SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return ssl->ctx; }

SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) {
  if (ssl->ctx == ctx) {
    return ssl->ctx;
  }

  if (ctx == NULL) {
    ctx = ssl->initial_ctx;
  }

  if (ssl->cert != NULL) {
    ssl_cert_free(ssl->cert);
  }

  ssl->cert = ssl_cert_dup(ctx->cert);
  CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
  if (ssl->ctx != NULL) {
    SSL_CTX_free(ssl->ctx); /* decrement reference count */
  }
  ssl->ctx = ctx;

  ssl->sid_ctx_length = ctx->sid_ctx_length;
  assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx));
  memcpy(ssl->sid_ctx, ctx->sid_ctx, sizeof(ssl->sid_ctx));

  return ssl->ctx;
}

int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) {
  return X509_STORE_set_default_paths(ctx->cert_store);
}

int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
                                  const char *CApath) {
  return X509_STORE_load_locations(ctx->cert_store, CAfile, CApath);
}

void SSL_set_info_callback(SSL *ssl,
                           void (*cb)(const SSL *ssl, int type, int val)) {
  ssl->info_callback = cb;
}

void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/, int /*type*/,
                                              int /*val*/) {
  return ssl->info_callback;
}

int SSL_state(const SSL *ssl) { return ssl->state; }

void SSL_set_state(SSL *ssl, int state) { ssl->state = state; }

void SSL_set_verify_result(SSL *ssl, long arg) { ssl->verify_result = arg; }

long SSL_get_verify_result(const SSL *ssl) { return ssl->verify_result; }

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) {
  return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp, new_func,
                                 dup_func, free_func);
}

int SSL_set_ex_data(SSL *s, int idx, void *arg) {
  return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
}

void *SSL_get_ex_data(const SSL *s, int idx) {
  return CRYPTO_get_ex_data(&s->ex_data, idx);
}

int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                             CRYPTO_EX_dup *dup_func,
                             CRYPTO_EX_free *free_func) {
  return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp, new_func,
                                 dup_func, free_func);
}

int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg) {
  return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
}

void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx) {
  return CRYPTO_get_ex_data(&s->ex_data, idx);
}

int ssl_ok(SSL *s) { return 1; }

X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
  return ctx->cert_store;
}

void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) {
  if (ctx->cert_store != NULL) {
    X509_STORE_free(ctx->cert_store);
  }
  ctx->cert_store = store;
}

int SSL_want(const SSL *s) { return s->rwstate; }

void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
                                  RSA *(*cb)(SSL *ssl, int is_export,
                                             int keylength)) {
  SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb);
}

void SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb)(SSL *ssl, int is_export,
                                                   int keylength)) {
  SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb);
}

void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
                                 DH *(*dh)(SSL *ssl, int is_export,
                                           int keylength)) {
  SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh);
}

void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh)(SSL *ssl, int is_export,
                                                 int keylength)) {
  SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh);
}

void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
                                   EC_KEY *(*ecdh)(SSL *ssl, int is_export,
                                                   int keylength)) {
  SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH_CB, (void (*)(void))ecdh);
}

void SSL_set_tmp_ecdh_callback(SSL *ssl,
                               EC_KEY *(*ecdh)(SSL *ssl, int is_export,
                                               int keylength)) {
  SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_ECDH_CB, (void (*)(void))ecdh);
}

int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) {
  if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
    OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_psk_identity_hint,
                      SSL_R_DATA_LENGTH_TOO_LONG);
    return 0;
  }

  if (ctx->psk_identity_hint != NULL) {
    OPENSSL_free(ctx->psk_identity_hint);
  }

  if (identity_hint != NULL) {
    ctx->psk_identity_hint = BUF_strdup(identity_hint);
    if (ctx->psk_identity_hint == NULL) {
      return 0;
    }
  } else {
    ctx->psk_identity_hint = NULL;
  }

  return 1;
}

int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) {
  if (s == NULL) {
    return 0;
  }

  if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
    OPENSSL_PUT_ERROR(SSL, SSL_use_psk_identity_hint,
                      SSL_R_DATA_LENGTH_TOO_LONG);
    return 0;
  }

  /* Clear currently configured hint, if any. */
  if (s->psk_identity_hint != NULL) {
    OPENSSL_free(s->psk_identity_hint);
    s->psk_identity_hint = NULL;
  }

  if (identity_hint != NULL) {
    s->psk_identity_hint = BUF_strdup(identity_hint);
    if (s->psk_identity_hint == NULL) {
      return 0;
    }
  }

  return 1;
}

const char *SSL_get_psk_identity_hint(const SSL *s) {
  if (s == NULL) {
    return NULL;
  }
  return s->psk_identity_hint;
}

const char *SSL_get_psk_identity(const SSL *s) {
  if (s == NULL || s->session == NULL) {
    return NULL;
  }

  return s->session->psk_identity;
}

void SSL_set_psk_client_callback(
    SSL *s, unsigned int (*cb)(SSL *ssl, const char *hint, char *identity,
                               unsigned int max_identity_len, uint8_t *psk,
                               unsigned int max_psk_len)) {
  s->psk_client_callback = cb;
}

void SSL_CTX_set_psk_client_callback(
    SSL_CTX *ctx, unsigned int (*cb)(SSL *ssl, const char *hint, char *identity,
                                     unsigned int max_identity_len,
                                     uint8_t *psk, unsigned int max_psk_len)) {
  ctx->psk_client_callback = cb;
}

void SSL_set_psk_server_callback(
    SSL *s, unsigned int (*cb)(SSL *ssl, const char *identity, uint8_t *psk,
                               unsigned int max_psk_len)) {
  s->psk_server_callback = cb;
}

void SSL_CTX_set_psk_server_callback(
    SSL_CTX *ctx, unsigned int (*cb)(SSL *ssl, const char *identity,
                                     uint8_t *psk, unsigned int max_psk_len)) {
  ctx->psk_server_callback = cb;
}

void SSL_CTX_set_min_version(SSL_CTX *ctx, uint16_t version) {
  ctx->min_version = version;
}

void SSL_CTX_set_max_version(SSL_CTX *ctx, uint16_t version) {
  ctx->max_version = version;
}

void SSL_set_min_version(SSL *ssl, uint16_t version) {
  ssl->min_version = version;
}

void SSL_set_max_version(SSL *ssl, uint16_t version) {
  ssl->max_version = version;
}

void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
                              void (*cb)(int write_p, int version,
                                         int content_type, const void *buf,
                                         size_t len, SSL *ssl, void *arg)) {
  SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
}
void SSL_set_msg_callback(SSL *ssl,
                          void (*cb)(int write_p, int version, int content_type,
                                     const void *buf, size_t len, SSL *ssl,
                                     void *arg)) {
  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_in_false_start(const SSL *s) {
  return s->s3->tmp.in_false_start;
}

int SSL_cutthrough_complete(const SSL *s) {
  return SSL_in_false_start(s);
}

void SSL_get_structure_sizes(size_t *ssl_size, size_t *ssl_ctx_size,
                             size_t *ssl_session_size) {
  *ssl_size = sizeof(SSL);
  *ssl_ctx_size = sizeof(SSL_CTX);
  *ssl_session_size = sizeof(SSL_SESSION);
}

int ssl3_can_false_start(const SSL *s) {
  const SSL_CIPHER *const cipher = SSL_get_current_cipher(s);

  /* False Start only for TLS 1.2 with a forward-secure, AEAD cipher and ALPN or
   * NPN. */
  return !SSL_IS_DTLS(s) &&
      SSL_version(s) >= TLS1_2_VERSION &&
      (s->s3->alpn_selected || s->s3->next_proto_neg_seen) &&
      cipher != NULL &&
      (cipher->algorithm_mkey == SSL_kEDH ||
       cipher->algorithm_mkey == SSL_kEECDH) &&
      (cipher->algorithm_enc == SSL_AES128GCM ||
       cipher->algorithm_enc == SSL_AES256GCM ||
       cipher->algorithm_enc == SSL_CHACHA20POLY1305);
}

const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) {
  switch (version) {
    case SSL3_VERSION:
      return &SSLv3_enc_data;

    case TLS1_VERSION:
      return &TLSv1_enc_data;

    case TLS1_1_VERSION:
      return &TLSv1_1_enc_data;

    case TLS1_2_VERSION:
      return &TLSv1_2_enc_data;

    case DTLS1_VERSION:
      return &DTLSv1_enc_data;

    case DTLS1_2_VERSION:
      return &DTLSv1_2_enc_data;

    default:
      return NULL;
  }
}

uint16_t ssl3_get_max_server_version(const SSL *s) {
  uint16_t max_version;

  if (SSL_IS_DTLS(s)) {
    max_version = (s->max_version != 0) ? s->max_version : DTLS1_2_VERSION;
    if (!(s->options & SSL_OP_NO_DTLSv1_2) && DTLS1_2_VERSION >= max_version) {
      return DTLS1_2_VERSION;
    }
    if (!(s->options & SSL_OP_NO_DTLSv1) && DTLS1_VERSION >= max_version) {
      return DTLS1_VERSION;
    }
    return 0;
  }

  max_version = (s->max_version != 0) ? s->max_version : TLS1_2_VERSION;
  if (!(s->options & SSL_OP_NO_TLSv1_2) && TLS1_2_VERSION <= max_version) {
    return TLS1_2_VERSION;
  }
  if (!(s->options & SSL_OP_NO_TLSv1_1) && TLS1_1_VERSION <= max_version) {
    return TLS1_1_VERSION;
  }
  if (!(s->options & SSL_OP_NO_TLSv1) && TLS1_VERSION <= max_version) {
    return TLS1_VERSION;
  }
  if (!(s->options & SSL_OP_NO_SSLv3) && SSL3_VERSION <= max_version) {
    return SSL3_VERSION;
  }
  return 0;
}

uint16_t ssl3_get_mutual_version(SSL *s, uint16_t client_version) {
  uint16_t version = 0;

  if (SSL_IS_DTLS(s)) {
    /* Clamp client_version to max_version. */
    if (s->max_version != 0 && client_version < s->max_version) {
      client_version = s->max_version;
    }

    if (client_version <= DTLS1_2_VERSION && !(s->options & SSL_OP_NO_DTLSv1_2)) {
      version = DTLS1_2_VERSION;
    } else if (client_version <= DTLS1_VERSION &&
               !(s->options & SSL_OP_NO_DTLSv1)) {
      version = DTLS1_VERSION;
    }

    /* Check against min_version. */
    if (version != 0 && s->min_version != 0 && version > s->min_version) {
      return 0;
    }
    return version;
  } else {
    /* Clamp client_version to max_version. */
    if (s->max_version != 0 && client_version > s->max_version) {
      client_version = s->max_version;
    }

    if (client_version >= TLS1_2_VERSION && !(s->options & SSL_OP_NO_TLSv1_2)) {
      version = TLS1_2_VERSION;
    } else if (client_version >= TLS1_1_VERSION &&
             !(s->options & SSL_OP_NO_TLSv1_1)) {
      version = TLS1_1_VERSION;
    } else if (client_version >= TLS1_VERSION && !(s->options & SSL_OP_NO_TLSv1)) {
      version = TLS1_VERSION;
    } else if (client_version >= SSL3_VERSION && !(s->options & SSL_OP_NO_SSLv3)) {
      version = SSL3_VERSION;
    }

    /* Check against min_version. */
    if (version != 0 && s->min_version != 0 && version < s->min_version) {
      return 0;
    }
    return version;
  }
}

uint16_t ssl3_get_max_client_version(SSL *s) {
  unsigned long options = s->options;
  uint16_t version = 0;

  /* OpenSSL's API for controlling versions entails blacklisting individual
   * protocols. This has two problems. First, on the client, the protocol can
   * only express a contiguous range of versions. Second, a library consumer
   * trying to set a maximum version cannot disable protocol versions that get
   * added in a future version of the library.
   *
   * To account for both of these, OpenSSL interprets the client-side bitmask
   * as a min/max range by picking the lowest contiguous non-empty range of
   * enabled protocols. Note that this means it is impossible to set a maximum
   * version of TLS 1.2 in a future-proof way.
   *
   * By this scheme, the maximum version is the lowest version V such that V is
   * enabled and V+1 is disabled or unimplemented. */
  if (SSL_IS_DTLS(s)) {
    if (!(options & SSL_OP_NO_DTLSv1_2)) {
      version = DTLS1_2_VERSION;
    }
    if (!(options & SSL_OP_NO_DTLSv1) && (options & SSL_OP_NO_DTLSv1_2)) {
      version = DTLS1_VERSION;
    }
    if (s->max_version != 0 && version < s->max_version) {
      version = s->max_version;
    }
  } else {
    if (!(options & SSL_OP_NO_TLSv1_2)) {
      version = TLS1_2_VERSION;
    }
    if (!(options & SSL_OP_NO_TLSv1_1) && (options & SSL_OP_NO_TLSv1_2)) {
      version = TLS1_1_VERSION;
    }
    if (!(options & SSL_OP_NO_TLSv1) && (options & SSL_OP_NO_TLSv1_1)) {
      version = TLS1_VERSION;
    }
    if (!(options & SSL_OP_NO_SSLv3) && (options & SSL_OP_NO_TLSv1)) {
      version = SSL3_VERSION;
    }
    if (s->max_version != 0 && version > s->max_version) {
      version = s->max_version;
    }
  }

  return version;
}

int ssl3_is_version_enabled(SSL *s, uint16_t version) {
  if (SSL_IS_DTLS(s)) {
    if (s->max_version != 0 && version < s->max_version) {
      return 0;
    }
    if (s->min_version != 0 && version > s->min_version) {
      return 0;
    }

    switch (version) {
      case DTLS1_VERSION:
        return !(s->options & SSL_OP_NO_DTLSv1);

      case DTLS1_2_VERSION:
        return !(s->options & SSL_OP_NO_DTLSv1_2);

      default:
        return 0;
    }
  } else {
    if (s->max_version != 0 && version > s->max_version) {
      return 0;
    }
    if (s->min_version != 0 && version < s->min_version) {
      return 0;
    }

    switch (version) {
      case SSL3_VERSION:
        return !(s->options & SSL_OP_NO_SSLv3);

      case TLS1_VERSION:
        return !(s->options & SSL_OP_NO_TLSv1);

      case TLS1_1_VERSION:
        return !(s->options & SSL_OP_NO_TLSv1_1);

      case TLS1_2_VERSION:
        return !(s->options & SSL_OP_NO_TLSv1_2);

      default:
        return 0;
    }
  }
}

uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version) {
  if (!SSL_IS_DTLS(s)) {
    return wire_version;
  }

  uint16_t tls_version = ~wire_version;
  uint16_t version = tls_version + 0x0201;
  /* If either component overflowed, clamp it so comparisons still work. */
  if ((version >> 8) < (tls_version >> 8)) {
    version = 0xff00 | (version & 0xff);
  }
  if ((version & 0xff) < (tls_version & 0xff)) {
    version = (version & 0xff00) | 0xff;
  }
  /* DTLS 1.0 maps to TLS 1.1, not TLS 1.0. */
  if (version == TLS1_VERSION) {
    version = TLS1_1_VERSION;
  }
  return version;
}

int SSL_cache_hit(SSL *s) { return s->hit; }

int SSL_is_server(SSL *s) { return s->server; }

void SSL_enable_fastradio_padding(SSL *s, char on_off) {
  s->fastradio_padding = on_off;
}

const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) {
  return ssl3_get_cipher_by_value(value);
}
