Add SSL_get0_verified_chain() to return verified chain of peer
[openssl.git] / ssl / ssl_lib.c
index cfc73de9cab84c3f84c841e66a835fcdd41c2762..197a37cd0d46b511ece256542fddf67bbd61b9d6 100644 (file)
@@ -190,13 +190,341 @@ struct ssl_async_args {
     SSL *s;
     void *buf;
     int num;
-    int type;
+    enum { READFUNC, WRITEFUNC,  OTHERFUNC} type;
     union {
-        int (*func1)(SSL *, void *, int);
-        int (*func2)(SSL *, const void *, int);
+        int (*func_read)(SSL *, void *, int);
+        int (*func_write)(SSL *, const void *, int);
+        int (*func_other)(SSL *);
     } f;
 };
 
+static const struct {
+    uint8_t mtype;
+    uint8_t ord;
+    int     nid;
+} dane_mds[] = {
+    { DANETLS_MATCHING_FULL, 0, NID_undef },
+    { DANETLS_MATCHING_2256, 1, NID_sha256 },
+    { DANETLS_MATCHING_2512, 2, NID_sha512 },
+};
+
+static int dane_ctx_enable(struct dane_ctx_st *dctx)
+{
+    const EVP_MD **mdevp;
+    uint8_t *mdord;
+    uint8_t mdmax = DANETLS_MATCHING_LAST;
+    int n = ((int) mdmax) + 1;          /* int to handle PrivMatch(255) */
+    size_t i;
+
+    mdevp = OPENSSL_zalloc(n * sizeof(*mdevp));
+    mdord = OPENSSL_zalloc(n * sizeof(*mdord));
+
+    if (mdord == NULL || mdevp == NULL) {
+        OPENSSL_free(mdevp);
+        SSLerr(SSL_F_DANE_CTX_ENABLE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    /* Install default entries */
+    for (i = 0; i < OSSL_NELEM(dane_mds); ++i) {
+        const EVP_MD *md;
+
+        if (dane_mds[i].nid == NID_undef ||
+            (md = EVP_get_digestbynid(dane_mds[i].nid)) == NULL)
+            continue;
+        mdevp[dane_mds[i].mtype] = md;
+        mdord[dane_mds[i].mtype] = dane_mds[i].ord;
+    }
+
+    dctx->mdevp = mdevp;
+    dctx->mdord = mdord;
+    dctx->mdmax = mdmax;
+
+    return 1;
+}
+
+static void dane_ctx_final(struct dane_ctx_st *dctx)
+{
+    OPENSSL_free(dctx->mdevp);
+    dctx->mdevp = NULL;
+
+    OPENSSL_free(dctx->mdord);
+    dctx->mdord = NULL;
+    dctx->mdmax = 0;
+}
+
+static void tlsa_free(danetls_record *t)
+{
+    if (t == NULL)
+        return;
+    OPENSSL_free(t->data);
+    EVP_PKEY_free(t->spki);
+    OPENSSL_free(t);
+}
+
+static void dane_final(struct dane_st *dane)
+{
+    sk_danetls_record_pop_free(dane->trecs, tlsa_free);
+    dane->trecs = NULL;
+
+    sk_X509_pop_free(dane->certs, X509_free);
+    dane->certs = NULL;
+
+    X509_free(dane->mcert);
+    dane->mcert = NULL;
+    dane->mtlsa = NULL;
+    dane->mdpth = -1;
+    dane->pdpth = -1;
+}
+
+/*
+ * dane_copy - Copy dane configuration, sans verification state.
+ */
+static int ssl_dane_dup(SSL *to, SSL *from)
+{
+    int num;
+    int i;
+
+    if (!DANETLS_ENABLED(&from->dane))
+        return 1;
+
+    dane_final(&to->dane);
+
+    num  = sk_danetls_record_num(from->dane.trecs);
+    for (i = 0; i < num; ++i) {
+        danetls_record *t = sk_danetls_record_value(from->dane.trecs, i);
+        if (SSL_dane_tlsa_add(to, t->usage, t->selector, t->mtype,
+                              t->data, t->dlen) <= 0)
+            return 0;
+    }
+    return 1;
+}
+
+static int dane_mtype_set(
+    struct dane_ctx_st *dctx,
+    const EVP_MD *md,
+    uint8_t mtype,
+    uint8_t ord)
+{
+    int i;
+
+    if (mtype == DANETLS_MATCHING_FULL && md != NULL) {
+        SSLerr(SSL_F_DANE_MTYPE_SET,
+                SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL);
+        return 0;
+    }
+
+    if (mtype > dctx->mdmax) {
+        const EVP_MD **mdevp;
+        uint8_t *mdord;
+        int n = ((int) mtype) + 1;
+
+        mdevp = OPENSSL_realloc(dctx->mdevp, n * sizeof(*mdevp));
+        if (mdevp == NULL) {
+            SSLerr(SSL_F_DANE_MTYPE_SET, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        dctx->mdevp = mdevp;
+
+        mdord = OPENSSL_realloc(dctx->mdord, n * sizeof(*mdord));
+        if (mdord == NULL) {
+            SSLerr(SSL_F_DANE_MTYPE_SET, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        dctx->mdord = mdord;
+
+        /* Zero-fill any gaps */
+        for (i = dctx->mdmax+1; i < mtype; ++i) {
+            mdevp[i] = NULL;
+            mdord[i] = 0;
+        }
+
+        dctx->mdmax = mtype;
+    }
+
+    dctx->mdevp[mtype] = md;
+    /* Coerce ordinal of disabled matching types to 0 */
+    dctx->mdord[mtype] = (md == NULL) ? 0 : ord;
+
+    return 1;
+}
+
+static const EVP_MD *tlsa_md_get(struct dane_st *dane, uint8_t mtype)
+{
+    if (mtype > dane->dctx->mdmax)
+        return NULL;
+    return dane->dctx->mdevp[mtype];
+}
+
+static int dane_tlsa_add(
+    struct dane_st *dane,
+    uint8_t usage,
+    uint8_t selector,
+    uint8_t mtype,
+    unsigned char *data,
+    size_t dlen)
+{
+    danetls_record *t;
+    const EVP_MD *md = NULL;
+    int ilen = (int)dlen;
+    int i;
+
+    if (dane->trecs == NULL) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_NOT_ENABLED);
+        return -1;
+    }
+
+    if (ilen < 0 || dlen != (size_t)ilen) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_DATA_LENGTH);
+        return 0;
+    }
+
+    if (usage > DANETLS_USAGE_LAST) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE);
+        return 0;
+    }
+
+    if (selector > DANETLS_SELECTOR_LAST) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_SELECTOR);
+        return 0;
+    }
+
+    if (mtype != DANETLS_MATCHING_FULL) {
+        md = tlsa_md_get(dane, mtype);
+        if (md == NULL) {
+            SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_MATCHING_TYPE);
+            return 0;
+        }
+    }
+
+    if (md != NULL && dlen != (size_t)EVP_MD_size(md)) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH);
+        return 0;
+    }
+    if (!data) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_NULL_DATA);
+        return 0;
+    }
+
+    if ((t = OPENSSL_zalloc(sizeof(*t))) == NULL) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+
+    t->usage = usage;
+    t->selector = selector;
+    t->mtype = mtype;
+    t->data = OPENSSL_malloc(ilen);
+    if (t->data == NULL) {
+        tlsa_free(t);
+        SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    memcpy(t->data, data, ilen);
+    t->dlen = ilen;
+
+    /* Validate and cache full certificate or public key */
+    if (mtype == DANETLS_MATCHING_FULL) {
+        const unsigned char *p = data;
+        X509 *cert = NULL;
+        EVP_PKEY *pkey = NULL;
+
+        switch (selector) {
+        case DANETLS_SELECTOR_CERT:
+            if (!d2i_X509(&cert, &p, dlen) || p < data ||
+                dlen != (size_t)(p - data)) {
+                tlsa_free(t);
+                SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE);
+                return 0;
+            }
+            if (X509_get0_pubkey(cert) == NULL) {
+                tlsa_free(t);
+                SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE);
+                return 0;
+            }
+
+            if ((DANETLS_USAGE_BIT(usage) & DANETLS_TA_MASK) == 0) {
+                X509_free(cert);
+                break;
+            }
+
+            /*
+             * For usage DANE-TA(2), we support authentication via "2 0 0" TLSA
+             * records that contain full certificates of trust-anchors that are
+             * not present in the wire chain.  For usage PKIX-TA(0), we augment
+             * the chain with untrusted Full(0) certificates from DNS, in case
+             * they are missing from the chain.
+             */
+            if ((dane->certs == NULL &&
+                 (dane->certs = sk_X509_new_null()) == NULL) ||
+                !sk_X509_push(dane->certs, cert)) {
+                SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
+                X509_free(cert);
+                tlsa_free(t);
+                return -1;
+            }
+            break;
+
+        case DANETLS_SELECTOR_SPKI:
+            if (!d2i_PUBKEY(&pkey, &p, dlen) || p < data ||
+                dlen != (size_t)(p - data)) {
+                tlsa_free(t);
+                SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY);
+                return 0;
+            }
+
+            /*
+             * For usage DANE-TA(2), we support authentication via "2 1 0" TLSA
+             * records that contain full bare keys of trust-anchors that are
+             * not present in the wire chain.
+             */
+            if (usage == DANETLS_USAGE_DANE_TA)
+                t->spki = pkey;
+            else
+                EVP_PKEY_free(pkey);
+            break;
+        }
+    }
+
+    /*-
+     * Find the right insertion point for the new record.
+     *
+     * See crypto/x509/x509_vfy.c.  We sort DANE-EE(3) records first, so that
+     * they can be processed first, as they require no chain building, and no
+     * expiration or hostname checks.  Because DANE-EE(3) is numerically
+     * largest, this is accomplished via descending sort by "usage".
+     *
+     * We also sort in descending order by matching ordinal to simplify
+     * the implementation of digest agility in the verification code.
+     *
+     * The choice of order for the selector is not significant, so we
+     * use the same descending order for consistency.
+     */
+    for (i = 0; i < sk_danetls_record_num(dane->trecs); ++i) {
+        danetls_record *rec = sk_danetls_record_value(dane->trecs, i);
+        if (rec->usage > usage)
+            continue;
+        if (rec->usage < usage)
+            break;
+        if (rec->selector > selector)
+            continue;
+        if (rec->selector < selector)
+            break;
+        if (dane->dctx->mdord[rec->mtype] > dane->dctx->mdord[mtype])
+            continue;
+        break;
+    }
+
+    if (!sk_danetls_record_insert(dane->trecs, t, i)) {
+        tlsa_free(t);
+        SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    dane->umask |= DANETLS_USAGE_BIT(usage);
+
+    return 1;
+}
+
 static void clear_ciphers(SSL *s)
 {
     /* clear the current cipher */
@@ -237,6 +565,16 @@ int SSL_clear(SSL *s)
     clear_ciphers(s);
     s->first_packet = 0;
 
+    /* Reset DANE verification result state */
+    s->dane.mdpth = -1;
+    s->dane.pdpth = -1;
+    X509_free(s->dane.mcert);
+    s->dane.mcert = NULL;
+    s->dane.mtlsa = NULL;
+
+    /* Clear the verification result peername */
+    X509_VERIFY_PARAM_move_peername(s->param, NULL);
+
     /*
      * Check to see if we were changed into a different method, if so, revert
      * back if we are not doing session-id reuse.
@@ -377,6 +715,7 @@ SSL *SSL_new(SSL_CTX *ctx)
         s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
     }
 
+    s->verified_chain = NULL;
     s->verify_result = X509_V_OK;
 
     s->default_passwd_callback = ctx->default_passwd_callback;
@@ -408,6 +747,11 @@ SSL *SSL_new(SSL_CTX *ctx)
     return (NULL);
 }
 
+void SSL_up_ref(SSL *s)
+{
+    CRYPTO_add(&s->references, 1, CRYPTO_LOCK_SSL);
+}
+
 int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
                                    unsigned int sid_ctx_len)
 {
@@ -497,6 +841,127 @@ int SSL_set_trust(SSL *s, int trust)
     return X509_VERIFY_PARAM_set_trust(s->param, trust);
 }
 
+int SSL_set1_host(SSL *s, const char *hostname)
+{
+    return X509_VERIFY_PARAM_set1_host(s->param, hostname, 0);
+}
+
+int SSL_add1_host(SSL *s, const char *hostname)
+{
+    return X509_VERIFY_PARAM_add1_host(s->param, hostname, 0);
+}
+
+void SSL_set_hostflags(SSL *s, unsigned int flags)
+{
+    X509_VERIFY_PARAM_set_hostflags(s->param, flags);
+}
+
+const char *SSL_get0_peername(SSL *s)
+{
+    return X509_VERIFY_PARAM_get0_peername(s->param);
+}
+
+int SSL_CTX_dane_enable(SSL_CTX *ctx)
+{
+    return dane_ctx_enable(&ctx->dane);
+}
+
+int SSL_dane_enable(SSL *s, const char *basedomain)
+{
+    struct dane_st *dane = &s->dane;
+
+    if (s->ctx->dane.mdmax == 0) {
+        SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_CONTEXT_NOT_DANE_ENABLED);
+        return 0;
+    }
+    if (dane->trecs != NULL) {
+        SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_DANE_ALREADY_ENABLED);
+        return 0;
+    }
+
+    /*
+     * Default SNI name.  This rejects empty names, while set1_host below
+     * accepts them and disables host name checks.  To avoid side-effects with
+     * invalid input, set the SNI name first.
+     */
+    if (s->tlsext_hostname == NULL) {
+       if (!SSL_set_tlsext_host_name(s, basedomain)) {
+            SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN);
+           return -1;
+        }
+    }
+
+    /* Primary RFC6125 reference identifier */
+    if (!X509_VERIFY_PARAM_set1_host(s->param, basedomain, 0)) {
+        SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN);
+        return -1;
+    }
+
+    dane->mdpth = -1;
+    dane->pdpth = -1;
+    dane->dctx = &s->ctx->dane;
+    dane->trecs = sk_danetls_record_new_null();
+
+    if (dane->trecs == NULL) {
+        SSLerr(SSL_F_SSL_DANE_ENABLE, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    return 1;
+}
+
+int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki)
+{
+    struct dane_st *dane = &s->dane;
+
+    if (!DANETLS_ENABLED(dane))
+        return -1;
+    if (dane->mtlsa) {
+        if (mcert)
+            *mcert = dane->mcert;
+        if (mspki)
+            *mspki = (dane->mcert == NULL) ? dane->mtlsa->spki : NULL;
+    }
+    return dane->mdpth;
+}
+
+int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector,
+                       uint8_t *mtype, unsigned const char **data, size_t *dlen)
+{
+    struct dane_st *dane = &s->dane;
+
+    if (!DANETLS_ENABLED(dane))
+        return -1;
+    if (dane->mtlsa) {
+        if (usage)
+            *usage = dane->mtlsa->usage;
+        if (selector)
+            *selector = dane->mtlsa->selector;
+        if (mtype)
+            *mtype = dane->mtlsa->mtype;
+        if (data)
+            *data = dane->mtlsa->data;
+        if (dlen)
+            *dlen = dane->mtlsa->dlen;
+    }
+    return dane->mdpth;
+}
+
+struct dane_st *SSL_get0_dane(SSL *s)
+{
+    return &s->dane;
+}
+
+int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector,
+                      uint8_t mtype, unsigned char *data, size_t dlen)
+{
+    return dane_tlsa_add(&s->dane, usage, selector, mtype, data, dlen);
+}
+
+int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md, uint8_t mtype, uint8_t ord)
+{
+    return dane_mtype_set(&ctx->dane, md, mtype, ord);
+}
+
 int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm)
 {
     return X509_VERIFY_PARAM_set1(ctx->param, vpm);
@@ -543,6 +1008,7 @@ void SSL_free(SSL *s)
 #endif
 
     X509_VERIFY_PARAM_free(s->param);
+    dane_final(&s->dane);
     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
 
     if (s->bbio != NULL) {
@@ -587,6 +1053,8 @@ void SSL_free(SSL *s)
 
     sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
 
+    sk_X509_pop_free(s->verified_chain, X509_free);
+
     if (s->method != NULL)
         s->method->ssl_free(s);
 
@@ -877,9 +1345,10 @@ int SSL_copy_session_id(SSL *t, const SSL *f)
      * what if we are setup for one protocol version but want to talk another
      */
     if (t->method != f->method) {
-        t->method->ssl_free(t); /* cleanup current */
-        t->method = f->method;  /* change method */
-        t->method->ssl_new(t);  /* setup new */
+        t->method->ssl_free(t);
+        t->method = f->method;
+        if (t->method->ssl_new(t) == 0)
+            return 0;
     }
 
     CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT);
@@ -1004,10 +1473,15 @@ static int ssl_io_intern(void *vargs)
     s = args->s;
     buf = args->buf;
     num = args->num;
-    if (args->type == 1)
-        return args->f.func1(s, buf, num);
-    else
-        return args->f.func2(s, buf, num);
+    switch (args->type) {
+    case READFUNC:
+        return args->f.func_read(s, buf, num);
+    case WRITEFUNC:
+        return args->f.func_write(s, buf, num);
+    case OTHERFUNC:
+        return args->f.func_other(s);
+    }
+    return -1;
 }
 
 int SSL_read(SSL *s, void *buf, int num)
@@ -1028,8 +1502,8 @@ int SSL_read(SSL *s, void *buf, int num)
         args.s = s;
         args.buf = buf;
         args.num = num;
-        args.type = 1;
-        args.f.func1 = s->method->ssl_read;
+        args.type = READFUNC;
+        args.f.func_read = s->method->ssl_read;
 
         return ssl_start_async_job(s, &args, ssl_io_intern);
     } else {
@@ -1053,8 +1527,8 @@ int SSL_peek(SSL *s, void *buf, int num)
         args.s = s;
         args.buf = buf;
         args.num = num;
-        args.type = 1;
-        args.f.func1 = s->method->ssl_peek;
+        args.type = READFUNC;
+        args.f.func_read = s->method->ssl_peek;
 
         return ssl_start_async_job(s, &args, ssl_io_intern);
     } else {
@@ -1081,8 +1555,8 @@ int SSL_write(SSL *s, const void *buf, int num)
         args.s = s;
         args.buf = (void *)buf;
         args.num = num;
-        args.type = 2;
-        args.f.func2 = s->method->ssl_write;
+        args.type = WRITEFUNC;
+        args.f.func_write = s->method->ssl_write;
 
         return ssl_start_async_job(s, &args, ssl_io_intern);
     } else {
@@ -1104,10 +1578,19 @@ int SSL_shutdown(SSL *s)
         return -1;
     }
 
-    if (!SSL_in_init(s))
-        return (s->method->ssl_shutdown(s));
-    else
-        return (1);
+    if((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
+        struct ssl_async_args args;
+
+        args.s = s;
+        args.type = OTHERFUNC;
+        args.f.func_other = s->method->ssl_shutdown;
+
+        return ssl_start_async_job(s, &args, ssl_io_intern);
+    } else {
+        return s->method->ssl_shutdown(s);
+    }
+
+    return s->method->ssl_shutdown(s);
 }
 
 int SSL_renegotiate(SSL *s)
@@ -1155,10 +1638,6 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
         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:
@@ -1201,11 +1680,11 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
         else
             return 0;
     case SSL_CTRL_SET_MIN_PROTO_VERSION:
-        s->min_proto_version = larg;
-        return 1;
+        return ssl_set_version_bound(s->ctx->method->version, (int)larg,
+                                     &s->min_proto_version);
     case SSL_CTRL_SET_MAX_PROTO_VERSION:
-        s->max_proto_version = larg;
-        return 1;
+        return ssl_set_version_bound(s->ctx->method->version, (int)larg,
+                                     &s->max_proto_version);
     default:
         return (s->method->ssl_ctrl(s, cmd, larg, parg));
     }
@@ -1305,10 +1784,6 @@ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
         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:
@@ -1323,11 +1798,11 @@ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
     case SSL_CTRL_CLEAR_CERT_FLAGS:
         return (ctx->cert->cert_flags &= ~larg);
     case SSL_CTRL_SET_MIN_PROTO_VERSION:
-        ctx->min_proto_version = larg;
-        return 1;
+        return ssl_set_version_bound(ctx->method->version, (int)larg,
+                                     &ctx->min_proto_version);
     case SSL_CTRL_SET_MAX_PROTO_VERSION:
-        ctx->max_proto_version = larg;
-        return 1;
+        return ssl_set_version_bound(ctx->method->version, (int)larg,
+                                     &ctx->max_proto_version);
     default:
         return (ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg));
     }
@@ -1429,7 +1904,7 @@ STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s)
 /** The old interface to get the same thing as SSL_get_ciphers() */
 const char *SSL_get_cipher_list(const SSL *s, int n)
 {
-    SSL_CIPHER *c;
+    const SSL_CIPHER *c;
     STACK_OF(SSL_CIPHER) *sk;
 
     if (s == NULL)
@@ -1487,7 +1962,7 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len)
 {
     char *p;
     STACK_OF(SSL_CIPHER) *sk;
-    SSL_CIPHER *c;
+    const SSL_CIPHER *c;
     int i;
 
     if ((s->session == NULL) || (s->session->ciphers == NULL) || (len < 2))
@@ -1510,7 +1985,7 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len)
             *p = '\0';
             return buf;
         }
-        strcpy(p, c->name);
+        memcpy(p, c->name, n + 1);
         p += n;
         *(p++) = ':';
         len -= n + 1;
@@ -1782,8 +2257,6 @@ static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b)
  * variable. The reason is that the functions aren't static, they're exposed
  * via ssl.h.
  */
-static IMPLEMENT_LHASH_HASH_FN(ssl_session, SSL_SESSION)
-static IMPLEMENT_LHASH_COMP_FN(ssl_session, SSL_SESSION)
 
 SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
 {
@@ -1795,7 +2268,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
     }
 
     if (FIPS_mode() && (meth->version < TLS1_VERSION)) {
-        SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+        SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE);
         return NULL;
     }
 
@@ -1820,7 +2293,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
     if ((ret->cert = ssl_cert_new()) == NULL)
         goto err;
 
-    ret->sessions = lh_SSL_SESSION_new();
+    ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
     if (ret->sessions == NULL)
         goto err;
     ret->cert_store = X509_STORE_new();
@@ -1892,6 +2365,13 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
      * deployed might change this.
      */
     ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
+    /*
+     * Disable compression by default to prevent CRIME. Applications can
+     * re-enable compression by configuring
+     * SSL_CTX_clear_options(ctx, SSL_OP_NO_COMPRESSION);
+     * or by using the SSL_CONF library.
+     */
+    ret->options |= SSL_OP_NO_COMPRESSION;
 
     return (ret);
  err:
@@ -1901,6 +2381,11 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
     return (NULL);
 }
 
+void SSL_CTX_up_ref(SSL_CTX *ctx)
+{
+    CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
+}
+
 void SSL_CTX_free(SSL_CTX *a)
 {
     int i;
@@ -1922,6 +2407,7 @@ void SSL_CTX_free(SSL_CTX *a)
 #endif
 
     X509_VERIFY_PARAM_free(a->param);
+    dane_ctx_final(&a->dane);
 
     /*
      * Free internal session cache. However: the remove_cb() may reference
@@ -2049,9 +2535,8 @@ void ssl_set_masks(SSL *s, const SSL_CIPHER *cipher)
     mask_a = 0;
 
 #ifdef CIPHER_DEBUG
-    fprintf(stderr,
-            "dht=%d re=%d rs=%d ds=%d dhr=%d dhd=%d\n",
-            dh_tmp, rsa_enc, rsa_sign, dsa_sign, dh_rsa, dh_dsa);
+    fprintf(stderr, "dht=%d re=%d rs=%d ds=%d\n",
+            dh_tmp, rsa_enc, rsa_sign, dsa_sign);
 #endif
 
 #ifndef OPENSSL_NO_GOST
@@ -2346,24 +2831,23 @@ const SSL_METHOD *SSL_get_ssl_method(SSL *s)
 
 int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth)
 {
-    int conn = -1;
     int ret = 1;
 
     if (s->method != meth) {
-        if (s->handshake_func != NULL)
-            conn = (s->handshake_func == s->method->ssl_connect);
+        const SSL_METHOD *sm = s->method;
+        int (*hf)(SSL *) = s->handshake_func;
 
-        if (s->method->version == meth->version)
+        if (sm->version == meth->version)
             s->method = meth;
         else {
-            s->method->ssl_free(s);
+            sm->ssl_free(s);
             s->method = meth;
             ret = s->method->ssl_new(s);
         }
 
-        if (conn == 1)
+        if (hf == sm->ssl_connect)
             s->handshake_func = meth->ssl_connect;
-        else if (conn == 0)
+        else if (hf == sm->ssl_accept)
             s->handshake_func = meth->ssl_accept;
     }
     return (ret);
@@ -2554,14 +3038,23 @@ SSL *SSL_dup(SSL *s)
     SSL *ret;
     int i;
 
+    /* If we're not quiescent, just up_ref! */
+    if (!SSL_in_init(s) || !SSL_in_before(s)) {
+        CRYPTO_add(&s->references, 1, CRYPTO_LOCK_SSL);
+        return s;
+    }
+
+    /*
+     * Otherwise, copy configuration state, and session if set.
+     */
     if ((ret = SSL_new(SSL_get_SSL_CTX(s))) == NULL)
         return (NULL);
 
-    ret->version = s->version;
-    ret->method = s->method;
-
     if (s->session != NULL) {
-        /* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */
+        /*
+         * Arranges to share the same session via up_ref.  This "copies"
+         * session-id, SSL_METHOD, sid_ctx, and 'cert'
+         */
         if (!SSL_copy_session_id(ret, s))
             goto err;
     } else {
@@ -2571,10 +3064,8 @@ SSL *SSL_dup(SSL *s)
          * point to the same object, and thus we can't use
          * SSL_copy_session_id.
          */
-
-        ret->method->ssl_free(ret);
-        ret->method = s->method;
-        ret->method->ssl_new(ret);
+        if (!SSL_set_ssl_method(ret, s->method))
+            goto err;
 
         if (s->cert != NULL) {
             ssl_cert_free(ret->cert);
@@ -2587,6 +3078,8 @@ SSL *SSL_dup(SSL *s)
             goto err;
     }
 
+    ssl_dane_dup(ret, s);
+    ret->version = s->version;
     ret->options = s->options;
     ret->mode = s->mode;
     SSL_set_max_cert_list(ret, SSL_get_max_cert_list(s));
@@ -2599,8 +3092,6 @@ SSL *SSL_dup(SSL *s)
 
     SSL_set_info_callback(ret, SSL_get_info_callback(s));
 
-    ret->debug = s->debug;
-
     /* copy app data, a little dangerous perhaps */
     if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, &ret->ex_data, &s->ex_data))
         goto err;
@@ -2617,19 +3108,15 @@ SSL *SSL_dup(SSL *s)
         } else
             ret->wbio = ret->rbio;
     }
-    ret->rwstate = s->rwstate;
-    ret->handshake_func = s->handshake_func;
+
     ret->server = s->server;
-    ret->renegotiate = s->renegotiate;
-    ret->new_session = s->new_session;
-    ret->quiet_shutdown = s->quiet_shutdown;
+    if (s->handshake_func) {
+        if (s->server)
+            SSL_set_accept_state(ret);
+        else
+            SSL_set_connect_state(ret);
+    }
     ret->shutdown = s->shutdown;
-    ret->statem = s->statem;      /* SSL_dup does not really work at any state,
-                                   * though */
-    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 */
     ret->hit = s->hit;
 
     ret->default_passwd_callback = s->default_passwd_callback;
@@ -2670,13 +3157,11 @@ SSL *SSL_dup(SSL *s)
 void ssl_clear_cipher_ctx(SSL *s)
 {
     if (s->enc_read_ctx != NULL) {
-        EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
-        OPENSSL_free(s->enc_read_ctx);
+        EVP_CIPHER_CTX_free(s->enc_read_ctx);
         s->enc_read_ctx = NULL;
     }
     if (s->enc_write_ctx != NULL) {
-        EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
-        OPENSSL_free(s->enc_write_ctx);
+        EVP_CIPHER_CTX_free(s->enc_write_ctx);
         s->enc_write_ctx = NULL;
     }
 #ifndef OPENSSL_NO_COMP
@@ -3218,11 +3703,6 @@ int ssl_handshake_hash(SSL *s, unsigned char *out, int outlen)
     return ret;
 }
 
-void SSL_set_debug(SSL *s, int debug)
-{
-    s->debug = debug;
-}
-
 int SSL_cache_hit(SSL *s)
 {
     return s->hit;
@@ -3233,6 +3713,16 @@ int SSL_is_server(SSL *s)
     return s->server;
 }
 
+#if OPENSSL_API_COMPAT < 0x10100000L
+void SSL_set_debug(SSL *s, int debug)
+{
+    /* Old function was do-nothing anyway... */
+    (void)s;
+    (void)debug;
+}
+#endif
+
+
 void SSL_set_security_level(SSL *s, int level)
 {
     s->cert->sec_level = level;
@@ -3304,4 +3794,40 @@ void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx)
     return ctx->cert->sec_ex;
 }
 
+
+/*
+ * Get/Set/Clear options in SSL_CTX or SSL, formerly macros, now functions that
+ * can return unsigned long, instead of the generic long return value from the
+ * control interface.
+ */
+unsigned long SSL_CTX_get_options(const SSL_CTX *ctx)
+{
+    return ctx->options;
+}
+unsigned long SSL_get_options(const SSL* s)
+{
+    return s->options;
+}
+unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op)
+{
+    return ctx->options |= op;
+}
+unsigned long SSL_set_options(SSL *s, unsigned long op)
+{
+    return s->options |= op;
+}
+unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op)
+{
+    return ctx->options &= ~op;
+}
+unsigned long SSL_clear_options(SSL *s, unsigned long op)
+{
+    return s->options &= ~op;
+}
+
+STACK_OF(X509) *SSL_get0_verified_chain(const SSL *s)
+{
+    return s->verified_chain;
+}
+
 IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id);