1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * All rights reserved.
3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This package is an SSL implementation written
5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * by Eric Young (eay@cryptsoft.com).
6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The implementation was written so as to conform with Netscapes SSL.
7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This library is free for commercial and non-commercial use as long as
9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the following conditions are aheared to.  The following conditions
10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * apply to all code found in this distribution, be it the RC4, RSA,
11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * included with this distribution is covered by the same copyright terms
13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright remains Eric Young's, and as such any Copyright notices in
16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the code are not to be removed.
17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * If this package is used in a product, Eric Young should be given attribution
18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * as the author of the parts of the library used.
19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This can be in the form of a textual message at program startup or
20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * in documentation (online or textual) provided with the package.
21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without
23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions
24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met:
25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the copyright
26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer.
27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright
28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer in the
29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    documentation and/or other materials provided with the distribution.
30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this software
31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    must display the following acknowledgement:
32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes cryptographic software written by
33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *     Eric Young (eay@cryptsoft.com)"
34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    The word 'cryptographic' can be left out if the rouines from the library
35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    being used are not cryptographic related :-).
36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. If you include any Windows specific code (or a derivative thereof) from
37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    the apps directory (application code) you must include an acknowledgement:
38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SUCH DAMAGE.
51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The licence and distribution terms for any publically available version or
53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * derivative of this code cannot be changed.  i.e. this code cannot simply be
54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * copied and put under another distribution licence
55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * [including the GNU Public Licence.]
56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */
57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ====================================================================
58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without
61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions
62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met:
63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the above copyright
65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer.
66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright
68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer in
69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    the documentation and/or other materials provided with the
70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    distribution.
71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this
73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    software must display the following acknowledgment:
74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes software developed by the OpenSSL Project
75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    endorse or promote products derived from this software without
79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    prior written permission. For written permission, please contact
80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    openssl-core@openssl.org.
81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5. Products derived from this software may not be called "OpenSSL"
83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    nor may "OpenSSL" appear in their names without prior written
84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    permission of the OpenSSL Project.
85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 6. Redistributions of any form whatsoever must retain the following
87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    acknowledgment:
88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes software developed by the OpenSSL Project
89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF THE POSSIBILITY OF SUCH DAMAGE.
103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ====================================================================
104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This product includes cryptographic software written by Eric Young
106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (eay@cryptsoft.com).  This product includes software written by Tim
107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Hudson (tjh@cryptsoft.com).
108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */
110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ====================================================================
111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ECC cipher suite support in OpenSSL originally developed by
113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */
115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ====================================================================
116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright 2005 Nokia. All rights reserved.
117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The portions of the attached software ("Contribution") is developed by
119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Nokia Corporation and is licensed pursuant to the OpenSSL open source
120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * license.
121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The Contribution, originally written by Mika Kousa and Pasi Eronen of
123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * support (see RFC 4279) to OpenSSL.
125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * No patent licenses or other rights except those expressly stated in
127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the OpenSSL open source license shall be deemed granted or received
128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * expressly, by implication, estoppel, or otherwise.
129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * No assurances are provided by Nokia that the Contribution does not
131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * infringe the patent or other intellectual property rights of any third
132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * party or that the license provides you with all the necessary rights
133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * to make use of the Contribution.
134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OTHERWISE. */
140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
141b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include <openssl/ssl.h>
142b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <assert.h>
144e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <stdio.h>
145e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <string.h>
146d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
147d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/bytestring.h>
148b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include <openssl/crypto.h>
149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/dh.h>
150e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <openssl/err.h>
151d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/lhash.h>
152d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/mem.h>
153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/obj.h>
154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/rand.h>
155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/x509v3.h>
156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
157e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "internal.h"
158e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "../crypto/internal.h"
159e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
161b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root/* |SSL_R_UNKNOWN_PROTOCOL| is no longer emitted, but continue to define it
162b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root * to avoid downstream churn. */
163b8494591d1b1a143f3b192d845c238bbf3bc629dKenny RootOPENSSL_DECLARE_ERROR_REASON(SSL, UNKNOWN_PROTOCOL)
164b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Some error codes are special. Ensure the make_errors.go script never
166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * regresses this. */
167d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyOPENSSL_COMPILE_ASSERT(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION ==
168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                           SSL_AD_NO_RENEGOTIATION + SSL_AD_REASON_OFFSET,
169d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                       ssl_alert_reason_code_mismatch);
170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
171e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley/* kMaxHandshakeSize is the maximum size, in bytes, of a handshake message. */
172e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const size_t kMaxHandshakeSize = (1u << 24) - 1;
173e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
174b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootstatic CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl =
175b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
176b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootstatic CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl_ctx =
177b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
178d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
179b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_library_init(void) {
180b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  CRYPTO_library_init();
181b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return 1;
182b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
183b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
184b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootstatic uint32_t ssl_session_hash(const SSL_SESSION *a) {
185b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  uint32_t hash =
186e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      ((uint32_t)a->session_id[0]) |
187e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      ((uint32_t)a->session_id[1] << 8) |
188e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      ((uint32_t)a->session_id[2] << 16) |
189b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      ((uint32_t)a->session_id[3] << 24);
190b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
191b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return hash;
192b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
193b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
194b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root/* NB: If this function (or indeed the hash function which uses a sort of
195b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root * coarser function than this one) is changed, ensure
196b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
197b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root * able to construct an SSL_SESSION that will collide with any existing session
198b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root * with a matching session ID. */
199b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootstatic int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) {
200b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (a->ssl_version != b->ssl_version) {
201b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 1;
2021e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley  }
203d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
204b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (a->session_id_length != b->session_id_length) {
205b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 1;
2061e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley  }
207d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
208b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return memcmp(a->session_id, b->session_id, a->session_id_length);
209b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
2101e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley
211b8494591d1b1a143f3b192d845c238bbf3bc629dKenny RootSSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
212b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  SSL_CTX *ret = NULL;
213b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
214b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (method == NULL) {
215b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_METHOD_PASSED);
216b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return NULL;
217d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
218d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
219b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) {
220b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
221b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    goto err;
222b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
224b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
225b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ret == NULL) {
226b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    goto err;
227b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
229b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  memset(ret, 0, sizeof(SSL_CTX));
230d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
231b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret->method = method->method;
2321e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley
233b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  CRYPTO_MUTEX_init(&ret->lock);
2341e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley
235b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
236b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
2371e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley
238b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* We take the system default */
239b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
240b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
241b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret->references = 1;
242b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
243b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
244b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret->verify_mode = SSL_VERIFY_NONE;
245b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret->cert = ssl_cert_new();
246b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ret->cert == NULL) {
247b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    goto err;
2481e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley  }
2491e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley
250b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
251b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ret->sessions == NULL) {
252b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    goto err;
253b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
254b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret->cert_store = X509_STORE_new();
255b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ret->cert_store == NULL) {
256b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    goto err;
2571e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley  }
2581e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley
259b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_create_cipher_list(ret->method, &ret->cipher_list,
260b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                         &ret->cipher_list_by_id, SSL_DEFAULT_CIPHER_LIST);
261b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ret->cipher_list == NULL ||
262b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      sk_SSL_CIPHER_num(ret->cipher_list->ciphers) <= 0) {
263b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_LIBRARY_HAS_NO_CIPHERS);
264b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    goto err2;
2651e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley  }
2661e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley
267b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret->param = X509_VERIFY_PARAM_new();
268b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (!ret->param) {
269b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    goto err;
270b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
2711e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley
272b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret->client_CA = sk_X509_NAME_new_null();
273b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ret->client_CA == NULL) {
274b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    goto err;
275b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
276b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
2774139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  CRYPTO_new_ex_data(&ret->ex_data);
278b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
279b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
280b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
281b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* Setup RFC4507 ticket keys */
282b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (!RAND_bytes(ret->tlsext_tick_key_name, 16) ||
283b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      !RAND_bytes(ret->tlsext_tick_hmac_key, 16) ||
284b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      !RAND_bytes(ret->tlsext_tick_aes_key, 16)) {
285b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    ret->options |= SSL_OP_NO_TICKET;
286b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
287b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
288b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* Lock the SSL_CTX to the specified version, for compatibility with legacy
289b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * uses of SSL_METHOD. */
290b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (method->version != 0) {
291b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    SSL_CTX_set_max_version(ret, method->version);
292b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    SSL_CTX_set_min_version(ret, method->version);
293b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
294b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
295b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ret;
296b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
297b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rooterr:
298b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
299b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rooterr2:
300b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  SSL_CTX_free(ret);
301b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return NULL;
302b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
303b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
304b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_CTX_free(SSL_CTX *ctx) {
305b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ctx == NULL ||
306b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      !CRYPTO_refcount_dec_and_test_zero(&ctx->references)) {
307b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return;
308b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
309b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
310b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  X509_VERIFY_PARAM_free(ctx->param);
311b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
312b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* Free internal session cache. However: the remove_cb() may reference the
313b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * ex_data of SSL_CTX, thus the ex_data store can only be removed after the
314b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * sessions were flushed. As the ex_data handling routines might also touch
315b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * the session cache, the most secure solution seems to be: empty (flush) the
316b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * cache, then free ex_data, then finally free the cache. (See ticket
317b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * [openssl.org #212].) */
318b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  SSL_CTX_flush_sessions(ctx, 0);
319b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
320b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  CRYPTO_free_ex_data(&g_ex_data_class_ssl_ctx, ctx, &ctx->ex_data);
321b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
322b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  CRYPTO_MUTEX_cleanup(&ctx->lock);
323b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  lh_SSL_SESSION_free(ctx->sessions);
324b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  X509_STORE_free(ctx->cert_store);
325b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_cipher_preference_list_free(ctx->cipher_list);
326b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  sk_SSL_CIPHER_free(ctx->cipher_list_by_id);
327b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_cipher_preference_list_free(ctx->cipher_list_tls10);
328b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_cipher_preference_list_free(ctx->cipher_list_tls11);
329b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_cert_free(ctx->cert);
330b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->client_custom_extensions,
331b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                   SSL_CUSTOM_EXTENSION_free);
332b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->server_custom_extensions,
333b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                   SSL_CUSTOM_EXTENSION_free);
334b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  sk_X509_NAME_pop_free(ctx->client_CA, X509_NAME_free);
335b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  sk_SRTP_PROTECTION_PROFILE_free(ctx->srtp_profiles);
336b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ctx->psk_identity_hint);
337b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ctx->tlsext_ellipticcurvelist);
338b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ctx->alpn_client_proto_list);
339b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ctx->ocsp_response);
340b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ctx->signed_cert_timestamp_list);
341b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  EVP_PKEY_free(ctx->tlsext_channel_id_private);
342b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
343b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ctx);
344d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
345d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
346d9e397b599b13d642138480a28c14db7a136bf0Adam LangleySSL *SSL_new(SSL_CTX *ctx) {
347d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ctx == NULL) {
348b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_CTX);
349d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
350d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
351d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ctx->method == NULL) {
352b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
353d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
354d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
355d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
3564139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  SSL *ssl = (SSL *)OPENSSL_malloc(sizeof(SSL));
3574139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl == NULL) {
358d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
359d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
3604139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  memset(ssl, 0, sizeof(SSL));
361d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
3624139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->min_version = ctx->min_version;
3634139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->max_version = ctx->max_version;
364d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
3654139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->options = ctx->options;
3664139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->mode = ctx->mode;
3674139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->max_cert_list = ctx->max_cert_list;
368d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
3694139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->cert = ssl_cert_dup(ctx->cert);
3704139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->cert == NULL) {
371e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    goto err;
372d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
373d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
3744139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->msg_callback = ctx->msg_callback;
3754139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->msg_callback_arg = ctx->msg_callback_arg;
3764139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->verify_mode = ctx->verify_mode;
3774139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->sid_ctx_length = ctx->sid_ctx_length;
3784139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  assert(ssl->sid_ctx_length <= sizeof ssl->sid_ctx);
3794139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx));
3804139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->verify_callback = ctx->default_verify_callback;
381d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
3824139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->param = X509_VERIFY_PARAM_new();
3834139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (!ssl->param) {
384d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
385d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
3864139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  X509_VERIFY_PARAM_inherit(ssl->param, ctx->param);
3874139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->quiet_shutdown = ctx->quiet_shutdown;
3884139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->max_send_fragment = ctx->max_send_fragment;
389d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
390f4e427204234da139fd0585def4b4e22502e33f0Adam Langley  CRYPTO_refcount_inc(&ctx->references);
3914139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->ctx = ctx;
392f4e427204234da139fd0585def4b4e22502e33f0Adam Langley  CRYPTO_refcount_inc(&ctx->references);
3934139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->initial_ctx = ctx;
394d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
395d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ctx->tlsext_ellipticcurvelist) {
3964139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl->tlsext_ellipticcurvelist =
397d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        BUF_memdup(ctx->tlsext_ellipticcurvelist,
398d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                   ctx->tlsext_ellipticcurvelist_length * 2);
3994139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (!ssl->tlsext_ellipticcurvelist) {
400d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      goto err;
401d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
4024139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length;
403d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
404d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
4054139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->ctx->alpn_client_proto_list) {
4064139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl->alpn_client_proto_list = BUF_memdup(
4074139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley        ssl->ctx->alpn_client_proto_list, ssl->ctx->alpn_client_proto_list_len);
4084139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->alpn_client_proto_list == NULL) {
409d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      goto err;
410d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
4114139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl->alpn_client_proto_list_len = ssl->ctx->alpn_client_proto_list_len;
412d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
413d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
4144139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->verify_result = X509_V_OK;
4154139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->method = ctx->method;
416d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
4174139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (!ssl->method->ssl_new(ssl)) {
418d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
419d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
4204139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->enc_method = ssl3_get_enc_method(ssl->version);
4214139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  assert(ssl->enc_method != NULL);
422a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root
4234139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->rwstate = SSL_NOTHING;
424a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root
4254139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  CRYPTO_new_ex_data(&ssl->ex_data);
426a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root
4274139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->psk_identity_hint = NULL;
428a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root  if (ctx->psk_identity_hint) {
4294139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint);
4304139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->psk_identity_hint == NULL) {
4311e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley      goto err;
4321e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley    }
4331e4884f615b20946411a74e41eb9c6aa65e2d5f3Adam Langley  }
4344139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->psk_client_callback = ctx->psk_client_callback;
4354139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->psk_server_callback = ctx->psk_server_callback;
436b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
4374139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->tlsext_channel_id_enabled = ctx->tlsext_channel_id_enabled;
438b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ctx->tlsext_channel_id_private) {
4394139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl->tlsext_channel_id_private =
440b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root        EVP_PKEY_up_ref(ctx->tlsext_channel_id_private);
441b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
442b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
4434139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->signed_cert_timestamps_enabled =
4444139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      ssl->ctx->signed_cert_timestamps_enabled;
4454139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->ocsp_stapling_enabled = ssl->ctx->ocsp_stapling_enabled;
446b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
4474139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  return ssl;
448b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
449b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rooterr:
4504139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  SSL_free(ssl);
451b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
452b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
453b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return NULL;
454b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
455b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
456b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_free(SSL *ssl) {
457b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl == NULL) {
458b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return;
459b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
460b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
461b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  X509_VERIFY_PARAM_free(ssl->param);
462b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
463b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  CRYPTO_free_ex_data(&g_ex_data_class_ssl, ssl, &ssl->ex_data);
464b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
465b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->bbio != NULL) {
466b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    /* If the buffering BIO is in place, pop it off */
467b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (ssl->bbio == ssl->wbio) {
468b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      ssl->wbio = BIO_pop(ssl->wbio);
469b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
470b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    BIO_free(ssl->bbio);
471b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    ssl->bbio = NULL;
472b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
473b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
474b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  int free_wbio = ssl->wbio != ssl->rbio;
475b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  BIO_free_all(ssl->rbio);
476b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (free_wbio) {
477b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    BIO_free_all(ssl->wbio);
478b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
479b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
480b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  BUF_MEM_free(ssl->init_buf);
481b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
482b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* add extra stuff */
483b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_cipher_preference_list_free(ssl->cipher_list);
484b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  sk_SSL_CIPHER_free(ssl->cipher_list_by_id);
485b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
486b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_clear_bad_session(ssl);
487b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  SSL_SESSION_free(ssl->session);
488b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
489b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_clear_cipher_ctx(ssl);
490b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
491b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_cert_free(ssl->cert);
492b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
493b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ssl->tlsext_hostname);
494b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  SSL_CTX_free(ssl->initial_ctx);
495b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ssl->tlsext_ellipticcurvelist);
496b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ssl->alpn_client_proto_list);
497b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  EVP_PKEY_free(ssl->tlsext_channel_id_private);
498b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ssl->psk_identity_hint);
499b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  sk_X509_NAME_pop_free(ssl->client_CA, X509_NAME_free);
500b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ssl->next_proto_negotiated);
501b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  sk_SRTP_PROTECTION_PROFILE_free(ssl->srtp_profiles);
502b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
503b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->method != NULL) {
504b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    ssl->method->ssl_free(ssl);
505b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
506b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  SSL_CTX_free(ssl->ctx);
507b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
508b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ssl);
509b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
510b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
511b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_set_connect_state(SSL *ssl) {
512b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->server = 0;
513b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->shutdown = 0;
514b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->state = SSL_ST_CONNECT;
515b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->handshake_func = ssl->method->ssl_connect;
516b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* clear the current cipher */
517b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_clear_cipher_ctx(ssl);
518b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
519b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
520b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_set_accept_state(SSL *ssl) {
521b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->server = 1;
522b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->shutdown = 0;
523b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->state = SSL_ST_ACCEPT;
524b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->handshake_func = ssl->method->ssl_accept;
525b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* clear the current cipher */
526b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_clear_cipher_ctx(ssl);
527b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
528b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
529b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) {
530b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* If the output buffering BIO is still in place, remove it. */
531b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->bbio != NULL) {
532b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (ssl->wbio == ssl->bbio) {
533b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      ssl->wbio = ssl->wbio->next_bio;
534b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      ssl->bbio->next_bio = NULL;
535b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
536b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
537b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
538b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->rbio != rbio) {
539b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    BIO_free_all(ssl->rbio);
540b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
541b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->wbio != wbio && ssl->rbio != ssl->wbio) {
542b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    BIO_free_all(ssl->wbio);
543b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
544b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->rbio = rbio;
545b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->wbio = wbio;
546b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
547b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
548b8494591d1b1a143f3b192d845c238bbf3bc629dKenny RootBIO *SSL_get_rbio(const SSL *ssl) { return ssl->rbio; }
549b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
550b8494591d1b1a143f3b192d845c238bbf3bc629dKenny RootBIO *SSL_get_wbio(const SSL *ssl) { return ssl->wbio; }
551b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
552b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_do_handshake(SSL *ssl) {
553b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->handshake_func == NULL) {
554b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_TYPE_NOT_SET);
555b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return -1;
556b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
557b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
558b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (!SSL_in_init(ssl)) {
559b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 1;
560b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
561b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
562b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->handshake_func(ssl);
563b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
564b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
565b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_connect(SSL *ssl) {
566b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->handshake_func == 0) {
567b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    /* Not properly initialized yet */
568b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    SSL_set_connect_state(ssl);
569b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
570b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
571b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->handshake_func != ssl->method->ssl_connect) {
572b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
573b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return -1;
574b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
575b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
576b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->handshake_func(ssl);
577b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
578b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
579b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_accept(SSL *ssl) {
580b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->handshake_func == 0) {
581b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    /* Not properly initialized yet */
582b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    SSL_set_accept_state(ssl);
583b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
584b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
585b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->handshake_func != ssl->method->ssl_accept) {
586b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
587b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return -1;
588b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
589b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
590b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->handshake_func(ssl);
591b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
592b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
593b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_read(SSL *ssl, void *buf, int num) {
594b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->handshake_func == 0) {
595b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
596b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return -1;
597b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
598b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
599b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
600b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    ssl->rwstate = SSL_NOTHING;
601b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 0;
602b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
603b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
604b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ERR_clear_system_error();
605b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->method->ssl_read_app_data(ssl, buf, num, 0);
606b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
607b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
608b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_peek(SSL *ssl, void *buf, int num) {
609b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->handshake_func == 0) {
610b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
611b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return -1;
612b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
613b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
614b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
615b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 0;
616b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
617b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
618b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ERR_clear_system_error();
619b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->method->ssl_read_app_data(ssl, buf, num, 1);
620b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
621b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
622b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_write(SSL *ssl, const void *buf, int num) {
623b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->handshake_func == 0) {
624b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
625b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return -1;
626b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
627b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
628b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->shutdown & SSL_SENT_SHUTDOWN) {
629b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    ssl->rwstate = SSL_NOTHING;
630b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
631b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return -1;
632b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
633b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
634b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ERR_clear_system_error();
635b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->method->ssl_write_app_data(ssl, buf, num);
636b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
637b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
638b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_shutdown(SSL *ssl) {
639b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* Note that this function behaves differently from what one might expect.
640b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * Return values are 0 for no success (yet), 1 for success; but calling it
641b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * once is usually not enough, even if blocking I/O is used (see
642b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * ssl3_shutdown). */
643b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
644b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->handshake_func == 0) {
645b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
646b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return -1;
647b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
648b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
649b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (SSL_in_init(ssl)) {
650b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 1;
651b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
652b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
653b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* Do nothing if configured not to send a close_notify. */
654b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->quiet_shutdown) {
655b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    ssl->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
656b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 1;
657b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
658b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
659b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (!(ssl->shutdown & SSL_SENT_SHUTDOWN)) {
660b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    ssl->shutdown |= SSL_SENT_SHUTDOWN;
661b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
662b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
663b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    /* our shutdown alert has been sent now, and if it still needs to be
664b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root     * written, ssl->s3->alert_dispatch will be true */
665b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (ssl->s3->alert_dispatch) {
666b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      return -1; /* return WANT_WRITE */
667b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
668b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  } else if (ssl->s3->alert_dispatch) {
669b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    /* resend it if not sent */
670b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    int ret = ssl->method->ssl_dispatch_alert(ssl);
671b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (ret == -1) {
672b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      /* we only get to return -1 here the 2nd/Nth invocation, we must  have
673b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root       * already signalled return 0 upon a previous invoation, return
674b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root       * WANT_WRITE */
675b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      return ret;
676b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
677b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  } else if (!(ssl->shutdown & SSL_RECEIVED_SHUTDOWN)) {
678b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    /* If we are waiting for a close from our peer, we are closed */
679b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    ssl->method->ssl_read_close_notify(ssl);
680b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (!(ssl->shutdown & SSL_RECEIVED_SHUTDOWN)) {
681b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      return -1; /* return WANT_READ */
682b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
683b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
684b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
685b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN) &&
686b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      !ssl->s3->alert_dispatch) {
687b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 1;
688b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  } else {
689b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 0;
690b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
691b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
692b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
693b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_get_error(const SSL *ssl, int ret_code) {
694b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  int reason;
695b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  uint32_t err;
696b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  BIO *bio;
697b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
698b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ret_code > 0) {
699b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return SSL_ERROR_NONE;
700b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
701b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
702b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
703b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * where we do encode the error */
704b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  err = ERR_peek_error();
705b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (err != 0) {
706b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (ERR_GET_LIB(err) == ERR_LIB_SYS) {
707b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      return SSL_ERROR_SYSCALL;
708b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
709b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return SSL_ERROR_SSL;
710b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
711b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
712b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ret_code == 0) {
713b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if ((ssl->shutdown & SSL_RECEIVED_SHUTDOWN) &&
714b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root        (ssl->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) {
715b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      /* The socket was cleanly shut down with a close_notify. */
716b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      return SSL_ERROR_ZERO_RETURN;
717b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
718b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    /* An EOF was observed which violates the protocol, and the underlying
719b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root     * transport does not participate in the error queue. Bubble up to the
720b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root     * caller. */
721b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return SSL_ERROR_SYSCALL;
722b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
723b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
724b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (SSL_want_session(ssl)) {
725b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return SSL_ERROR_PENDING_SESSION;
726b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
727b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
728b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (SSL_want_certificate(ssl)) {
729b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return SSL_ERROR_PENDING_CERTIFICATE;
730b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
731b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
732b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (SSL_want_read(ssl)) {
733b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    bio = SSL_get_rbio(ssl);
734b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (BIO_should_read(bio)) {
735b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      return SSL_ERROR_WANT_READ;
736b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
737b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
738b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (BIO_should_write(bio)) {
739b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      /* This one doesn't make too much sense ... We never try to write to the
740b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root       * rbio, and an application program where rbio and wbio are separate
741b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root       * couldn't even know what it should wait for. However if we ever set
7424139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley       * ssl->rwstate incorrectly (so that we have SSL_want_read(ssl) instead of
7434139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley       * SSL_want_write(ssl)) and rbio and wbio *are* the same, this test works
744b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root       * around that bug; so it might be safer to keep it. */
745b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      return SSL_ERROR_WANT_WRITE;
746b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
747b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
748b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (BIO_should_io_special(bio)) {
749b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      reason = BIO_get_retry_reason(bio);
750b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      if (reason == BIO_RR_CONNECT) {
751b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root        return SSL_ERROR_WANT_CONNECT;
752b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      }
753b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
754b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      if (reason == BIO_RR_ACCEPT) {
755b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root        return SSL_ERROR_WANT_ACCEPT;
756b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      }
757b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
758b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      return SSL_ERROR_SYSCALL; /* unknown */
759b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
760b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
761b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
762b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (SSL_want_write(ssl)) {
763b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    bio = SSL_get_wbio(ssl);
764b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (BIO_should_write(bio)) {
765b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      return SSL_ERROR_WANT_WRITE;
766b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
767b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
768b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (BIO_should_read(bio)) {
769b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      /* See above (SSL_want_read(ssl) with BIO_should_write(bio)) */
770b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      return SSL_ERROR_WANT_READ;
771b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
772b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
773b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (BIO_should_io_special(bio)) {
774b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      reason = BIO_get_retry_reason(bio);
775b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      if (reason == BIO_RR_CONNECT) {
776b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root        return SSL_ERROR_WANT_CONNECT;
777b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      }
778b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
779b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      if (reason == BIO_RR_ACCEPT) {
780b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root        return SSL_ERROR_WANT_ACCEPT;
781b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      }
782b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
783b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      return SSL_ERROR_SYSCALL;
784b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
785b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
786b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
787b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (SSL_want_x509_lookup(ssl)) {
788b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return SSL_ERROR_WANT_X509_LOOKUP;
789b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
790b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
791b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (SSL_want_channel_id_lookup(ssl)) {
792b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP;
793b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
794b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
795b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (SSL_want_private_key_operation(ssl)) {
796b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return SSL_ERROR_WANT_PRIVATE_KEY_OPERATION;
797b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
798b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
799b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return SSL_ERROR_SYSCALL;
800b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
801b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
802b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_CTX_set_min_version(SSL_CTX *ctx, uint16_t version) {
803b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ctx->min_version = version;
804b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
805b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
806b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_CTX_set_max_version(SSL_CTX *ctx, uint16_t version) {
807b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ctx->max_version = version;
808b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
809b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
810b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_set_min_version(SSL *ssl, uint16_t version) {
811b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->min_version = version;
812b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
813b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
814b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_set_max_version(SSL *ssl, uint16_t version) {
815b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->max_version = version;
816b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
817b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
818b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootuint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options) {
819b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ctx->options |= options;
820b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ctx->options;
821b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
822b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
823b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootuint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options) {
824b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ctx->options &= ~options;
825b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ctx->options;
826b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
827b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
828b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootuint32_t SSL_CTX_get_options(const SSL_CTX *ctx) { return ctx->options; }
829b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
830b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootuint32_t SSL_set_options(SSL *ssl, uint32_t options) {
831b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->options |= options;
832b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->options;
833b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
834b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
835b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootuint32_t SSL_clear_options(SSL *ssl, uint32_t options) {
836b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->options &= ~options;
837b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->options;
838b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
839b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
840b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootuint32_t SSL_get_options(const SSL *ssl) { return ssl->options; }
841b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
842b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootuint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode) {
843b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ctx->mode |= mode;
844b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ctx->mode;
845b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
846b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
847b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootuint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode) {
848b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ctx->mode &= ~mode;
849b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ctx->mode;
850b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
851b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
852b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootuint32_t SSL_CTX_get_mode(const SSL_CTX *ctx) { return ctx->mode; }
853b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
854b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootuint32_t SSL_set_mode(SSL *ssl, uint32_t mode) {
855b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->mode |= mode;
856b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->mode;
857b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
858b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
859b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootuint32_t SSL_clear_mode(SSL *ssl, uint32_t mode) {
860b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->mode &= ~mode;
861b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->mode;
862b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
863b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
864b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootuint32_t SSL_get_mode(const SSL *ssl) { return ssl->mode; }
865b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
866b8494591d1b1a143f3b192d845c238bbf3bc629dKenny RootX509 *SSL_get_peer_certificate(const SSL *ssl) {
867b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl == NULL || ssl->session == NULL || ssl->session->peer == NULL) {
868b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return NULL;
869b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
870b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return X509_up_ref(ssl->session->peer);
871b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
872b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
873b8494591d1b1a143f3b192d845c238bbf3bc629dKenny RootSTACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) {
874b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl == NULL || ssl->session == NULL) {
875b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return NULL;
876b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
877b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->session->cert_chain;
878b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
879b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
880b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len,
881b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                       size_t max_out) {
882b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* The tls-unique value is the first Finished message in the handshake, which
883b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * is the client's in a full handshake and the server's for a resumption. See
884b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * https://tools.ietf.org/html/rfc5929#section-3.1. */
885b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  const uint8_t *finished = ssl->s3->previous_client_finished;
886b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  size_t finished_len = ssl->s3->previous_client_finished_len;
887b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->hit) {
888b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    /* tls-unique is broken for resumed sessions unless EMS is used. */
889b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (!ssl->session->extended_master_secret) {
890b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      goto err;
891b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
892b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    finished = ssl->s3->previous_server_finished;
893b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    finished_len = ssl->s3->previous_server_finished_len;
894b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
895d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
896b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (!ssl->s3->initial_handshake_complete ||
897b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      ssl->version < TLS1_VERSION) {
898b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    goto err;
899d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
900d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
901b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  *out_len = finished_len;
902b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (finished_len > max_out) {
903b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    *out_len = max_out;
904b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
905d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
906b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  memcpy(out, finished, *out_len);
907b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return 1;
908d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
909d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr:
910b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  *out_len = 0;
911b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  memset(out, 0, max_out);
912b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return 0;
913d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
914d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
915d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx,
916b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                   unsigned sid_ctx_len) {
917b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (sid_ctx_len > sizeof(ctx->sid_ctx)) {
918b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
919d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
920d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
921d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->sid_ctx_length = sid_ctx_len;
922d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len);
923d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
924d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
925d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
926d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
927d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
928b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                               unsigned sid_ctx_len) {
929d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
930b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
931d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
932d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
933d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ssl->sid_ctx_length = sid_ctx_len;
934d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len);
935d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
936d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
937d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
938d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
939b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) {
940b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
941d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
942d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
943b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_set_purpose(SSL *ssl, int purpose) {
944b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return X509_VERIFY_PARAM_set_purpose(ssl->param, purpose);
945d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
946d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
947b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_CTX_set_trust(SSL_CTX *ctx, int trust) {
948b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
949d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
950d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
951b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_set_trust(SSL *ssl, int trust) {
952b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return X509_VERIFY_PARAM_set_trust(ssl->param, trust);
953d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
954d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
955b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) {
956b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return X509_VERIFY_PARAM_set1(ctx->param, param);
957d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
958d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
959b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) {
960b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return X509_VERIFY_PARAM_set1(ssl->param, param);
961d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
962d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
963d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid ssl_cipher_preference_list_free(
964d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    struct ssl_cipher_preference_list_st *cipher_list) {
965e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (cipher_list == NULL) {
966e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return;
967e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
968d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  sk_SSL_CIPHER_free(cipher_list->ciphers);
969d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  OPENSSL_free(cipher_list->in_group_flags);
970d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  OPENSSL_free(cipher_list);
971d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
972d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
973d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyX509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { return ctx->param; }
974d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
975d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyX509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { return ssl->param; }
976d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
977b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_certs_clear(SSL *ssl) { ssl_cert_clear_certs(ssl->cert); }
978d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
979e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_get_fd(const SSL *ssl) { return SSL_get_rfd(ssl); }
980d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
981e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_get_rfd(const SSL *ssl) {
982d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int ret = -1;
983e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  BIO *b = BIO_find_type(SSL_get_rbio(ssl), BIO_TYPE_DESCRIPTOR);
984e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (b != NULL) {
985e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    BIO_get_fd(b, &ret);
986d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
987d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ret;
988d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
989d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
990e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_get_wfd(const SSL *ssl) {
991d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int ret = -1;
992e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  BIO *b = BIO_find_type(SSL_get_wbio(ssl), BIO_TYPE_DESCRIPTOR);
993e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (b != NULL) {
994e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    BIO_get_fd(b, &ret);
995d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
996d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ret;
997d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
998d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
999e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_set_fd(SSL *ssl, int fd) {
1000e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  BIO *bio = BIO_new(BIO_s_fd());
1001d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (bio == NULL) {
1002b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
1003e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    return 0;
1004d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1005d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  BIO_set_fd(bio, fd, BIO_NOCLOSE);
1006e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  SSL_set_bio(ssl, bio, bio);
1007e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  return 1;
1008d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1009d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1010e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_set_wfd(SSL *ssl, int fd) {
1011e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->rbio == NULL ||
1012e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      BIO_method_type(ssl->rbio) != BIO_TYPE_FD ||
1013e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      BIO_get_fd(ssl->rbio, NULL) != fd) {
1014e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    BIO *bio = BIO_new(BIO_s_fd());
1015d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (bio == NULL) {
1016b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
1017e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      return 0;
1018d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1019d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    BIO_set_fd(bio, fd, BIO_NOCLOSE);
1020e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    SSL_set_bio(ssl, SSL_get_rbio(ssl), bio);
1021d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
1022e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    SSL_set_bio(ssl, SSL_get_rbio(ssl), SSL_get_rbio(ssl));
1023d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1024d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1025e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  return 1;
1026d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1027d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1028e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_set_rfd(SSL *ssl, int fd) {
1029e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->wbio == NULL || BIO_method_type(ssl->wbio) != BIO_TYPE_FD ||
1030e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      BIO_get_fd(ssl->wbio, NULL) != fd) {
1031e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    BIO *bio = BIO_new(BIO_s_fd());
1032d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (bio == NULL) {
1033b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
1034e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      return 0;
1035d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1036d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    BIO_set_fd(bio, fd, BIO_NOCLOSE);
1037e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    SSL_set_bio(ssl, bio, SSL_get_wbio(ssl));
1038d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
1039e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    SSL_set_bio(ssl, SSL_get_wbio(ssl), SSL_get_wbio(ssl));
1040d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1041e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  return 1;
1042d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1043d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1044e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootsize_t SSL_get_finished(const SSL *ssl, void *buf, size_t count) {
1045d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t ret = 0;
1046d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1047e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->s3 != NULL) {
1048e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    ret = ssl->s3->tmp.finish_md_len;
1049d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (count > ret) {
1050d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      count = ret;
1051d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1052e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    memcpy(buf, ssl->s3->tmp.finish_md, count);
1053d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1054d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1055d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ret;
1056d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1057d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1058e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootsize_t SSL_get_peer_finished(const SSL *ssl, void *buf, size_t count) {
1059d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t ret = 0;
1060d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1061e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->s3 != NULL) {
1062e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    ret = ssl->s3->tmp.peer_finish_md_len;
1063d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (count > ret) {
1064d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      count = ret;
1065d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1066e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    memcpy(buf, ssl->s3->tmp.peer_finish_md, count);
1067d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1068d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1069d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ret;
1070d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1071d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1072b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_get_verify_mode(const SSL *ssl) { return ssl->verify_mode; }
1073b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
1074b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_get_verify_depth(const SSL *ssl) {
1075b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return X509_VERIFY_PARAM_get_depth(ssl->param);
1076b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
1077d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1078b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_get_extms_support(const SSL *ssl) {
1079b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->s3->tmp.extended_master_secret == 1;
1080d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1081d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1082b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) {
1083b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->verify_callback;
1084d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1085d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1086d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { return ctx->verify_mode; }
1087d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1088d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_CTX_get_verify_depth(const SSL_CTX *ctx) {
1089d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return X509_VERIFY_PARAM_get_depth(ctx->param);
1090d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1091d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1092b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
1093b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    int ok, X509_STORE_CTX *store_ctx) {
1094d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ctx->default_verify_callback;
1095d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1096d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1097b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_set_verify(SSL *ssl, int mode,
1098b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                    int (*callback)(int ok, X509_STORE_CTX *store_ctx)) {
1099b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->verify_mode = mode;
1100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (callback != NULL) {
1101b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    ssl->verify_callback = callback;
1102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1105b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_set_verify_depth(SSL *ssl, int depth) {
1106b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  X509_VERIFY_PARAM_set_depth(ssl->param, depth);
1107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1109f4e427204234da139fd0585def4b4e22502e33f0Adam Langleyint SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; }
1110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
11114139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint SSL_get_read_ahead(const SSL *ssl) { return 0; }
1112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1113f4e427204234da139fd0585def4b4e22502e33f0Adam Langleyvoid SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { }
1114e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
11154139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyvoid SSL_set_read_ahead(SSL *ssl, int yes) { }
1116e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
1117e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_pending(const SSL *ssl) {
1118e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->s3->rrec.type != SSL3_RT_APPLICATION_DATA) {
1119e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    return 0;
1120e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  }
1121e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  return ssl->s3->rrec.length;
1122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Fix this so it checks all the valid key/cert options */
1125d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_CTX_check_private_key(const SSL_CTX *ctx) {
1126b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ctx->cert->x509 == NULL) {
1127b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
1128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
1129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1131b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ctx->cert->privatekey == NULL) {
1132b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
1133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
1134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1136b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return X509_check_private_key(ctx->cert->x509, ctx->cert->privatekey);
1137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Fix this function so that it takes an optional type parameter */
1140d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_check_private_key(const SSL *ssl) {
1141b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->cert->x509 == NULL) {
1142b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
1143a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root    return 0;
1144a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root  }
1145a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root
1146b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->cert->privatekey == NULL) {
1147b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
1148a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root    return 0;
1149a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root  }
1150a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root
1151b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return X509_check_private_key(ssl->cert->x509, ssl->cert->privatekey);
1152a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root}
1153a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root
1154b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootlong SSL_get_default_timeout(const SSL *ssl) {
1155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return SSL_DEFAULT_SESSION_TIMEOUT;
1156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1157d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1158f4e427204234da139fd0585def4b4e22502e33f0Adam Langleyint SSL_renegotiate(SSL *ssl) {
1159f4e427204234da139fd0585def4b4e22502e33f0Adam Langley  /* Caller-initiated renegotiation is not supported. */
1160b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1161f4e427204234da139fd0585def4b4e22502e33f0Adam Langley  return 0;
1162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1163d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1164a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Rootint SSL_renegotiate_pending(SSL *ssl) {
1165a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root  return SSL_in_init(ssl) && ssl->s3->initial_handshake_complete;
1166a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root}
1167a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root
1168e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleysize_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx) {
1169e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return ctx->max_cert_list;
1170e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
1171d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1172e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid SSL_CTX_set_max_cert_list(SSL_CTX *ctx, size_t max_cert_list) {
1173e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (max_cert_list > kMaxHandshakeSize) {
1174e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    max_cert_list = kMaxHandshakeSize;
1175d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1176e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ctx->max_cert_list = (uint32_t)max_cert_list;
1177d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1178d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1179e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleysize_t SSL_get_max_cert_list(const SSL *ssl) {
1180e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return ssl->max_cert_list;
1181e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
1182d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1183e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list) {
1184e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (max_cert_list > kMaxHandshakeSize) {
1185e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    max_cert_list = kMaxHandshakeSize;
1186d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1187e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ssl->max_cert_list = (uint32_t)max_cert_list;
1188d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1189d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1190e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, size_t max_send_fragment) {
1191e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (max_send_fragment < 512) {
1192e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    max_send_fragment = 512;
1193e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
1194e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
1195e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
1196e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
1197e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ctx->max_send_fragment = (uint16_t)max_send_fragment;
1198e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
1199d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1200e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment) {
1201e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (max_send_fragment < 512) {
1202e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    max_send_fragment = 512;
1203e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
1204e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
1205e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
1206e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
1207e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ssl->max_send_fragment = (uint16_t)max_send_fragment;
1208e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
1209d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1210e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_set_mtu(SSL *ssl, unsigned mtu) {
1211e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!SSL_IS_DTLS(ssl) || mtu < dtls1_min_mtu()) {
1212e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return 0;
1213e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
1214e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ssl->d1->mtu = mtu;
1215e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return 1;
1216e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
1217d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1218e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_get_secure_renegotiation_support(const SSL *ssl) {
1219e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return ssl->s3->send_connection_binding;
1220e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
1221d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1222e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam LangleyLHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) { return ctx->sessions; }
1223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1224e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleysize_t SSL_CTX_sess_number(const SSL_CTX *ctx) {
1225e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return lh_SSL_SESSION_num_items(ctx->sessions);
1226e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
1227d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1228e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyunsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx, unsigned long size) {
1229e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  unsigned long ret = ctx->session_cache_size;
1230e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ctx->session_cache_size = size;
1231e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return ret;
1232e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
1233d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1234e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyunsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx) {
1235e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return ctx->session_cache_size;
1236e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
1237d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1238e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode) {
1239e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  int ret = ctx->session_cache_mode;
1240e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ctx->session_cache_mode = mode;
1241e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return ret;
1242d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1243d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1244e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx) {
1245e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return ctx->session_cache_mode;
1246e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
1247d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1248e99801b603dea8893dcc61c70b327ef2d00b652cKenny RootSTACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl) {
1249e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl == NULL) {
1250d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
1251d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1252d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1253e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->cipher_list != NULL) {
1254e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    return ssl->cipher_list->ciphers;
1255d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1256d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1257e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->version >= TLS1_1_VERSION && ssl->ctx != NULL &&
1258e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      ssl->ctx->cipher_list_tls11 != NULL) {
1259e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    return ssl->ctx->cipher_list_tls11->ciphers;
1260d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1261d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1262e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->version >= TLS1_VERSION && ssl->ctx != NULL &&
1263e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      ssl->ctx->cipher_list_tls10 != NULL) {
1264e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    return ssl->ctx->cipher_list_tls10->ciphers;
1265b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
1266b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
1267e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->ctx != NULL && ssl->ctx->cipher_list != NULL) {
1268e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    return ssl->ctx->cipher_list->ciphers;
1269d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1270d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1271d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return NULL;
1272d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1273d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1274d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* return a STACK of the ciphers available for the SSL and in order of
1275d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * algorithm id */
12764139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam LangleySTACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *ssl) {
12774139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl == NULL) {
1278d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
1279d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1280d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
12814139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->cipher_list_by_id != NULL) {
12824139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    return ssl->cipher_list_by_id;
1283d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1284d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
12854139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->ctx != NULL && ssl->ctx->cipher_list_by_id != NULL) {
12864139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    return ssl->ctx->cipher_list_by_id;
1287d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1288d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1289d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return NULL;
1290d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1291d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1292e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootconst char *SSL_get_cipher_list(const SSL *ssl, int n) {
1293d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  const SSL_CIPHER *c;
1294e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  STACK_OF(SSL_CIPHER) *sk;
1295d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1296e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl == NULL) {
1297d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
1298d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1299d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1300e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  sk = SSL_get_ciphers(ssl);
1301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (sk == NULL || n < 0 || (size_t)n >= sk_SSL_CIPHER_num(sk)) {
1302d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
1303d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1304d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1305d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  c = sk_SSL_CIPHER_value(sk, n);
1306d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (c == NULL) {
1307d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
1308d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1309d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1310d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return c->name;
1311d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1312d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1313d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) {
1314e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
1315e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      ctx->method, &ctx->cipher_list, &ctx->cipher_list_by_id, str);
1316e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (cipher_list == NULL) {
131703bcf618b7ed811b305845461fbb5497dfe55ac3Kenny Root    return 0;
1318e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  }
1319e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root
1320e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
1321e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (sk_SSL_CIPHER_num(cipher_list) == 0) {
1322b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
1323b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 0;
1324b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
1325b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
1326b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return 1;
1327b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
1328b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
1329b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_CTX_set_cipher_list_tls10(SSL_CTX *ctx, const char *str) {
1330e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
1331e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      ctx->method, &ctx->cipher_list_tls10, NULL, str);
1332e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (cipher_list == NULL) {
133303bcf618b7ed811b305845461fbb5497dfe55ac3Kenny Root    return 0;
1334e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  }
1335e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root
1336e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
1337e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (sk_SSL_CIPHER_num(cipher_list) == 0) {
1338b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
1339d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
1340d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1341d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1342d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
1343d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1344d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1345d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_CTX_set_cipher_list_tls11(SSL_CTX *ctx, const char *str) {
1346e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
1347e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      ctx->method, &ctx->cipher_list_tls11, NULL, str);
1348e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (cipher_list == NULL) {
1349d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
1350d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1351d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1352e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
1353e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (sk_SSL_CIPHER_num(cipher_list) == 0) {
1354b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
1355d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
1356d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1357d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1358d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
1359d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1360d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1361e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_set_cipher_list(SSL *ssl, const char *str) {
1362e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
1363e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      ssl->ctx->method, &ssl->cipher_list, &ssl->cipher_list_by_id, str);
1364e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (cipher_list == NULL) {
1365d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
1366d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1367d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1368e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
1369e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (sk_SSL_CIPHER_num(cipher_list) == 0) {
1370e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
1371d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
1372d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1373d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1374e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  return 1;
1375d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1376d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
13774139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam LangleySTACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *ssl, const CBS *cbs) {
1378d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  CBS cipher_suites = *cbs;
1379d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  const SSL_CIPHER *c;
1380e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  STACK_OF(SSL_CIPHER) *sk;
1381d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
13824139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->s3) {
13834139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl->s3->send_connection_binding = 0;
1384d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1385d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1386d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (CBS_len(&cipher_suites) % 2 != 0) {
1387b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
1388d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
1389d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1390d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1391d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  sk = sk_SSL_CIPHER_new_null();
1392d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (sk == NULL) {
1393b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
1394d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    goto err;
1395d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1396d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1397d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  while (CBS_len(&cipher_suites) > 0) {
1398d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    uint16_t cipher_suite;
1399d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1400d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
1401b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
1402d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      goto err;
1403d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1404d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1405d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* Check for SCSV. */
14064139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->s3 && cipher_suite == (SSL3_CK_SCSV & 0xffff)) {
1407d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      /* SCSV is fatal if renegotiating. */
14084139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      if (ssl->s3->initial_handshake_complete) {
1409b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root        OPENSSL_PUT_ERROR(SSL, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
14104139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
1411d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        goto err;
1412d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
14134139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      ssl->s3->send_connection_binding = 1;
1414d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      continue;
1415d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1416d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1417d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* Check for FALLBACK_SCSV. */
14184139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->s3 && cipher_suite == (SSL3_CK_FALLBACK_SCSV & 0xffff)) {
14194139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      uint16_t max_version = ssl3_get_max_server_version(ssl);
14204139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      if (SSL_IS_DTLS(ssl) ? (uint16_t)ssl->version > max_version
14214139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley                         : (uint16_t)ssl->version < max_version) {
1422b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root        OPENSSL_PUT_ERROR(SSL, SSL_R_INAPPROPRIATE_FALLBACK);
14234139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley        ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL3_AD_INAPPROPRIATE_FALLBACK);
1424d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        goto err;
1425d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
1426d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      continue;
1427d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1428d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1429f4e427204234da139fd0585def4b4e22502e33f0Adam Langley    c = SSL_get_cipher_by_value(cipher_suite);
1430d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (c != NULL && !sk_SSL_CIPHER_push(sk, c)) {
1431b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
1432d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      goto err;
1433d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1434d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1435d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1436d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return sk;
1437d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1438d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr:
1439e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  sk_SSL_CIPHER_free(sk);
1440d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return NULL;
1441d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1442d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1443e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootconst char *SSL_get_servername(const SSL *ssl, const int type) {
1444d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (type != TLSEXT_NAMETYPE_host_name) {
1445d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
1446d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1447d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1448e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  /* Historically, |SSL_get_servername| was also the configuration getter
1449e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root   * corresponding to |SSL_set_tlsext_host_name|. */
1450e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->tlsext_hostname != NULL) {
1451e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    return ssl->tlsext_hostname;
1452e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  }
1453e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root
1454e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->session == NULL) {
1455e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    return NULL;
1456e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  }
1457e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  return ssl->session->tlsext_hostname;
1458d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1459d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1460e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_get_servername_type(const SSL *ssl) {
1461e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->session != NULL && ssl->session->tlsext_hostname != NULL) {
1462d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return TLSEXT_NAMETYPE_host_name;
1463d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1464d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1465d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return -1;
1466d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1467d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1468d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx) {
1469d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->signed_cert_timestamps_enabled = 1;
1470d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1471d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1472d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_enable_signed_cert_timestamps(SSL *ssl) {
1473d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ssl->signed_cert_timestamps_enabled = 1;
1474d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
1475d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1476d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1477d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx) {
1478d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->ocsp_stapling_enabled = 1;
1479d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1480d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1481d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_enable_ocsp_stapling(SSL *ssl) {
1482d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ssl->ocsp_stapling_enabled = 1;
1483d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
1484d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1485d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1486d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out,
1487d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                         size_t *out_len) {
1488d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  SSL_SESSION *session = ssl->session;
1489d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1490d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *out_len = 0;
1491d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *out = NULL;
1492d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ssl->server || !session || !session->tlsext_signed_cert_timestamp_list) {
1493d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return;
1494d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1495d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1496d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *out = session->tlsext_signed_cert_timestamp_list;
1497d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *out_len = session->tlsext_signed_cert_timestamp_list_length;
1498d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1499d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1500d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
1501d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                            size_t *out_len) {
1502d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  SSL_SESSION *session = ssl->session;
1503d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1504d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *out_len = 0;
1505d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *out = NULL;
1506d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ssl->server || !session || !session->ocsp_response) {
1507d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return;
1508d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1509d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *out = session->ocsp_response;
1510d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *out_len = session->ocsp_response_length;
1511d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1512d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1513b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list,
1514b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                           size_t list_len) {
1515b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ctx->signed_cert_timestamp_list);
1516b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ctx->signed_cert_timestamp_list_length = 0;
1517b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
1518b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ctx->signed_cert_timestamp_list = BUF_memdup(list, list_len);
1519b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ctx->signed_cert_timestamp_list == NULL) {
1520b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 0;
1521b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
1522b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ctx->signed_cert_timestamp_list_length = list_len;
1523b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
1524b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return 1;
1525b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
1526b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
1527b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response,
1528b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                              size_t response_len) {
1529b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ctx->ocsp_response);
1530b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ctx->ocsp_response_length = 0;
1531b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
1532b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ctx->ocsp_response = BUF_memdup(response, response_len);
1533b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ctx->ocsp_response == NULL) {
1534b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 0;
1535b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
1536b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ctx->ocsp_response_length = response_len;
1537b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
1538b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return 1;
1539b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
1540b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
1541b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_select_next_proto(uint8_t **out, uint8_t *out_len,
1542b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                          const uint8_t *server, unsigned server_len,
1543b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                          const uint8_t *client, unsigned client_len) {
1544d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  unsigned int i, j;
1545d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  const uint8_t *result;
1546d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  int status = OPENSSL_NPN_UNSUPPORTED;
1547d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1548d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* For each protocol in server preference order, see if we support it. */
1549d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  for (i = 0; i < server_len;) {
1550d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    for (j = 0; j < client_len;) {
1551d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      if (server[i] == client[j] &&
1552d9e397b599b13d642138480a28c14db7a136bf0Adam Langley          memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) {
1553d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        /* We found a match */
1554d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        result = &server[i];
1555d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        status = OPENSSL_NPN_NEGOTIATED;
1556d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        goto found;
1557d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      }
1558d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      j += client[j];
1559d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      j++;
1560d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1561d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    i += server[i];
1562d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    i++;
1563d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1564d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1565d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* There's no overlap between our protocols and the server's list. */
1566d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  result = client;
1567d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  status = OPENSSL_NPN_NO_OVERLAP;
1568d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1569d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyfound:
1570d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *out = (uint8_t *)result + 1;
1571b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  *out_len = result[0];
1572d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return status;
1573d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1574d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1575b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data,
1576b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                    unsigned *out_len) {
1577b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  *out_data = ssl->next_proto_negotiated;
1578b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (*out_data == NULL) {
1579b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    *out_len = 0;
1580d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
1581b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    *out_len = ssl->next_proto_negotiated_len;
1582d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1583d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1584d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1585d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_next_protos_advertised_cb(
1586d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    SSL_CTX *ctx,
1587b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg),
1588d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    void *arg) {
1589d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->next_protos_advertised_cb = cb;
1590d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->next_protos_advertised_cb_arg = arg;
1591d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1592d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1593d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_next_proto_select_cb(
1594b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len,
1595b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                            const uint8_t *in, unsigned in_len, void *arg),
1596d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    void *arg) {
1597d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->next_proto_select_cb = cb;
1598d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->next_proto_select_cb_arg = arg;
1599d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1600d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1601d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos,
1602d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                            unsigned protos_len) {
1603e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  OPENSSL_free(ctx->alpn_client_proto_list);
1604d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->alpn_client_proto_list = BUF_memdup(protos, protos_len);
1605d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!ctx->alpn_client_proto_list) {
1606d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 1;
1607d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1608d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->alpn_client_proto_list_len = protos_len;
1609d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1610d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 0;
1611d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1612d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1613d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) {
1614e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  OPENSSL_free(ssl->alpn_client_proto_list);
1615d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ssl->alpn_client_proto_list = BUF_memdup(protos, protos_len);
1616d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!ssl->alpn_client_proto_list) {
1617d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 1;
1618d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1619d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ssl->alpn_client_proto_list_len = protos_len;
1620d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1621d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 0;
1622d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1623d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1624d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
1625d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                int (*cb)(SSL *ssl, const uint8_t **out,
1626b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                          uint8_t *out_len, const uint8_t *in,
1627b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                          unsigned in_len, void *arg),
1628d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                void *arg) {
1629d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->alpn_select_cb = cb;
1630d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->alpn_select_cb_arg = arg;
1631d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1632d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1633b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data,
1634b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                            unsigned *out_len) {
1635b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  *out_data = NULL;
1636d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ssl->s3) {
1637b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    *out_data = ssl->s3->alpn_selected;
1638d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1639b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (*out_data == NULL) {
1640b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    *out_len = 0;
1641d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
1642b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    *out_len = ssl->s3->alpn_selected_len;
1643d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1644d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1645d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1646e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
1647e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                               const char *label, size_t label_len,
1648e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                               const uint8_t *context, size_t context_len,
1649e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                               int use_context) {
1650e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->version < TLS1_VERSION) {
1651e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return 0;
1652d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1653d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1654e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  return ssl->enc_method->export_keying_material(
1655e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      ssl, out, out_len, label, label_len, context, context_len, use_context);
1656d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1657d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1658d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
1659b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                      int (*cb)(X509_STORE_CTX *store_ctx,
1660b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                                void *arg),
1661d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                      void *arg) {
1662d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->app_verify_callback = cb;
1663d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->app_verify_arg = arg;
1664d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1665d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1666d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
1667d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                        int (*cb)(int, X509_STORE_CTX *)) {
1668d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->verify_mode = mode;
1669d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->default_verify_callback = cb;
1670d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1671d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1672d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) {
1673d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  X509_VERIFY_PARAM_set_depth(ctx->param, depth);
1674d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1675d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1676b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg),
1677d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                         void *arg) {
1678b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_cert_set_cert_cb(ctx->cert, cb, arg);
1679d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1680d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1681b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) {
1682b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_cert_set_cert_cb(ssl->cert, cb, arg);
1683d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1684d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
16854139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyvoid ssl_get_compatible_server_ciphers(SSL *ssl, uint32_t *out_mask_k,
1686e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                                       uint32_t *out_mask_a) {
16874139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  CERT *c = ssl->cert;
1688b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  int have_rsa_cert = 0, dh_tmp;
1689e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  uint32_t mask_k, mask_a;
1690b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  int have_ecc_cert = 0, ecdsa_ok;
1691d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  X509 *x;
1692d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1693a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root  dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
1694a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root
16954139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->cert->x509 != NULL && ssl_has_private_key(ssl)) {
16964139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl_private_key_type(ssl) == EVP_PKEY_RSA) {
1697b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      have_rsa_cert = 1;
16984139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    } else if (ssl_private_key_type(ssl) == EVP_PKEY_EC) {
1699b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      have_ecc_cert = 1;
1700b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
1701b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
1702b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
1703d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  mask_k = 0;
1704d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  mask_a = 0;
1705d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1706d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (dh_tmp) {
1707e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    mask_k |= SSL_kDHE;
1708d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1709b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (have_rsa_cert) {
1710b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    mask_k |= SSL_kRSA;
1711d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    mask_a |= SSL_aRSA;
1712d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1713d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1714d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* An ECC certificate may be usable for ECDSA cipher suites depending on the
1715d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * key usage extension and on the client's curve preferences. */
1716d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (have_ecc_cert) {
1717b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    x = c->x509;
1718d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* This call populates extension flags (ex_flags). */
1719d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    X509_check_purpose(x, -1, 0);
1720d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE)
1721d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                   ? (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)
1722d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                   : 1;
17234139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (!tls1_check_ec_cert(ssl, x)) {
1724d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      ecdsa_ok = 0;
1725b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
1726b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (ecdsa_ok) {
1727b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      mask_a |= SSL_aECDSA;
1728b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    }
1729a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root  }
1730a04d78d392463df4e69a64360c952ffa5abd22f7Kenny Root
1731b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* If we are considering an ECC cipher suite that uses an ephemeral EC
17324139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley   * key, check for a shared curve. */
17334139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  uint16_t unused;
17344139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (tls1_get_shared_curve(ssl, &unused)) {
1735b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    mask_k |= SSL_kECDHE;
1736d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1737d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1738b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* PSK requires a server callback. */
17394139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->psk_server_callback != NULL) {
1740b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    mask_k |= SSL_kPSK;
1741b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    mask_a |= SSL_aPSK;
1742d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1743d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1744b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  *out_mask_k = mask_k;
1745b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  *out_mask_a = mask_a;
1746d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1747d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1748e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootvoid ssl_update_cache(SSL *ssl, int mode) {
1749e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  SSL_CTX *ctx = ssl->initial_ctx;
1750e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  /* Never cache sessions with empty session IDs. */
1751e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (ssl->session->session_id_length == 0 ||
1752e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      (ctx->session_cache_mode & mode) != mode) {
1753d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return;
1754d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1755d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1756e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  /* Clients never use the internal session cache. */
1757e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  int use_internal_cache = ssl->server && !(ctx->session_cache_mode &
1758e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root                                            SSL_SESS_CACHE_NO_INTERNAL_STORE);
175956d250321ea9dfa66ea9afa599f12c83a4147c86Adam Langley
1760e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  /* A client may see new sessions on abbreviated handshakes if the server
1761e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root   * decides to renew the ticket. Once the handshake is completed, it should be
1762e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root   * inserted into the cache. */
1763e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (!ssl->hit || (!ssl->server && ssl->tlsext_ticket_expected)) {
1764e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    if (use_internal_cache) {
1765e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      SSL_CTX_add_session(ctx, ssl->session);
1766e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    }
1767e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    if (ctx->new_session_cb != NULL &&
1768e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root        !ctx->new_session_cb(ssl, SSL_SESSION_up_ref(ssl->session))) {
1769e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      /* |new_session_cb|'s return value signals whether it took ownership. */
1770e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      SSL_SESSION_free(ssl->session);
1771d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1772d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1773d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1774e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  if (use_internal_cache &&
1775e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      !(ctx->session_cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR)) {
1776e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    /* Automatically flush the internal session cache every 255 connections. */
1777e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    int flush_cache = 0;
1778f4e427204234da139fd0585def4b4e22502e33f0Adam Langley    CRYPTO_MUTEX_lock_write(&ctx->lock);
1779e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    ctx->handshakes_since_cache_flush++;
1780e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    if (ctx->handshakes_since_cache_flush >= 255) {
1781e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      flush_cache = 1;
1782e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      ctx->handshakes_since_cache_flush = 0;
1783e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    }
1784f4e427204234da139fd0585def4b4e22502e33f0Adam Langley    CRYPTO_MUTEX_unlock(&ctx->lock);
1785e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
1786e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    if (flush_cache) {
1787e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      SSL_CTX_flush_sessions(ctx, (unsigned long)time(NULL));
1788d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1789d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1790d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1791d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1792d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic const char *ssl_get_version(int version) {
1793d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  switch (version) {
1794d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    case TLS1_2_VERSION:
1795d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return "TLSv1.2";
1796d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1797d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    case TLS1_1_VERSION:
1798d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return "TLSv1.1";
1799d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1800d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    case TLS1_VERSION:
1801d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return "TLSv1";
1802d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1803d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    case SSL3_VERSION:
1804d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return "SSLv3";
1805d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1806e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    case DTLS1_VERSION:
1807e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      return "DTLSv1";
1808e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
1809e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    case DTLS1_2_VERSION:
1810e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      return "DTLSv1.2";
1811e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
1812d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    default:
1813d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return "unknown";
1814d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1815d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1816d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1817b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootconst char *SSL_get_version(const SSL *ssl) {
1818b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl_get_version(ssl->version);
1819b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
1820b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
1821b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootconst char *SSL_SESSION_get_version(const SSL_SESSION *session) {
1822b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl_get_version(session->ssl_version);
1823d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1824d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
18254139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyvoid ssl_clear_cipher_ctx(SSL *ssl) {
18264139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  SSL_AEAD_CTX_free(ssl->aead_read_ctx);
18274139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->aead_read_ctx = NULL;
18284139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  SSL_AEAD_CTX_free(ssl->aead_write_ctx);
18294139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->aead_write_ctx = NULL;
1830d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1831d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
18324139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam LangleyX509 *SSL_get_certificate(const SSL *ssl) {
18334139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->cert != NULL) {
18344139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    return ssl->cert->x509;
1835d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1836d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1837d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return NULL;
1838d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1839d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
18404139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam LangleyEVP_PKEY *SSL_get_privatekey(const SSL *ssl) {
18414139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->cert != NULL) {
18424139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    return ssl->cert->privatekey;
1843d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1844d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1845d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return NULL;
1846d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1847d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1848d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyX509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
1849d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ctx->cert != NULL) {
1850b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return ctx->cert->x509;
1851d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1852d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1853d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return NULL;
1854d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1855d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1856d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyEVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) {
1857d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ctx->cert != NULL) {
1858b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return ctx->cert->privatekey;
1859d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1860d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1861d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return NULL;
1862d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1863d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1864b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootconst SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl) {
1865b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->aead_write_ctx == NULL) {
1866f4e427204234da139fd0585def4b4e22502e33f0Adam Langley    return NULL;
1867d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1868b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->aead_write_ctx->cipher;
1869d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1870d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
18714139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyconst COMP_METHOD *SSL_get_current_compression(SSL *ssl) { return NULL; }
1872d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
18734139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyconst COMP_METHOD *SSL_get_current_expansion(SSL *ssl) { return NULL; }
1874d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
18754139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint ssl_init_wbio_buffer(SSL *ssl, int push) {
1876d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  BIO *bbio;
1877d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
18784139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->bbio == NULL) {
1879d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    bbio = BIO_new(BIO_f_buffer());
1880d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (bbio == NULL) {
1881d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
1882d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
18834139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl->bbio = bbio;
1884d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
18854139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    bbio = ssl->bbio;
18864139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->bbio == ssl->wbio) {
18874139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      ssl->wbio = BIO_pop(ssl->wbio);
1888d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1889d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1890d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1891d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  BIO_reset(bbio);
1892d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!BIO_set_read_buffer_size(bbio, 1)) {
1893b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
1894d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
1895d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1896d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1897d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (push) {
18984139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->wbio != bbio) {
18994139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      ssl->wbio = BIO_push(bbio, ssl->wbio);
1900d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1901d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
19024139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->wbio == bbio) {
19034139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      ssl->wbio = BIO_pop(bbio);
1904d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
1905d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1906d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1907d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
1908d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1909d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
19104139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyvoid ssl_free_wbio_buffer(SSL *ssl) {
19114139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->bbio == NULL) {
1912d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return;
1913d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1914d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
19154139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->bbio == ssl->wbio) {
1916d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* remove buffering */
19174139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl->wbio = BIO_pop(ssl->wbio);
1918d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1919d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
19204139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  BIO_free(ssl->bbio);
19214139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->bbio = NULL;
1922d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1923d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1924d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) {
1925fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  ctx->quiet_shutdown = (mode != 0);
1926d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1927d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1928d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) {
1929d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ctx->quiet_shutdown;
1930d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1931d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1932fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langleyvoid SSL_set_quiet_shutdown(SSL *ssl, int mode) {
1933fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  ssl->quiet_shutdown = (mode != 0);
1934fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley}
1935d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1936e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_get_quiet_shutdown(const SSL *ssl) { return ssl->quiet_shutdown; }
1937d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1938e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootvoid SSL_set_shutdown(SSL *ssl, int mode) {
1939e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  /* It is an error to clear any bits that have already been set. (We can't try
1940e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root   * to get a second close_notify or send two.) */
1941e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  assert((ssl->shutdown & mode) == ssl->shutdown);
1942e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root
1943e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  ssl->shutdown |= mode;
1944e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root}
1945d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1946e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_get_shutdown(const SSL *ssl) { return ssl->shutdown; }
1947d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1948e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_version(const SSL *ssl) { return ssl->version; }
1949d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1950d9e397b599b13d642138480a28c14db7a136bf0Adam LangleySSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return ssl->ctx; }
1951d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1952d9e397b599b13d642138480a28c14db7a136bf0Adam LangleySSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) {
1953d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ssl->ctx == ctx) {
1954d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return ssl->ctx;
1955d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1956d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1957d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (ctx == NULL) {
1958d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ctx = ssl->initial_ctx;
1959d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
1960d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1961e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ssl_cert_free(ssl->cert);
1962d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ssl->cert = ssl_cert_dup(ctx->cert);
1963e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
1964f4e427204234da139fd0585def4b4e22502e33f0Adam Langley  CRYPTO_refcount_inc(&ctx->references);
1965e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  SSL_CTX_free(ssl->ctx); /* decrement reference count */
1966d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ssl->ctx = ctx;
1967d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1968d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ssl->sid_ctx_length = ctx->sid_ctx_length;
1969d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx));
1970d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  memcpy(ssl->sid_ctx, ctx->sid_ctx, sizeof(ssl->sid_ctx));
1971d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1972d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ssl->ctx;
1973d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1974d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1975d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) {
1976d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return X509_STORE_set_default_paths(ctx->cert_store);
1977d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1978d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1979b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file,
1980b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                  const char *ca_dir) {
1981b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return X509_STORE_load_locations(ctx->cert_store, ca_file, ca_dir);
1982d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1983d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1984d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_set_info_callback(SSL *ssl,
1985e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root                           void (*cb)(const SSL *ssl, int type, int value)) {
1986d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ssl->info_callback = cb;
1987d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1988d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1989e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootvoid (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, int type,
1990e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root                                              int value) {
1991d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ssl->info_callback;
1992d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
1993d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1994d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_state(const SSL *ssl) { return ssl->state; }
1995d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1996f4e427204234da139fd0585def4b4e22502e33f0Adam Langleyvoid SSL_set_state(SSL *ssl, int state) { }
1997d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1998b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_set_verify_result(SSL *ssl, long result) {
1999b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->verify_result = result;
2000b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root}
2001d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2002d9e397b599b13d642138480a28c14db7a136bf0Adam Langleylong SSL_get_verify_result(const SSL *ssl) { return ssl->verify_result; }
2003d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
20044139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
2005d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
2006e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  int index;
2007e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl, &index, argl, argp,
20084139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley                               dup_func, free_func)) {
2009e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return -1;
2010e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
2011e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return index;
2012d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2013d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2014b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_set_ex_data(SSL *ssl, int idx, void *arg) {
2015b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return CRYPTO_set_ex_data(&ssl->ex_data, idx, arg);
2016d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2017d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2018b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid *SSL_get_ex_data(const SSL *ssl, int idx) {
2019b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return CRYPTO_get_ex_data(&ssl->ex_data, idx);
2020d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2021d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
20224139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
2023d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                             CRYPTO_EX_dup *dup_func,
2024d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                             CRYPTO_EX_free *free_func) {
2025e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  int index;
2026e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl_ctx, &index, argl, argp,
20274139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley                               dup_func, free_func)) {
2028e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return -1;
2029e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
2030e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return index;
2031d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2032d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2033b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *arg) {
2034b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return CRYPTO_set_ex_data(&ctx->ex_data, idx, arg);
2035d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2036d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2037b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) {
2038b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return CRYPTO_get_ex_data(&ctx->ex_data, idx);
2039d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2040d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2041d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyX509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
2042d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return ctx->cert_store;
2043d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2044d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2045d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) {
2046e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  X509_STORE_free(ctx->cert_store);
2047d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->cert_store = store;
2048d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2049d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2050e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_want(const SSL *ssl) { return ssl->rwstate; }
2051d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2052d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
2053d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                  RSA *(*cb)(SSL *ssl, int is_export,
2054d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                             int keylength)) {
2055d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2056d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2057d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb)(SSL *ssl, int is_export,
2058d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                                   int keylength)) {
2059d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2060d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2061d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
2062e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                                 DH *(*callback)(SSL *ssl, int is_export,
2063e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                                                 int keylength)) {
2064e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ctx->cert->dh_tmp_cb = callback;
2065d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2066d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2067e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid SSL_set_tmp_dh_callback(SSL *ssl, DH *(*callback)(SSL *ssl, int is_export,
2068e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                                                       int keylength)) {
2069e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ssl->cert->dh_tmp_cb = callback;
2070d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2071d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2072d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) {
2073d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
2074b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
2075d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
2076d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2077d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2078e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  OPENSSL_free(ctx->psk_identity_hint);
2079d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2080d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (identity_hint != NULL) {
2081d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ctx->psk_identity_hint = BUF_strdup(identity_hint);
2082d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (ctx->psk_identity_hint == NULL) {
2083d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
2084d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2085d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
2086d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    ctx->psk_identity_hint = NULL;
2087d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2088d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2089d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
2090d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2091d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2092b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_use_psk_identity_hint(SSL *ssl, const char *identity_hint) {
2093b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl == NULL) {
2094d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
2095d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2096d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2097d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
2098b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
2099d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
2100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Clear currently configured hint, if any. */
2103b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ssl->psk_identity_hint);
2104b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->psk_identity_hint = NULL;
2105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (identity_hint != NULL) {
2107b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    ssl->psk_identity_hint = BUF_strdup(identity_hint);
2108b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (ssl->psk_identity_hint == NULL) {
2109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
2110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
2114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2116b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootconst char *SSL_get_psk_identity_hint(const SSL *ssl) {
2117b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl == NULL) {
2118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
2119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2120b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->psk_identity_hint;
2121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2123b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootconst char *SSL_get_psk_identity(const SSL *ssl) {
2124b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl == NULL || ssl->session == NULL) {
2125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return NULL;
2126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2128b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return ssl->session->psk_identity;
2129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2131d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_set_psk_client_callback(
2132b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity,
2133b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                             unsigned max_identity_len, uint8_t *psk,
2134b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                             unsigned max_psk_len)) {
2135b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->psk_client_callback = cb;
2136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2138d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_psk_client_callback(
2139b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *hint, char *identity,
2140b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                 unsigned max_identity_len, uint8_t *psk,
2141b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                 unsigned max_psk_len)) {
2142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->psk_client_callback = cb;
2143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2145d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_set_psk_server_callback(
2146b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    SSL *ssl, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk,
2147b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                             unsigned max_psk_len)) {
2148b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->psk_server_callback = cb;
2149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2151d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_psk_server_callback(
2152b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *identity,
2153b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                 uint8_t *psk, unsigned max_psk_len)) {
2154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  ctx->psk_server_callback = cb;
2155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2157d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_CTX_set_msg_callback(SSL_CTX *ctx,
2158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                              void (*cb)(int write_p, int version,
2159d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                         int content_type, const void *buf,
2160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                         size_t len, SSL *ssl, void *arg)) {
2161e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ctx->msg_callback = cb;
2162e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
2163e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
2164e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid SSL_CTX_set_msg_callback_arg(SSL_CTX *ctx, void *arg) {
2165e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ctx->msg_callback_arg = arg;
2166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2167e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
2168d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_set_msg_callback(SSL *ssl,
2169d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                          void (*cb)(int write_p, int version, int content_type,
2170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                     const void *buf, size_t len, SSL *ssl,
2171d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                                     void *arg)) {
2172e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ssl->msg_callback = cb;
2173e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
2174e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
2175e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid SSL_set_msg_callback_arg(SSL *ssl, void *arg) {
2176e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ssl->msg_callback_arg = arg;
2177d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2178d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
21794139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyvoid SSL_CTX_set_keylog_callback(SSL_CTX *ctx,
21804139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley                                 void (*cb)(const SSL *ssl, const char *line)) {
21814139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ctx->keylog_callback = cb;
2182d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2183d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2184d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) {
2185d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  static const char hextable[] = "0123456789abcdef";
2186d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint8_t *out;
2187d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  size_t i;
2188d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2189d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (!CBB_add_space(cbb, &out, in_len * 2)) {
2190d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
2191d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2192d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2193d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  for (i = 0; i < in_len; i++) {
2194d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    *(out++) = (uint8_t)hextable[in[i] >> 4];
2195d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    *(out++) = (uint8_t)hextable[in[i] & 0xf];
2196d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2197d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2198d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
2199d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2200d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
22014139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint ssl_log_rsa_client_key_exchange(const SSL *ssl,
22024139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley                                    const uint8_t *encrypted_premaster,
22034139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley                                    size_t encrypted_premaster_len,
22044139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley                                    const uint8_t *premaster,
22054139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley                                    size_t premaster_len) {
22064139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->ctx->keylog_callback == NULL) {
2207d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 1;
2208d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2209d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2210d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (encrypted_premaster_len < 8) {
2211b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
2212d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
2213d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2214d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
22154139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  CBB cbb;
22164139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  uint8_t *out;
22174139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  size_t out_len;
2218b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (!CBB_init(&cbb, 4 + 16 + 1 + premaster_len * 2 + 1) ||
2219b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      !CBB_add_bytes(&cbb, (const uint8_t *)"RSA ", 4) ||
2220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      /* Only the first 8 bytes of the encrypted premaster secret are
2221d9e397b599b13d642138480a28c14db7a136bf0Adam Langley       * logged. */
2222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !cbb_add_hex(&cbb, encrypted_premaster, 8) ||
2223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
2224d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !cbb_add_hex(&cbb, premaster, premaster_len) ||
22254139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      !CBB_add_u8(&cbb, 0 /* NUL */) ||
2226d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !CBB_finish(&cbb, &out, &out_len)) {
2227d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    CBB_cleanup(&cbb);
2228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
2229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2230d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
22314139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->ctx->keylog_callback(ssl, (const char *)out);
2232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  OPENSSL_free(out);
22334139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  return 1;
2234d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2235d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
22364139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint ssl_log_master_secret(const SSL *ssl, const uint8_t *client_random,
22374139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley                          size_t client_random_len, const uint8_t *master,
22384139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley                          size_t master_len) {
22394139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->ctx->keylog_callback == NULL) {
2240d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 1;
2241d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2242d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2243d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (client_random_len != 32) {
2244b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
2245d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
2246d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2247d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
22484139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  CBB cbb;
22494139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  uint8_t *out;
22504139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  size_t out_len;
2251b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (!CBB_init(&cbb, 14 + 64 + 1 + master_len * 2 + 1) ||
2252b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      !CBB_add_bytes(&cbb, (const uint8_t *)"CLIENT_RANDOM ", 14) ||
2253d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !cbb_add_hex(&cbb, client_random, 32) ||
2254d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
2255d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !cbb_add_hex(&cbb, master, master_len) ||
22564139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      !CBB_add_u8(&cbb, 0 /* NUL */) ||
2257d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      !CBB_finish(&cbb, &out, &out_len)) {
2258d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    CBB_cleanup(&cbb);
2259d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
2260d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2261d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
22624139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->ctx->keylog_callback(ssl, (const char *)out);
2263d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  OPENSSL_free(out);
22644139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  return 1;
2265d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2266d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2267e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_is_init_finished(const SSL *ssl) {
2268e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  return ssl->state == SSL_ST_OK;
2269e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root}
2270e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root
2271e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_in_init(const SSL *ssl) {
2272e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  return (ssl->state & SSL_ST_INIT) != 0;
2273e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root}
2274e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root
2275e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootint SSL_in_false_start(const SSL *ssl) {
2276e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  return ssl->s3->tmp.in_false_start;
2277e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
2278e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
22794139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint SSL_cutthrough_complete(const SSL *ssl) {
22804139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  return SSL_in_false_start(ssl);
2281d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2282d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2283d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid SSL_get_structure_sizes(size_t *ssl_size, size_t *ssl_ctx_size,
2284d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                             size_t *ssl_session_size) {
2285d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *ssl_size = sizeof(SSL);
2286d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *ssl_ctx_size = sizeof(SSL_CTX);
2287d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *ssl_session_size = sizeof(SSL_SESSION);
2288d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2289d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
22904139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint ssl3_can_false_start(const SSL *ssl) {
22914139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  const SSL_CIPHER *const cipher = SSL_get_current_cipher(ssl);
2292d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2293e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  /* False Start only for TLS 1.2 with an ECDHE+AEAD cipher and ALPN or NPN. */
22944139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  return !SSL_IS_DTLS(ssl) &&
22954139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      SSL_version(ssl) >= TLS1_2_VERSION &&
22964139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      (ssl->s3->alpn_selected || ssl->s3->next_proto_neg_seen) &&
2297e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      cipher != NULL &&
2298e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      cipher->algorithm_mkey == SSL_kECDHE &&
22994139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      cipher->algorithm_mac == SSL_AEAD;
2300d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2302d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) {
2303d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  switch (version) {
2304d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    case SSL3_VERSION:
2305d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return &SSLv3_enc_data;
2306d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2307d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    case TLS1_VERSION:
2308d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return &TLSv1_enc_data;
2309d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2310e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    case DTLS1_VERSION:
2311d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    case TLS1_1_VERSION:
2312d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return &TLSv1_1_enc_data;
2313d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2314e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    case DTLS1_2_VERSION:
2315d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    case TLS1_2_VERSION:
2316d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return &TLSv1_2_enc_data;
2317d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2318d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    default:
2319d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return NULL;
2320d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2321d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2322d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
23234139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyuint16_t ssl3_get_max_server_version(const SSL *ssl) {
2324d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint16_t max_version;
2325d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
23264139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (SSL_IS_DTLS(ssl)) {
23274139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    max_version = (ssl->max_version != 0) ? ssl->max_version : DTLS1_2_VERSION;
23284139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (!(ssl->options & SSL_OP_NO_DTLSv1_2) &&
23294139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley        DTLS1_2_VERSION >= max_version) {
2330d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return DTLS1_2_VERSION;
2331d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
23324139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (!(ssl->options & SSL_OP_NO_DTLSv1) && DTLS1_VERSION >= max_version) {
2333d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return DTLS1_VERSION;
2334d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2335d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
2336d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2337d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
23384139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  max_version = (ssl->max_version != 0) ? ssl->max_version : TLS1_2_VERSION;
23394139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (!(ssl->options & SSL_OP_NO_TLSv1_2) && TLS1_2_VERSION <= max_version) {
2340d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return TLS1_2_VERSION;
2341d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
23424139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (!(ssl->options & SSL_OP_NO_TLSv1_1) && TLS1_1_VERSION <= max_version) {
2343d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return TLS1_1_VERSION;
2344d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
23454139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (!(ssl->options & SSL_OP_NO_TLSv1) && TLS1_VERSION <= max_version) {
2346d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return TLS1_VERSION;
2347d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
23484139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (!(ssl->options & SSL_OP_NO_SSLv3) && SSL3_VERSION <= max_version) {
2349d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return SSL3_VERSION;
2350d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2351d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 0;
2352d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2353d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
23544139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyuint16_t ssl3_get_mutual_version(SSL *ssl, uint16_t client_version) {
2355d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint16_t version = 0;
2356d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
23574139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (SSL_IS_DTLS(ssl)) {
2358d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* Clamp client_version to max_version. */
23594139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->max_version != 0 && client_version < ssl->max_version) {
23604139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      client_version = ssl->max_version;
2361d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2362d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
23634139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (client_version <= DTLS1_2_VERSION &&
23644139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley        !(ssl->options & SSL_OP_NO_DTLSv1_2)) {
2365d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      version = DTLS1_2_VERSION;
2366d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    } else if (client_version <= DTLS1_VERSION &&
23674139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley               !(ssl->options & SSL_OP_NO_DTLSv1)) {
2368d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      version = DTLS1_VERSION;
2369d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2370d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2371d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* Check against min_version. */
23724139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (version != 0 && ssl->min_version != 0 && version > ssl->min_version) {
2373d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
2374d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2375d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return version;
2376d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
2377d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* Clamp client_version to max_version. */
23784139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->max_version != 0 && client_version > ssl->max_version) {
23794139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      client_version = ssl->max_version;
2380d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2381d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
23824139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (client_version >= TLS1_2_VERSION &&
23834139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley        !(ssl->options & SSL_OP_NO_TLSv1_2)) {
2384d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      version = TLS1_2_VERSION;
2385d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    } else if (client_version >= TLS1_1_VERSION &&
23864139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley               !(ssl->options & SSL_OP_NO_TLSv1_1)) {
2387d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      version = TLS1_1_VERSION;
23884139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    } else if (client_version >= TLS1_VERSION &&
23894139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley               !(ssl->options & SSL_OP_NO_TLSv1)) {
2390d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      version = TLS1_VERSION;
23914139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    } else if (client_version >= SSL3_VERSION &&
23924139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley               !(ssl->options & SSL_OP_NO_SSLv3)) {
2393d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      version = SSL3_VERSION;
2394d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2395d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2396d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* Check against min_version. */
23974139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (version != 0 && ssl->min_version != 0 && version < ssl->min_version) {
2398d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
2399d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2400d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return version;
2401d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2402d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2403d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
24044139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyuint16_t ssl3_get_max_client_version(SSL *ssl) {
24054139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  uint32_t options = ssl->options;
2406d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint16_t version = 0;
2407d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2408d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* OpenSSL's API for controlling versions entails blacklisting individual
2409d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * protocols. This has two problems. First, on the client, the protocol can
2410d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * only express a contiguous range of versions. Second, a library consumer
2411d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * trying to set a maximum version cannot disable protocol versions that get
2412d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * added in a future version of the library.
2413d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   *
2414d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * To account for both of these, OpenSSL interprets the client-side bitmask
2415d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * as a min/max range by picking the lowest contiguous non-empty range of
2416d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * enabled protocols. Note that this means it is impossible to set a maximum
2417d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * version of TLS 1.2 in a future-proof way.
2418d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   *
2419d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * By this scheme, the maximum version is the lowest version V such that V is
2420d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * enabled and V+1 is disabled or unimplemented. */
24214139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (SSL_IS_DTLS(ssl)) {
2422d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!(options & SSL_OP_NO_DTLSv1_2)) {
2423d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      version = DTLS1_2_VERSION;
2424d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2425d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!(options & SSL_OP_NO_DTLSv1) && (options & SSL_OP_NO_DTLSv1_2)) {
2426d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      version = DTLS1_VERSION;
2427d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
24284139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->max_version != 0 && version < ssl->max_version) {
24294139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      version = ssl->max_version;
2430d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2431d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
2432d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!(options & SSL_OP_NO_TLSv1_2)) {
2433d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      version = TLS1_2_VERSION;
2434d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2435d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!(options & SSL_OP_NO_TLSv1_1) && (options & SSL_OP_NO_TLSv1_2)) {
2436d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      version = TLS1_1_VERSION;
2437d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2438d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!(options & SSL_OP_NO_TLSv1) && (options & SSL_OP_NO_TLSv1_1)) {
2439d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      version = TLS1_VERSION;
2440d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2441d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (!(options & SSL_OP_NO_SSLv3) && (options & SSL_OP_NO_TLSv1)) {
2442d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      version = SSL3_VERSION;
2443d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
24444139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->max_version != 0 && version > ssl->max_version) {
24454139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      version = ssl->max_version;
2446d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2447d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2448d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2449d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return version;
2450d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2451d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
24524139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint ssl3_is_version_enabled(SSL *ssl, uint16_t version) {
24534139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (SSL_IS_DTLS(ssl)) {
24544139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->max_version != 0 && version < ssl->max_version) {
2455d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
2456d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
24574139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->min_version != 0 && version > ssl->min_version) {
2458d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
2459d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2460d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2461d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    switch (version) {
2462d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      case DTLS1_VERSION:
24634139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley        return !(ssl->options & SSL_OP_NO_DTLSv1);
2464d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2465d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      case DTLS1_2_VERSION:
24664139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley        return !(ssl->options & SSL_OP_NO_DTLSv1_2);
2467d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2468d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      default:
2469d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        return 0;
2470d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2471d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  } else {
24724139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->max_version != 0 && version > ssl->max_version) {
2473d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
2474d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
24754139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    if (ssl->min_version != 0 && version < ssl->min_version) {
2476d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      return 0;
2477d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2478d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2479d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    switch (version) {
2480d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      case SSL3_VERSION:
24814139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley        return !(ssl->options & SSL_OP_NO_SSLv3);
2482d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2483d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      case TLS1_VERSION:
24844139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley        return !(ssl->options & SSL_OP_NO_TLSv1);
2485d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2486d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      case TLS1_1_VERSION:
24874139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley        return !(ssl->options & SSL_OP_NO_TLSv1_1);
2488d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2489d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      case TLS1_2_VERSION:
24904139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley        return !(ssl->options & SSL_OP_NO_TLSv1_2);
2491d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2492d9e397b599b13d642138480a28c14db7a136bf0Adam Langley      default:
2493d9e397b599b13d642138480a28c14db7a136bf0Adam Langley        return 0;
2494d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
2495d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2496d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2497d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
24984139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyuint16_t ssl3_version_from_wire(SSL *ssl, uint16_t wire_version) {
24994139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (!SSL_IS_DTLS(ssl)) {
2500d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return wire_version;
2501d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2502d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2503d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint16_t tls_version = ~wire_version;
2504d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint16_t version = tls_version + 0x0201;
2505d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* If either component overflowed, clamp it so comparisons still work. */
2506d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if ((version >> 8) < (tls_version >> 8)) {
2507d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    version = 0xff00 | (version & 0xff);
2508d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2509d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if ((version & 0xff) < (tls_version & 0xff)) {
2510d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    version = (version & 0xff00) | 0xff;
2511d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2512d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* DTLS 1.0 maps to TLS 1.1, not TLS 1.0. */
2513d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (version == TLS1_VERSION) {
2514d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    version = TLS1_1_VERSION;
2515d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2516d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return version;
2517d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
2518d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2519b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_cache_hit(SSL *ssl) { return SSL_session_reused(ssl); }
2520d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2521b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_is_server(SSL *ssl) { return ssl->server; }
2522d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2523e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootvoid SSL_CTX_set_select_certificate_cb(
2524e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root    SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
2525e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  ctx->select_certificate_cb = cb;
2526e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root}
2527e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root
2528e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyvoid SSL_CTX_set_dos_protection_cb(
2529e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
2530e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  ctx->dos_protection_cb = cb;
2531e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
2532e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
2533e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootvoid SSL_set_renegotiate_mode(SSL *ssl, enum ssl_renegotiate_mode_t mode) {
2534e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  ssl->renegotiate_mode = mode;
2535e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root}
2536e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root
2537e99801b603dea8893dcc61c70b327ef2d00b652cKenny Rootvoid SSL_set_reject_peer_renegotiations(SSL *ssl, int reject) {
2538e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root  SSL_set_renegotiate_mode(
2539e99801b603dea8893dcc61c70b327ef2d00b652cKenny Root      ssl, reject ? ssl_renegotiate_never : ssl_renegotiate_freely);
2540e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
2541e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
2542e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
2543e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley                      const RC4_KEY **write_key) {
2544e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (ssl->aead_read_ctx == NULL || ssl->aead_write_ctx == NULL) {
2545e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return 0;
2546e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
2547e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
2548e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return EVP_AEAD_CTX_get_rc4_state(&ssl->aead_read_ctx->ctx, read_key) &&
2549e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley         EVP_AEAD_CTX_get_rc4_state(&ssl->aead_write_ctx->ctx, write_key);
2550e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}
2551e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
2552fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langleyint SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv,
2553fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley                const uint8_t **out_write_iv, size_t *out_iv_len) {
2554fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  if (ssl->aead_read_ctx == NULL || ssl->aead_write_ctx == NULL) {
2555fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley    return 0;
2556fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  }
2557fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley
2558fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  size_t write_iv_len;
2559fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  if (!EVP_AEAD_CTX_get_iv(&ssl->aead_read_ctx->ctx, out_read_iv, out_iv_len) ||
2560fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley      !EVP_AEAD_CTX_get_iv(&ssl->aead_write_ctx->ctx, out_write_iv,
2561fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley                           &write_iv_len) ||
2562fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley      *out_iv_len != write_iv_len) {
2563fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley    return 0;
2564fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  }
2565fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley
2566fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  return 1;
2567fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley}
2568fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley
2569fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langleyuint8_t SSL_get_server_key_exchange_hash(const SSL *ssl) {
2570fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley  return ssl->s3->tmp.server_key_exchange_hash;
2571fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley}
2572fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley
2573b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootint SSL_clear(SSL *ssl) {
2574b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->method == NULL) {
2575b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_NO_METHOD_SPECIFIED);
2576b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 0;
2577b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
2578b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
2579b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl_clear_bad_session(ssl)) {
2580b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    SSL_SESSION_free(ssl->session);
2581b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    ssl->session = NULL;
2582b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
2583b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
2584b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->hit = 0;
2585b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->shutdown = 0;
2586b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
2587b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* SSL_clear may be called before or after the |ssl| is initialized in either
2588b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * accept or connect state. In the latter case, SSL_clear should preserve the
2589b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * half and reset |ssl->state| accordingly. */
2590b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->handshake_func != NULL) {
2591b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    if (ssl->server) {
2592b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      SSL_set_accept_state(ssl);
2593b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    } else {
2594b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root      SSL_set_connect_state(ssl);
2595f4e427204234da139fd0585def4b4e22502e33f0Adam Langley    }
2596b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  } else {
2597b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    assert(ssl->state == 0);
2598f4e427204234da139fd0585def4b4e22502e33f0Adam Langley  }
2599f4e427204234da139fd0585def4b4e22502e33f0Adam Langley
2600b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* TODO(davidben): Some state on |ssl| is reset both in |SSL_new| and
2601b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * |SSL_clear| because it is per-connection state rather than configuration
2602b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * state. Per-connection state should be on |ssl->s3| and |ssl->d1| so it is
2603b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * naturally reset at the right points between |SSL_new|, |SSL_clear|, and
2604b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * |ssl3_new|. */
2605b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
2606b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->rwstate = SSL_NOTHING;
2607b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
2608b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  BUF_MEM_free(ssl->init_buf);
2609b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->init_buf = NULL;
2610b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
2611b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl_clear_cipher_ctx(ssl);
2612b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
2613b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  OPENSSL_free(ssl->next_proto_negotiated);
2614b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->next_proto_negotiated = NULL;
2615b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->next_proto_negotiated_len = 0;
2616b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
2617b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* The ssl->d1->mtu is simultaneously configuration (preserved across
2618b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * clear) and connection-specific state (gets reset).
2619b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   *
2620b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * TODO(davidben): Avoid this. */
2621b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  unsigned mtu = 0;
2622b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (ssl->d1 != NULL) {
2623b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    mtu = ssl->d1->mtu;
2624f4e427204234da139fd0585def4b4e22502e33f0Adam Langley  }
2625f4e427204234da139fd0585def4b4e22502e33f0Adam Langley
2626b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->method->ssl_free(ssl);
2627b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (!ssl->method->ssl_new(ssl)) {
2628b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    return 0;
2629f4e427204234da139fd0585def4b4e22502e33f0Adam Langley  }
2630b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->enc_method = ssl3_get_enc_method(ssl->version);
2631b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  assert(ssl->enc_method != NULL);
2632f4e427204234da139fd0585def4b4e22502e33f0Adam Langley
2633b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  if (SSL_IS_DTLS(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
2634b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    ssl->d1->mtu = mtu;
2635b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  }
2636f4e427204234da139fd0585def4b4e22502e33f0Adam Langley
2637b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  ssl->client_version = ssl->version;
2638f4e427204234da139fd0585def4b4e22502e33f0Adam Langley
2639b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return 1;
264056d250321ea9dfa66ea9afa599f12c83a4147c86Adam Langley}
264156d250321ea9dfa66ea9afa599f12c83a4147c86Adam Langley
2642e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_CTX_sess_connect(const SSL_CTX *ctx) { return 0; }
2643e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_CTX_sess_connect_good(const SSL_CTX *ctx) { return 0; }
2644e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx) { return 0; }
2645e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_CTX_sess_accept(const SSL_CTX *ctx) { return 0; }
2646e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx) { return 0; }
2647e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_CTX_sess_accept_good(const SSL_CTX *ctx) { return 0; }
2648e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_CTX_sess_hits(const SSL_CTX *ctx) { return 0; }
2649e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_CTX_sess_cb_hits(const SSL_CTX *ctx) { return 0; }
2650e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_CTX_sess_misses(const SSL_CTX *ctx) { return 0; }
2651e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_CTX_sess_timeouts(const SSL_CTX *ctx) { return 0; }
2652e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint SSL_CTX_sess_cache_full(const SSL_CTX *ctx) { return 0; }
2653b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid ERR_load_SSL_strings(void) {}
2654b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Rootvoid SSL_load_error_strings(void) {}
2655