blob: a4fcad5115fcaed1095f7c8111b931d179f1002d [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57/* ====================================================================
58 * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
62 * are met:
63 *
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 *
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in
69 * the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3. All advertising materials mentioning features or use of this
73 * software must display the following acknowledgment:
74 * "This product includes software developed by the OpenSSL Project
75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76 *
77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78 * endorse or promote products derived from this software without
79 * prior written permission. For written permission, please contact
80 * openssl-core@openssl.org.
81 *
82 * 5. Products derived from this software may not be called "OpenSSL"
83 * nor may "OpenSSL" appear in their names without prior written
84 * permission of the OpenSSL Project.
85 *
86 * 6. Redistributions of any form whatsoever must retain the following
87 * acknowledgment:
88 * "This product includes software developed by the OpenSSL Project
89 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90 *
91 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
95 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102 * OF THE POSSIBILITY OF SUCH DAMAGE.
103 * ====================================================================
104 *
105 * This product includes cryptographic software written by Eric Young
106 * (eay@cryptsoft.com). This product includes software written by Tim
107 * Hudson (tjh@cryptsoft.com).
108 *
109 */
110/* ====================================================================
111 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
112 * ECC cipher suite support in OpenSSL originally developed by
113 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
114 */
115/* ====================================================================
116 * Copyright 2005 Nokia. All rights reserved.
117 *
118 * The portions of the attached software ("Contribution") is developed by
119 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
120 * license.
121 *
122 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
123 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
124 * support (see RFC 4279) to OpenSSL.
125 *
126 * No patent licenses or other rights except those expressly stated in
127 * the OpenSSL open source license shall be deemed granted or received
128 * expressly, by implication, estoppel, or otherwise.
129 *
130 * No assurances are provided by Nokia that the Contribution does not
131 * infringe the patent or other intellectual property rights of any third
132 * party or that the license provides you with all the necessary rights
133 * to make use of the Contribution.
134 *
135 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
136 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
137 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
138 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
139 * OTHERWISE. */
140
David Benjamin9e4e01e2015-09-15 01:48:04 -0400141#include <openssl/ssl.h>
142
Adam Langley95c29f32014-06-20 12:00:00 -0700143#include <assert.h>
David Benjaminf0ae1702015-04-07 23:05:04 -0400144#include <stdio.h>
145#include <string.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700146
David Benjamin39482a12014-07-20 13:30:15 -0400147#include <openssl/bytestring.h>
David Benjamin7c6d09b2015-09-05 11:00:19 -0400148#include <openssl/crypto.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700149#include <openssl/dh.h>
David Benjaminf0ae1702015-04-07 23:05:04 -0400150#include <openssl/err.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700151#include <openssl/lhash.h>
152#include <openssl/mem.h>
153#include <openssl/obj.h>
154#include <openssl/rand.h>
155#include <openssl/x509v3.h>
156
David Benjamin2ee94aa2015-04-07 22:38:30 -0400157#include "internal.h"
David Benjamin546f1a52015-04-15 16:46:09 -0400158#include "../crypto/internal.h"
159
Adam Langley95c29f32014-06-20 12:00:00 -0700160
David Benjamin76c2efc2015-08-31 14:24:29 -0400161/* |SSL_R_UNKNOWN_PROTOCOL| is no longer emitted, but continue to define it
David Benjamin97760d52015-07-24 23:02:49 -0400162 * to avoid downstream churn. */
David Benjamin76c2efc2015-08-31 14:24:29 -0400163OPENSSL_DECLARE_ERROR_REASON(SSL, UNKNOWN_PROTOCOL)
David Benjamin97760d52015-07-24 23:02:49 -0400164
Adam Langleyfcf25832014-12-18 17:42:32 -0800165/* Some error codes are special. Ensure the make_errors.go script never
166 * regresses this. */
167OPENSSL_COMPILE_ASSERT(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION ==
168 SSL_AD_NO_RENEGOTIATION + SSL_AD_REASON_OFFSET,
169 ssl_alert_reason_code_mismatch);
David Benjamine1136082014-09-20 12:28:58 -0400170
David Benjamin1d0a1942015-04-26 15:35:35 -0400171/* kMaxHandshakeSize is the maximum size, in bytes, of a handshake message. */
172static const size_t kMaxHandshakeSize = (1u << 24) - 1;
173
David Benjaminaa585132015-06-29 23:36:17 -0400174static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl =
175 CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
176static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl_ctx =
177 CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
David Benjamin9f33fc62015-04-15 17:29:53 -0400178
David Benjamin7c6d09b2015-09-05 11:00:19 -0400179int SSL_library_init(void) {
180 CRYPTO_library_init();
181 return 1;
182}
183
David Benjamin27bbae42015-09-13 00:54:37 -0400184static uint32_t ssl_session_hash(const SSL_SESSION *a) {
185 uint32_t hash =
Adam Langleyf4e554e2015-09-30 13:46:34 -0700186 ((uint32_t)a->session_id[0]) |
187 ((uint32_t)a->session_id[1] << 8) |
188 ((uint32_t)a->session_id[2] << 16) |
David Benjamin27bbae42015-09-13 00:54:37 -0400189 ((uint32_t)a->session_id[3] << 24);
David Benjamin7c6d09b2015-09-05 11:00:19 -0400190
David Benjamin27bbae42015-09-13 00:54:37 -0400191 return hash;
192}
193
194/* NB: If this function (or indeed the hash function which uses a sort of
195 * coarser function than this one) is changed, ensure
196 * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
197 * able to construct an SSL_SESSION that will collide with any existing session
198 * with a matching session ID. */
199static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) {
200 if (a->ssl_version != b->ssl_version) {
201 return 1;
Adam Langleyfcf25832014-12-18 17:42:32 -0800202 }
Adam Langley95c29f32014-06-20 12:00:00 -0700203
David Benjamin27bbae42015-09-13 00:54:37 -0400204 if (a->session_id_length != b->session_id_length) {
205 return 1;
Adam Langleyfcf25832014-12-18 17:42:32 -0800206 }
Adam Langley95c29f32014-06-20 12:00:00 -0700207
David Benjamin27bbae42015-09-13 00:54:37 -0400208 return memcmp(a->session_id, b->session_id, a->session_id_length);
209}
Adam Langley95c29f32014-06-20 12:00:00 -0700210
David Benjamin27bbae42015-09-13 00:54:37 -0400211SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
212 SSL_CTX *ret = NULL;
213
214 if (method == NULL) {
215 OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_METHOD_PASSED);
216 return NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -0800217 }
Adam Langley95c29f32014-06-20 12:00:00 -0700218
David Benjamin27bbae42015-09-13 00:54:37 -0400219 if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) {
220 OPENSSL_PUT_ERROR(SSL, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
221 goto err;
David Benjamin62fd1622015-01-11 13:30:01 -0500222 }
223
David Benjamin27bbae42015-09-13 00:54:37 -0400224 ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
225 if (ret == NULL) {
226 goto err;
David Benjamin62fd1622015-01-11 13:30:01 -0500227 }
228
David Benjamin27bbae42015-09-13 00:54:37 -0400229 memset(ret, 0, sizeof(SSL_CTX));
Adam Langley95c29f32014-06-20 12:00:00 -0700230
David Benjamin27bbae42015-09-13 00:54:37 -0400231 ret->method = method->method;
232
233 CRYPTO_MUTEX_init(&ret->lock);
234
235 ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
236 ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
237
238 /* We take the system default */
239 ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
240
241 ret->references = 1;
242
243 ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
244 ret->verify_mode = SSL_VERIFY_NONE;
245 ret->cert = ssl_cert_new();
246 if (ret->cert == NULL) {
247 goto err;
248 }
249
250 ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
251 if (ret->sessions == NULL) {
252 goto err;
253 }
254 ret->cert_store = X509_STORE_new();
255 if (ret->cert_store == NULL) {
256 goto err;
257 }
258
259 ssl_create_cipher_list(ret->method, &ret->cipher_list,
260 &ret->cipher_list_by_id, SSL_DEFAULT_CIPHER_LIST);
261 if (ret->cipher_list == NULL ||
262 sk_SSL_CIPHER_num(ret->cipher_list->ciphers) <= 0) {
263 OPENSSL_PUT_ERROR(SSL, SSL_R_LIBRARY_HAS_NO_CIPHERS);
264 goto err2;
265 }
266
267 ret->param = X509_VERIFY_PARAM_new();
268 if (!ret->param) {
269 goto err;
270 }
271
272 ret->client_CA = sk_X509_NAME_new_null();
273 if (ret->client_CA == NULL) {
274 goto err;
275 }
276
David Benjamin8a589332015-12-04 23:14:35 -0500277 CRYPTO_new_ex_data(&ret->ex_data);
David Benjamin27bbae42015-09-13 00:54:37 -0400278
279 ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
280
281 /* Setup RFC4507 ticket keys */
282 if (!RAND_bytes(ret->tlsext_tick_key_name, 16) ||
283 !RAND_bytes(ret->tlsext_tick_hmac_key, 16) ||
284 !RAND_bytes(ret->tlsext_tick_aes_key, 16)) {
285 ret->options |= SSL_OP_NO_TICKET;
286 }
287
David Benjamin27bbae42015-09-13 00:54:37 -0400288 /* Lock the SSL_CTX to the specified version, for compatibility with legacy
289 * uses of SSL_METHOD. */
290 if (method->version != 0) {
291 SSL_CTX_set_max_version(ret, method->version);
292 SSL_CTX_set_min_version(ret, method->version);
293 }
294
295 return ret;
296
297err:
298 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
299err2:
300 SSL_CTX_free(ret);
301 return NULL;
302}
303
304void SSL_CTX_free(SSL_CTX *ctx) {
305 if (ctx == NULL ||
306 !CRYPTO_refcount_dec_and_test_zero(&ctx->references)) {
307 return;
308 }
309
310 X509_VERIFY_PARAM_free(ctx->param);
311
312 /* Free internal session cache. However: the remove_cb() may reference the
313 * ex_data of SSL_CTX, thus the ex_data store can only be removed after the
314 * sessions were flushed. As the ex_data handling routines might also touch
315 * the session cache, the most secure solution seems to be: empty (flush) the
316 * cache, then free ex_data, then finally free the cache. (See ticket
317 * [openssl.org #212].) */
318 SSL_CTX_flush_sessions(ctx, 0);
319
320 CRYPTO_free_ex_data(&g_ex_data_class_ssl_ctx, ctx, &ctx->ex_data);
321
322 CRYPTO_MUTEX_cleanup(&ctx->lock);
323 lh_SSL_SESSION_free(ctx->sessions);
324 X509_STORE_free(ctx->cert_store);
325 ssl_cipher_preference_list_free(ctx->cipher_list);
326 sk_SSL_CIPHER_free(ctx->cipher_list_by_id);
327 ssl_cipher_preference_list_free(ctx->cipher_list_tls10);
328 ssl_cipher_preference_list_free(ctx->cipher_list_tls11);
329 ssl_cert_free(ctx->cert);
330 sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->client_custom_extensions,
331 SSL_CUSTOM_EXTENSION_free);
332 sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->server_custom_extensions,
333 SSL_CUSTOM_EXTENSION_free);
334 sk_X509_NAME_pop_free(ctx->client_CA, X509_NAME_free);
335 sk_SRTP_PROTECTION_PROFILE_free(ctx->srtp_profiles);
336 OPENSSL_free(ctx->psk_identity_hint);
337 OPENSSL_free(ctx->tlsext_ellipticcurvelist);
338 OPENSSL_free(ctx->alpn_client_proto_list);
339 OPENSSL_free(ctx->ocsp_response);
340 OPENSSL_free(ctx->signed_cert_timestamp_list);
341 EVP_PKEY_free(ctx->tlsext_channel_id_private);
David Benjamin27bbae42015-09-13 00:54:37 -0400342
343 OPENSSL_free(ctx);
Adam Langleyfcf25832014-12-18 17:42:32 -0800344}
Adam Langley95c29f32014-06-20 12:00:00 -0700345
Adam Langleyfcf25832014-12-18 17:42:32 -0800346SSL *SSL_new(SSL_CTX *ctx) {
347 SSL *s;
Adam Langley95c29f32014-06-20 12:00:00 -0700348
Adam Langleyfcf25832014-12-18 17:42:32 -0800349 if (ctx == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400350 OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_CTX);
Adam Langleyfcf25832014-12-18 17:42:32 -0800351 return NULL;
352 }
353 if (ctx->method == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400354 OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
Adam Langleyfcf25832014-12-18 17:42:32 -0800355 return NULL;
356 }
Adam Langley95c29f32014-06-20 12:00:00 -0700357
Adam Langleyfcf25832014-12-18 17:42:32 -0800358 s = (SSL *)OPENSSL_malloc(sizeof(SSL));
359 if (s == NULL) {
360 goto err;
361 }
362 memset(s, 0, sizeof(SSL));
Adam Langley95c29f32014-06-20 12:00:00 -0700363
Adam Langleyfcf25832014-12-18 17:42:32 -0800364 s->min_version = ctx->min_version;
365 s->max_version = ctx->max_version;
David Benjamin1eb367c2014-12-12 18:17:51 -0500366
Adam Langleyfcf25832014-12-18 17:42:32 -0800367 s->options = ctx->options;
368 s->mode = ctx->mode;
369 s->max_cert_list = ctx->max_cert_list;
Adam Langley95c29f32014-06-20 12:00:00 -0700370
David Benjamina5a3eeb2015-03-18 20:26:30 -0400371 s->cert = ssl_cert_dup(ctx->cert);
372 if (s->cert == NULL) {
373 goto err;
Adam Langleyfcf25832014-12-18 17:42:32 -0800374 }
Adam Langley95c29f32014-06-20 12:00:00 -0700375
Adam Langleyfcf25832014-12-18 17:42:32 -0800376 s->msg_callback = ctx->msg_callback;
377 s->msg_callback_arg = ctx->msg_callback_arg;
378 s->verify_mode = ctx->verify_mode;
379 s->sid_ctx_length = ctx->sid_ctx_length;
380 assert(s->sid_ctx_length <= sizeof s->sid_ctx);
381 memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx));
382 s->verify_callback = ctx->default_verify_callback;
Adam Langley95c29f32014-06-20 12:00:00 -0700383
Adam Langleyfcf25832014-12-18 17:42:32 -0800384 s->param = X509_VERIFY_PARAM_new();
385 if (!s->param) {
386 goto err;
387 }
388 X509_VERIFY_PARAM_inherit(s->param, ctx->param);
389 s->quiet_shutdown = ctx->quiet_shutdown;
390 s->max_send_fragment = ctx->max_send_fragment;
Adam Langley95c29f32014-06-20 12:00:00 -0700391
Adam Langley0b5e3902015-05-15 13:08:38 -0700392 CRYPTO_refcount_inc(&ctx->references);
Adam Langleyfcf25832014-12-18 17:42:32 -0800393 s->ctx = ctx;
Adam Langley0b5e3902015-05-15 13:08:38 -0700394 CRYPTO_refcount_inc(&ctx->references);
Adam Langleyfcf25832014-12-18 17:42:32 -0800395 s->initial_ctx = ctx;
Adam Langley95c29f32014-06-20 12:00:00 -0700396
Adam Langleyfcf25832014-12-18 17:42:32 -0800397 if (ctx->tlsext_ellipticcurvelist) {
398 s->tlsext_ellipticcurvelist =
399 BUF_memdup(ctx->tlsext_ellipticcurvelist,
400 ctx->tlsext_ellipticcurvelist_length * 2);
401 if (!s->tlsext_ellipticcurvelist) {
402 goto err;
403 }
404 s->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length;
405 }
Adam Langley95c29f32014-06-20 12:00:00 -0700406
Adam Langleyfcf25832014-12-18 17:42:32 -0800407 if (s->ctx->alpn_client_proto_list) {
408 s->alpn_client_proto_list = BUF_memdup(s->ctx->alpn_client_proto_list,
409 s->ctx->alpn_client_proto_list_len);
410 if (s->alpn_client_proto_list == NULL) {
411 goto err;
412 }
413 s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
414 }
Adam Langley95c29f32014-06-20 12:00:00 -0700415
Adam Langleyfcf25832014-12-18 17:42:32 -0800416 s->verify_result = X509_V_OK;
417 s->method = ctx->method;
Adam Langley95c29f32014-06-20 12:00:00 -0700418
Adam Langleyfcf25832014-12-18 17:42:32 -0800419 if (!s->method->ssl_new(s)) {
420 goto err;
421 }
422 s->enc_method = ssl3_get_enc_method(s->version);
423 assert(s->enc_method != NULL);
Adam Langley95c29f32014-06-20 12:00:00 -0700424
David Benjamin62fd1622015-01-11 13:30:01 -0500425 s->rwstate = SSL_NOTHING;
Adam Langley95c29f32014-06-20 12:00:00 -0700426
David Benjamin8a589332015-12-04 23:14:35 -0500427 CRYPTO_new_ex_data(&s->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700428
Adam Langleyfcf25832014-12-18 17:42:32 -0800429 s->psk_identity_hint = NULL;
430 if (ctx->psk_identity_hint) {
431 s->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint);
432 if (s->psk_identity_hint == NULL) {
433 goto err;
434 }
435 }
436 s->psk_client_callback = ctx->psk_client_callback;
437 s->psk_server_callback = ctx->psk_server_callback;
Adam Langley95c29f32014-06-20 12:00:00 -0700438
David Benjamin02ddbfd2015-01-11 13:09:11 -0500439 s->tlsext_channel_id_enabled = ctx->tlsext_channel_id_enabled;
440 if (ctx->tlsext_channel_id_private) {
David Benjamin9a10f8f2015-05-05 22:22:40 -0400441 s->tlsext_channel_id_private =
442 EVP_PKEY_up_ref(ctx->tlsext_channel_id_private);
David Benjamin02ddbfd2015-01-11 13:09:11 -0500443 }
444
Adam Langleyfcf25832014-12-18 17:42:32 -0800445 s->signed_cert_timestamps_enabled = s->ctx->signed_cert_timestamps_enabled;
446 s->ocsp_stapling_enabled = s->ctx->ocsp_stapling_enabled;
HÃ¥vard Molland9169c962014-08-14 14:42:37 +0200447
Adam Langleyfcf25832014-12-18 17:42:32 -0800448 return s;
449
Adam Langley95c29f32014-06-20 12:00:00 -0700450err:
David Benjamin2755a3e2015-04-22 16:17:58 -0400451 SSL_free(s);
David Benjamin3570d732015-06-29 00:28:17 -0400452 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700453
Adam Langleyfcf25832014-12-18 17:42:32 -0800454 return NULL;
455}
Adam Langley95c29f32014-06-20 12:00:00 -0700456
David Benjamin27bbae42015-09-13 00:54:37 -0400457void SSL_free(SSL *ssl) {
458 if (ssl == NULL) {
459 return;
460 }
461
462 X509_VERIFY_PARAM_free(ssl->param);
463
464 CRYPTO_free_ex_data(&g_ex_data_class_ssl, ssl, &ssl->ex_data);
465
466 if (ssl->bbio != NULL) {
467 /* If the buffering BIO is in place, pop it off */
468 if (ssl->bbio == ssl->wbio) {
469 ssl->wbio = BIO_pop(ssl->wbio);
470 }
471 BIO_free(ssl->bbio);
472 ssl->bbio = NULL;
473 }
474
475 int free_wbio = ssl->wbio != ssl->rbio;
476 BIO_free_all(ssl->rbio);
477 if (free_wbio) {
478 BIO_free_all(ssl->wbio);
479 }
480
481 BUF_MEM_free(ssl->init_buf);
482
483 /* add extra stuff */
484 ssl_cipher_preference_list_free(ssl->cipher_list);
485 sk_SSL_CIPHER_free(ssl->cipher_list_by_id);
486
487 ssl_clear_bad_session(ssl);
488 SSL_SESSION_free(ssl->session);
489
490 ssl_clear_cipher_ctx(ssl);
491
492 ssl_cert_free(ssl->cert);
493
494 OPENSSL_free(ssl->tlsext_hostname);
495 SSL_CTX_free(ssl->initial_ctx);
496 OPENSSL_free(ssl->tlsext_ellipticcurvelist);
497 OPENSSL_free(ssl->alpn_client_proto_list);
498 EVP_PKEY_free(ssl->tlsext_channel_id_private);
499 OPENSSL_free(ssl->psk_identity_hint);
500 sk_X509_NAME_pop_free(ssl->client_CA, X509_NAME_free);
501 OPENSSL_free(ssl->next_proto_negotiated);
502 sk_SRTP_PROTECTION_PROFILE_free(ssl->srtp_profiles);
503
504 if (ssl->method != NULL) {
505 ssl->method->ssl_free(ssl);
506 }
507 SSL_CTX_free(ssl->ctx);
508
509 OPENSSL_free(ssl);
510}
511
512void SSL_set_connect_state(SSL *ssl) {
513 ssl->server = 0;
514 ssl->shutdown = 0;
515 ssl->state = SSL_ST_CONNECT;
516 ssl->handshake_func = ssl->method->ssl_connect;
517 /* clear the current cipher */
518 ssl_clear_cipher_ctx(ssl);
519}
520
521void SSL_set_accept_state(SSL *ssl) {
522 ssl->server = 1;
523 ssl->shutdown = 0;
524 ssl->state = SSL_ST_ACCEPT;
525 ssl->handshake_func = ssl->method->ssl_accept;
526 /* clear the current cipher */
527 ssl_clear_cipher_ctx(ssl);
528}
529
530void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) {
531 /* If the output buffering BIO is still in place, remove it. */
532 if (ssl->bbio != NULL) {
533 if (ssl->wbio == ssl->bbio) {
534 ssl->wbio = ssl->wbio->next_bio;
535 ssl->bbio->next_bio = NULL;
536 }
537 }
538
539 if (ssl->rbio != rbio) {
540 BIO_free_all(ssl->rbio);
541 }
542 if (ssl->wbio != wbio && ssl->rbio != ssl->wbio) {
543 BIO_free_all(ssl->wbio);
544 }
545 ssl->rbio = rbio;
546 ssl->wbio = wbio;
547}
548
549BIO *SSL_get_rbio(const SSL *ssl) { return ssl->rbio; }
550
551BIO *SSL_get_wbio(const SSL *ssl) { return ssl->wbio; }
552
553int SSL_do_handshake(SSL *ssl) {
554 if (ssl->handshake_func == NULL) {
555 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_TYPE_NOT_SET);
556 return -1;
557 }
558
559 if (!SSL_in_init(ssl)) {
560 return 1;
561 }
562
563 return ssl->handshake_func(ssl);
564}
565
566int SSL_connect(SSL *ssl) {
567 if (ssl->handshake_func == 0) {
568 /* Not properly initialized yet */
569 SSL_set_connect_state(ssl);
570 }
571
572 if (ssl->handshake_func != ssl->method->ssl_connect) {
573 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
574 return -1;
575 }
576
577 return ssl->handshake_func(ssl);
578}
579
580int SSL_accept(SSL *ssl) {
581 if (ssl->handshake_func == 0) {
582 /* Not properly initialized yet */
583 SSL_set_accept_state(ssl);
584 }
585
586 if (ssl->handshake_func != ssl->method->ssl_accept) {
587 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
588 return -1;
589 }
590
591 return ssl->handshake_func(ssl);
592}
593
594int SSL_read(SSL *ssl, void *buf, int num) {
595 if (ssl->handshake_func == 0) {
596 OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
597 return -1;
598 }
599
600 if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
601 ssl->rwstate = SSL_NOTHING;
602 return 0;
603 }
604
605 ERR_clear_system_error();
606 return ssl->method->ssl_read_app_data(ssl, buf, num, 0);
607}
608
609int SSL_peek(SSL *ssl, void *buf, int num) {
610 if (ssl->handshake_func == 0) {
611 OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
612 return -1;
613 }
614
615 if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
616 return 0;
617 }
618
619 ERR_clear_system_error();
620 return ssl->method->ssl_read_app_data(ssl, buf, num, 1);
621}
622
623int SSL_write(SSL *ssl, const void *buf, int num) {
624 if (ssl->handshake_func == 0) {
625 OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
626 return -1;
627 }
628
629 if (ssl->shutdown & SSL_SENT_SHUTDOWN) {
630 ssl->rwstate = SSL_NOTHING;
631 OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
632 return -1;
633 }
634
635 ERR_clear_system_error();
636 return ssl->method->ssl_write_app_data(ssl, buf, num);
637}
638
639int SSL_shutdown(SSL *ssl) {
640 /* Note that this function behaves differently from what one might expect.
641 * Return values are 0 for no success (yet), 1 for success; but calling it
642 * once is usually not enough, even if blocking I/O is used (see
643 * ssl3_shutdown). */
644
645 if (ssl->handshake_func == 0) {
646 OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
647 return -1;
648 }
649
650 if (SSL_in_init(ssl)) {
651 return 1;
652 }
653
654 /* Do nothing if configured not to send a close_notify. */
655 if (ssl->quiet_shutdown) {
656 ssl->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
657 return 1;
658 }
659
660 if (!(ssl->shutdown & SSL_SENT_SHUTDOWN)) {
661 ssl->shutdown |= SSL_SENT_SHUTDOWN;
662 ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
663
664 /* our shutdown alert has been sent now, and if it still needs to be
665 * written, ssl->s3->alert_dispatch will be true */
666 if (ssl->s3->alert_dispatch) {
667 return -1; /* return WANT_WRITE */
668 }
669 } else if (ssl->s3->alert_dispatch) {
670 /* resend it if not sent */
671 int ret = ssl->method->ssl_dispatch_alert(ssl);
672 if (ret == -1) {
673 /* we only get to return -1 here the 2nd/Nth invocation, we must have
674 * already signalled return 0 upon a previous invoation, return
675 * WANT_WRITE */
676 return ret;
677 }
678 } else if (!(ssl->shutdown & SSL_RECEIVED_SHUTDOWN)) {
679 /* If we are waiting for a close from our peer, we are closed */
680 ssl->method->ssl_read_close_notify(ssl);
681 if (!(ssl->shutdown & SSL_RECEIVED_SHUTDOWN)) {
682 return -1; /* return WANT_READ */
683 }
684 }
685
686 if (ssl->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN) &&
687 !ssl->s3->alert_dispatch) {
688 return 1;
689 } else {
690 return 0;
691 }
692}
693
694int SSL_get_error(const SSL *ssl, int ret_code) {
695 int reason;
696 uint32_t err;
697 BIO *bio;
698
699 if (ret_code > 0) {
700 return SSL_ERROR_NONE;
701 }
702
703 /* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
704 * where we do encode the error */
705 err = ERR_peek_error();
706 if (err != 0) {
707 if (ERR_GET_LIB(err) == ERR_LIB_SYS) {
708 return SSL_ERROR_SYSCALL;
709 }
710 return SSL_ERROR_SSL;
711 }
712
713 if (ret_code == 0) {
714 if ((ssl->shutdown & SSL_RECEIVED_SHUTDOWN) &&
715 (ssl->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) {
716 /* The socket was cleanly shut down with a close_notify. */
717 return SSL_ERROR_ZERO_RETURN;
718 }
719 /* An EOF was observed which violates the protocol, and the underlying
720 * transport does not participate in the error queue. Bubble up to the
721 * caller. */
722 return SSL_ERROR_SYSCALL;
723 }
724
725 if (SSL_want_session(ssl)) {
726 return SSL_ERROR_PENDING_SESSION;
727 }
728
729 if (SSL_want_certificate(ssl)) {
730 return SSL_ERROR_PENDING_CERTIFICATE;
731 }
732
733 if (SSL_want_read(ssl)) {
734 bio = SSL_get_rbio(ssl);
735 if (BIO_should_read(bio)) {
736 return SSL_ERROR_WANT_READ;
737 }
738
739 if (BIO_should_write(bio)) {
740 /* This one doesn't make too much sense ... We never try to write to the
741 * rbio, and an application program where rbio and wbio are separate
742 * couldn't even know what it should wait for. However if we ever set
743 * s->rwstate incorrectly (so that we have SSL_want_read(s) instead of
744 * SSL_want_write(s)) and rbio and wbio *are* the same, this test works
745 * around that bug; so it might be safer to keep it. */
746 return SSL_ERROR_WANT_WRITE;
747 }
748
749 if (BIO_should_io_special(bio)) {
750 reason = BIO_get_retry_reason(bio);
751 if (reason == BIO_RR_CONNECT) {
752 return SSL_ERROR_WANT_CONNECT;
753 }
754
755 if (reason == BIO_RR_ACCEPT) {
756 return SSL_ERROR_WANT_ACCEPT;
757 }
758
759 return SSL_ERROR_SYSCALL; /* unknown */
760 }
761 }
762
763 if (SSL_want_write(ssl)) {
764 bio = SSL_get_wbio(ssl);
765 if (BIO_should_write(bio)) {
766 return SSL_ERROR_WANT_WRITE;
767 }
768
769 if (BIO_should_read(bio)) {
770 /* See above (SSL_want_read(ssl) with BIO_should_write(bio)) */
771 return SSL_ERROR_WANT_READ;
772 }
773
774 if (BIO_should_io_special(bio)) {
775 reason = BIO_get_retry_reason(bio);
776 if (reason == BIO_RR_CONNECT) {
777 return SSL_ERROR_WANT_CONNECT;
778 }
779
780 if (reason == BIO_RR_ACCEPT) {
781 return SSL_ERROR_WANT_ACCEPT;
782 }
783
784 return SSL_ERROR_SYSCALL;
785 }
786 }
787
788 if (SSL_want_x509_lookup(ssl)) {
789 return SSL_ERROR_WANT_X509_LOOKUP;
790 }
791
792 if (SSL_want_channel_id_lookup(ssl)) {
793 return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP;
794 }
795
796 if (SSL_want_private_key_operation(ssl)) {
797 return SSL_ERROR_WANT_PRIVATE_KEY_OPERATION;
798 }
799
800 return SSL_ERROR_SYSCALL;
801}
802
803void SSL_CTX_set_min_version(SSL_CTX *ctx, uint16_t version) {
804 ctx->min_version = version;
805}
806
807void SSL_CTX_set_max_version(SSL_CTX *ctx, uint16_t version) {
808 ctx->max_version = version;
809}
810
811void SSL_set_min_version(SSL *ssl, uint16_t version) {
812 ssl->min_version = version;
813}
814
815void SSL_set_max_version(SSL *ssl, uint16_t version) {
816 ssl->max_version = version;
817}
818
819uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options) {
820 ctx->options |= options;
821 return ctx->options;
822}
823
824uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options) {
825 ctx->options &= ~options;
826 return ctx->options;
827}
828
829uint32_t SSL_CTX_get_options(const SSL_CTX *ctx) { return ctx->options; }
830
831uint32_t SSL_set_options(SSL *ssl, uint32_t options) {
832 ssl->options |= options;
833 return ssl->options;
834}
835
836uint32_t SSL_clear_options(SSL *ssl, uint32_t options) {
837 ssl->options &= ~options;
838 return ssl->options;
839}
840
841uint32_t SSL_get_options(const SSL *ssl) { return ssl->options; }
842
843uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode) {
844 ctx->mode |= mode;
845 return ctx->mode;
846}
847
848uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode) {
849 ctx->mode &= ~mode;
850 return ctx->mode;
851}
852
853uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx) { return ctx->mode; }
854
855uint32_t SSL_set_mode(SSL *ssl, uint32_t mode) {
856 ssl->mode |= mode;
857 return ssl->mode;
858}
859
860uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode) {
861 ssl->mode &= ~mode;
862 return ssl->mode;
863}
864
865uint32_t SSL_get_mode(const SSL *ssl) { return ssl->mode; }
866
David Benjaminee0c8272015-09-13 01:03:54 -0400867X509 *SSL_get_peer_certificate(const SSL *ssl) {
868 if (ssl == NULL || ssl->session == NULL || ssl->session->peer == NULL) {
869 return NULL;
870 }
871 return X509_up_ref(ssl->session->peer);
872}
873
874STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) {
875 if (ssl == NULL || ssl->session == NULL) {
876 return NULL;
877 }
878 return ssl->session->cert_chain;
879}
880
881int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len,
882 size_t max_out) {
883 /* The tls-unique value is the first Finished message in the handshake, which
884 * is the client's in a full handshake and the server's for a resumption. See
885 * https://tools.ietf.org/html/rfc5929#section-3.1. */
886 const uint8_t *finished = ssl->s3->previous_client_finished;
887 size_t finished_len = ssl->s3->previous_client_finished_len;
888 if (ssl->hit) {
889 /* tls-unique is broken for resumed sessions unless EMS is used. */
890 if (!ssl->session->extended_master_secret) {
891 goto err;
892 }
893 finished = ssl->s3->previous_server_finished;
894 finished_len = ssl->s3->previous_server_finished_len;
895 }
896
897 if (!ssl->s3->initial_handshake_complete ||
898 ssl->version < TLS1_VERSION) {
899 goto err;
900 }
901
902 *out_len = finished_len;
903 if (finished_len > max_out) {
904 *out_len = max_out;
905 }
906
907 memcpy(out, finished, *out_len);
908 return 1;
909
910err:
911 *out_len = 0;
912 memset(out, 0, max_out);
913 return 0;
914}
915
Adam Langleyfcf25832014-12-18 17:42:32 -0800916int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx,
David Benjamindafbdd42015-09-14 01:40:10 -0400917 unsigned sid_ctx_len) {
918 if (sid_ctx_len > sizeof(ctx->sid_ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400919 OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
Adam Langleyfcf25832014-12-18 17:42:32 -0800920 return 0;
921 }
922 ctx->sid_ctx_length = sid_ctx_len;
923 memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len);
Adam Langley95c29f32014-06-20 12:00:00 -0700924
Adam Langleyfcf25832014-12-18 17:42:32 -0800925 return 1;
926}
Adam Langley95c29f32014-06-20 12:00:00 -0700927
Adam Langleyfcf25832014-12-18 17:42:32 -0800928int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
David Benjamindafbdd42015-09-14 01:40:10 -0400929 unsigned sid_ctx_len) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800930 if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
David Benjamin3570d732015-06-29 00:28:17 -0400931 OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
Adam Langleyfcf25832014-12-18 17:42:32 -0800932 return 0;
933 }
934 ssl->sid_ctx_length = sid_ctx_len;
935 memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len);
Adam Langley95c29f32014-06-20 12:00:00 -0700936
Adam Langleyfcf25832014-12-18 17:42:32 -0800937 return 1;
938}
Adam Langley95c29f32014-06-20 12:00:00 -0700939
David Benjamin59937042015-09-19 13:04:22 -0400940int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) {
941 return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
Adam Langleyfcf25832014-12-18 17:42:32 -0800942}
943
David Benjamin59937042015-09-19 13:04:22 -0400944int SSL_set_purpose(SSL *ssl, int purpose) {
945 return X509_VERIFY_PARAM_set_purpose(ssl->param, purpose);
Adam Langleyfcf25832014-12-18 17:42:32 -0800946}
947
David Benjamin59937042015-09-19 13:04:22 -0400948int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) {
949 return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
Adam Langleyfcf25832014-12-18 17:42:32 -0800950}
951
David Benjamin59937042015-09-19 13:04:22 -0400952int SSL_set_trust(SSL *ssl, int trust) {
953 return X509_VERIFY_PARAM_set_trust(ssl->param, trust);
Adam Langleyfcf25832014-12-18 17:42:32 -0800954}
955
David Benjamin59937042015-09-19 13:04:22 -0400956int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) {
957 return X509_VERIFY_PARAM_set1(ctx->param, param);
Adam Langleyfcf25832014-12-18 17:42:32 -0800958}
959
David Benjamin59937042015-09-19 13:04:22 -0400960int SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) {
961 return X509_VERIFY_PARAM_set1(ssl->param, param);
Adam Langleyfcf25832014-12-18 17:42:32 -0800962}
Adam Langley95c29f32014-06-20 12:00:00 -0700963
Adam Langley858a88d2014-06-20 12:00:00 -0700964void ssl_cipher_preference_list_free(
Adam Langleyfcf25832014-12-18 17:42:32 -0800965 struct ssl_cipher_preference_list_st *cipher_list) {
David Benjamin5d1ec732015-04-22 13:38:00 -0400966 if (cipher_list == NULL) {
967 return;
968 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800969 sk_SSL_CIPHER_free(cipher_list->ciphers);
970 OPENSSL_free(cipher_list->in_group_flags);
971 OPENSSL_free(cipher_list);
972}
Adam Langley858a88d2014-06-20 12:00:00 -0700973
Adam Langleyfcf25832014-12-18 17:42:32 -0800974X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { return ctx->param; }
Adam Langley95c29f32014-06-20 12:00:00 -0700975
Adam Langleyfcf25832014-12-18 17:42:32 -0800976X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { return ssl->param; }
Adam Langley95c29f32014-06-20 12:00:00 -0700977
David Benjamin7481d392015-07-05 19:38:46 -0400978void SSL_certs_clear(SSL *ssl) { ssl_cert_clear_certs(ssl->cert); }
Adam Langley95c29f32014-06-20 12:00:00 -0700979
David Benjamin066fe0a2015-10-17 21:11:33 -0400980int SSL_get_fd(const SSL *ssl) { return SSL_get_rfd(ssl); }
Adam Langley95c29f32014-06-20 12:00:00 -0700981
David Benjamin066fe0a2015-10-17 21:11:33 -0400982int SSL_get_rfd(const SSL *ssl) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800983 int ret = -1;
David Benjamin066fe0a2015-10-17 21:11:33 -0400984 BIO *b = BIO_find_type(SSL_get_rbio(ssl), BIO_TYPE_DESCRIPTOR);
985 if (b != NULL) {
986 BIO_get_fd(b, &ret);
Adam Langleyfcf25832014-12-18 17:42:32 -0800987 }
988 return ret;
989}
Adam Langley95c29f32014-06-20 12:00:00 -0700990
David Benjamin066fe0a2015-10-17 21:11:33 -0400991int SSL_get_wfd(const SSL *ssl) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800992 int ret = -1;
David Benjamin066fe0a2015-10-17 21:11:33 -0400993 BIO *b = BIO_find_type(SSL_get_wbio(ssl), BIO_TYPE_DESCRIPTOR);
994 if (b != NULL) {
995 BIO_get_fd(b, &ret);
Adam Langleyfcf25832014-12-18 17:42:32 -0800996 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800997 return ret;
998}
Adam Langley95c29f32014-06-20 12:00:00 -0700999
David Benjamin066fe0a2015-10-17 21:11:33 -04001000int SSL_set_fd(SSL *ssl, int fd) {
1001 BIO *bio = BIO_new(BIO_s_fd());
Adam Langleyfcf25832014-12-18 17:42:32 -08001002 if (bio == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001003 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
David Benjamin066fe0a2015-10-17 21:11:33 -04001004 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001005 }
1006 BIO_set_fd(bio, fd, BIO_NOCLOSE);
David Benjamin066fe0a2015-10-17 21:11:33 -04001007 SSL_set_bio(ssl, bio, bio);
1008 return 1;
Adam Langleyfcf25832014-12-18 17:42:32 -08001009}
Adam Langley95c29f32014-06-20 12:00:00 -07001010
David Benjamin066fe0a2015-10-17 21:11:33 -04001011int SSL_set_wfd(SSL *ssl, int fd) {
1012 if (ssl->rbio == NULL ||
1013 BIO_method_type(ssl->rbio) != BIO_TYPE_FD ||
1014 BIO_get_fd(ssl->rbio, NULL) != fd) {
1015 BIO *bio = BIO_new(BIO_s_fd());
Adam Langleyfcf25832014-12-18 17:42:32 -08001016 if (bio == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001017 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
David Benjamin066fe0a2015-10-17 21:11:33 -04001018 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001019 }
1020 BIO_set_fd(bio, fd, BIO_NOCLOSE);
David Benjamin066fe0a2015-10-17 21:11:33 -04001021 SSL_set_bio(ssl, SSL_get_rbio(ssl), bio);
Adam Langleyfcf25832014-12-18 17:42:32 -08001022 } else {
David Benjamin066fe0a2015-10-17 21:11:33 -04001023 SSL_set_bio(ssl, SSL_get_rbio(ssl), SSL_get_rbio(ssl));
Adam Langleyfcf25832014-12-18 17:42:32 -08001024 }
1025
David Benjamin066fe0a2015-10-17 21:11:33 -04001026 return 1;
Adam Langleyfcf25832014-12-18 17:42:32 -08001027}
Adam Langley95c29f32014-06-20 12:00:00 -07001028
David Benjamin066fe0a2015-10-17 21:11:33 -04001029int SSL_set_rfd(SSL *ssl, int fd) {
1030 if (ssl->wbio == NULL || BIO_method_type(ssl->wbio) != BIO_TYPE_FD ||
1031 BIO_get_fd(ssl->wbio, NULL) != fd) {
1032 BIO *bio = BIO_new(BIO_s_fd());
Adam Langleyfcf25832014-12-18 17:42:32 -08001033 if (bio == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001034 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
David Benjamin066fe0a2015-10-17 21:11:33 -04001035 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001036 }
1037 BIO_set_fd(bio, fd, BIO_NOCLOSE);
David Benjamin066fe0a2015-10-17 21:11:33 -04001038 SSL_set_bio(ssl, bio, SSL_get_wbio(ssl));
Adam Langleyfcf25832014-12-18 17:42:32 -08001039 } else {
David Benjamin066fe0a2015-10-17 21:11:33 -04001040 SSL_set_bio(ssl, SSL_get_wbio(ssl), SSL_get_wbio(ssl));
Adam Langleyfcf25832014-12-18 17:42:32 -08001041 }
David Benjamin066fe0a2015-10-17 21:11:33 -04001042 return 1;
Adam Langleyfcf25832014-12-18 17:42:32 -08001043}
Adam Langley95c29f32014-06-20 12:00:00 -07001044
David Benjamin1a1b34d2015-10-17 12:51:52 -04001045size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001046 size_t ret = 0;
1047
David Benjamin1a1b34d2015-10-17 12:51:52 -04001048 if (ssl->s3 != NULL) {
1049 ret = ssl->s3->tmp.finish_md_len;
Adam Langleyfcf25832014-12-18 17:42:32 -08001050 if (count > ret) {
1051 count = ret;
1052 }
David Benjamin1a1b34d2015-10-17 12:51:52 -04001053 memcpy(buf, ssl->s3->tmp.finish_md, count);
Adam Langleyfcf25832014-12-18 17:42:32 -08001054 }
1055
1056 return ret;
1057}
Adam Langley95c29f32014-06-20 12:00:00 -07001058
David Benjamin1a1b34d2015-10-17 12:51:52 -04001059size_t SSL_get_peer_finished(const SSL *ssl, void *buf, size_t count) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001060 size_t ret = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001061
David Benjamin1a1b34d2015-10-17 12:51:52 -04001062 if (ssl->s3 != NULL) {
1063 ret = ssl->s3->tmp.peer_finish_md_len;
Adam Langleyfcf25832014-12-18 17:42:32 -08001064 if (count > ret) {
1065 count = ret;
1066 }
David Benjamin1a1b34d2015-10-17 12:51:52 -04001067 memcpy(buf, ssl->s3->tmp.peer_finish_md, count);
Adam Langleyfcf25832014-12-18 17:42:32 -08001068 }
Adam Langley95c29f32014-06-20 12:00:00 -07001069
Adam Langleyfcf25832014-12-18 17:42:32 -08001070 return ret;
1071}
Adam Langley95c29f32014-06-20 12:00:00 -07001072
David Benjamin59937042015-09-19 13:04:22 -04001073int SSL_get_verify_mode(const SSL *ssl) { return ssl->verify_mode; }
Adam Langley95c29f32014-06-20 12:00:00 -07001074
David Benjamin59937042015-09-19 13:04:22 -04001075int SSL_get_verify_depth(const SSL *ssl) {
1076 return X509_VERIFY_PARAM_get_depth(ssl->param);
Adam Langleyfcf25832014-12-18 17:42:32 -08001077}
Adam Langley95c29f32014-06-20 12:00:00 -07001078
David Benjamin42fea372015-09-19 01:22:44 -04001079int SSL_get_extms_support(const SSL *ssl) {
1080 return ssl->s3->tmp.extended_master_secret == 1;
Matt Braithwaitecd6f54b2015-09-17 12:54:42 -07001081}
1082
David Benjamin59937042015-09-19 13:04:22 -04001083int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) {
1084 return ssl->verify_callback;
Adam Langleyfcf25832014-12-18 17:42:32 -08001085}
Adam Langley95c29f32014-06-20 12:00:00 -07001086
Adam Langleyfcf25832014-12-18 17:42:32 -08001087int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { return ctx->verify_mode; }
Adam Langley95c29f32014-06-20 12:00:00 -07001088
Adam Langleyfcf25832014-12-18 17:42:32 -08001089int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) {
1090 return X509_VERIFY_PARAM_get_depth(ctx->param);
1091}
Adam Langley95c29f32014-06-20 12:00:00 -07001092
David Benjamin59937042015-09-19 13:04:22 -04001093int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
1094 int ok, X509_STORE_CTX *store_ctx) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001095 return ctx->default_verify_callback;
1096}
Adam Langley95c29f32014-06-20 12:00:00 -07001097
David Benjamin59937042015-09-19 13:04:22 -04001098void SSL_set_verify(SSL *ssl, int mode,
1099 int (*callback)(int ok, X509_STORE_CTX *store_ctx)) {
1100 ssl->verify_mode = mode;
Adam Langleyfcf25832014-12-18 17:42:32 -08001101 if (callback != NULL) {
David Benjamin59937042015-09-19 13:04:22 -04001102 ssl->verify_callback = callback;
Adam Langleyfcf25832014-12-18 17:42:32 -08001103 }
1104}
Adam Langley95c29f32014-06-20 12:00:00 -07001105
David Benjamin59937042015-09-19 13:04:22 -04001106void SSL_set_verify_depth(SSL *ssl, int depth) {
1107 X509_VERIFY_PARAM_set_depth(ssl->param, depth);
Adam Langleyfcf25832014-12-18 17:42:32 -08001108}
Adam Langley95c29f32014-06-20 12:00:00 -07001109
David Benjamin9a41d1b2015-05-16 01:30:09 -04001110int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; }
Adam Langley95c29f32014-06-20 12:00:00 -07001111
David Benjamin9a41d1b2015-05-16 01:30:09 -04001112int SSL_get_read_ahead(const SSL *s) { return 0; }
Adam Langley95c29f32014-06-20 12:00:00 -07001113
David Benjamin9a41d1b2015-05-16 01:30:09 -04001114void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { }
David Benjamin61ecccf2015-05-05 09:44:51 -04001115
David Benjamin9a41d1b2015-05-16 01:30:09 -04001116void SSL_set_read_ahead(SSL *s, int yes) { }
David Benjamin61ecccf2015-05-05 09:44:51 -04001117
David Benjamin9f859492015-10-03 10:44:30 -04001118int SSL_pending(const SSL *ssl) {
1119 if (ssl->s3->rrec.type != SSL3_RT_APPLICATION_DATA) {
1120 return 0;
1121 }
1122 return ssl->s3->rrec.length;
Adam Langleyfcf25832014-12-18 17:42:32 -08001123}
Adam Langley95c29f32014-06-20 12:00:00 -07001124
Adam Langley95c29f32014-06-20 12:00:00 -07001125/* Fix this so it checks all the valid key/cert options */
Adam Langleyfcf25832014-12-18 17:42:32 -08001126int SSL_CTX_check_private_key(const SSL_CTX *ctx) {
David Benjamin651b3d92015-08-09 12:07:25 -04001127 if (ctx->cert->x509 == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001128 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
Adam Langleyfcf25832014-12-18 17:42:32 -08001129 return 0;
1130 }
1131
David Benjamind1d80782015-07-05 11:54:09 -04001132 if (ctx->cert->privatekey == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001133 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
Adam Langleyfcf25832014-12-18 17:42:32 -08001134 return 0;
1135 }
1136
David Benjamind1d80782015-07-05 11:54:09 -04001137 return X509_check_private_key(ctx->cert->x509, ctx->cert->privatekey);
Adam Langleyfcf25832014-12-18 17:42:32 -08001138}
Adam Langley95c29f32014-06-20 12:00:00 -07001139
1140/* Fix this function so that it takes an optional type parameter */
Adam Langleyfcf25832014-12-18 17:42:32 -08001141int SSL_check_private_key(const SSL *ssl) {
David Benjamind1d80782015-07-05 11:54:09 -04001142 if (ssl->cert->x509 == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001143 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
Adam Langleyfcf25832014-12-18 17:42:32 -08001144 return 0;
1145 }
David Benjamin0b145c22014-11-26 20:10:09 -05001146
David Benjamind1d80782015-07-05 11:54:09 -04001147 if (ssl->cert->privatekey == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001148 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
Adam Langleyfcf25832014-12-18 17:42:32 -08001149 return 0;
1150 }
Adam Langley95c29f32014-06-20 12:00:00 -07001151
David Benjamind1d80782015-07-05 11:54:09 -04001152 return X509_check_private_key(ssl->cert->x509, ssl->cert->privatekey);
Adam Langleyfcf25832014-12-18 17:42:32 -08001153}
Adam Langley95c29f32014-06-20 12:00:00 -07001154
David Benjamin42fea372015-09-19 01:22:44 -04001155long SSL_get_default_timeout(const SSL *ssl) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001156 return SSL_DEFAULT_SESSION_TIMEOUT;
1157}
Adam Langley95c29f32014-06-20 12:00:00 -07001158
David Benjamin44d3eed2015-05-21 01:29:55 -04001159int SSL_renegotiate(SSL *ssl) {
1160 /* Caller-initiated renegotiation is not supported. */
David Benjamin3570d732015-06-29 00:28:17 -04001161 OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
David Benjamin44d3eed2015-05-21 01:29:55 -04001162 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001163}
Adam Langley95c29f32014-06-20 12:00:00 -07001164
David Benjamin44d3eed2015-05-21 01:29:55 -04001165int SSL_renegotiate_pending(SSL *ssl) {
1166 return SSL_in_init(ssl) && ssl->s3->initial_handshake_complete;
Adam Langleyfcf25832014-12-18 17:42:32 -08001167}
Adam Langley95c29f32014-06-20 12:00:00 -07001168
David Benjamin1d0a1942015-04-26 15:35:35 -04001169size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx) {
1170 return ctx->max_cert_list;
1171}
1172
1173void SSL_CTX_set_max_cert_list(SSL_CTX *ctx, size_t max_cert_list) {
1174 if (max_cert_list > kMaxHandshakeSize) {
1175 max_cert_list = kMaxHandshakeSize;
1176 }
1177 ctx->max_cert_list = (uint32_t)max_cert_list;
1178}
1179
1180size_t SSL_get_max_cert_list(const SSL *ssl) {
1181 return ssl->max_cert_list;
1182}
1183
1184void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list) {
1185 if (max_cert_list > kMaxHandshakeSize) {
1186 max_cert_list = kMaxHandshakeSize;
1187 }
1188 ssl->max_cert_list = (uint32_t)max_cert_list;
1189}
1190
1191void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, size_t max_send_fragment) {
1192 if (max_send_fragment < 512) {
1193 max_send_fragment = 512;
1194 }
1195 if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
1196 max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
1197 }
1198 ctx->max_send_fragment = (uint16_t)max_send_fragment;
1199}
1200
1201void SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment) {
1202 if (max_send_fragment < 512) {
1203 max_send_fragment = 512;
1204 }
1205 if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
1206 max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
1207 }
1208 ssl->max_send_fragment = (uint16_t)max_send_fragment;
1209}
1210
David Benjamincb9cf792015-05-05 09:46:14 -04001211int SSL_set_mtu(SSL *ssl, unsigned mtu) {
1212 if (!SSL_IS_DTLS(ssl) || mtu < dtls1_min_mtu()) {
1213 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001214 }
David Benjamincb9cf792015-05-05 09:46:14 -04001215 ssl->d1->mtu = mtu;
1216 return 1;
1217}
1218
1219int SSL_get_secure_renegotiation_support(const SSL *ssl) {
1220 return ssl->s3->send_connection_binding;
1221}
1222
Adam Langleyfcf25832014-12-18 17:42:32 -08001223LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) { return ctx->sessions; }
1224
David Benjamin71f7d3d2015-05-05 09:46:38 -04001225size_t SSL_CTX_sess_number(const SSL_CTX *ctx) {
1226 return lh_SSL_SESSION_num_items(ctx->sessions);
1227}
1228
1229unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx, unsigned long size) {
1230 unsigned long ret = ctx->session_cache_size;
1231 ctx->session_cache_size = size;
1232 return ret;
1233}
1234
1235unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx) {
1236 return ctx->session_cache_size;
1237}
1238
1239int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode) {
1240 int ret = ctx->session_cache_mode;
1241 ctx->session_cache_mode = mode;
1242 return ret;
1243}
1244
1245int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx) {
1246 return ctx->session_cache_mode;
1247}
1248
David Benjamin32876b32015-09-20 12:17:03 -04001249STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl) {
1250 if (ssl == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001251 return NULL;
1252 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001253
David Benjamin32876b32015-09-20 12:17:03 -04001254 if (ssl->cipher_list != NULL) {
1255 return ssl->cipher_list->ciphers;
Adam Langleyfcf25832014-12-18 17:42:32 -08001256 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001257
David Benjamin32876b32015-09-20 12:17:03 -04001258 if (ssl->version >= TLS1_1_VERSION && ssl->ctx != NULL &&
1259 ssl->ctx->cipher_list_tls11 != NULL) {
1260 return ssl->ctx->cipher_list_tls11->ciphers;
Adam Langleyfcf25832014-12-18 17:42:32 -08001261 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001262
David Benjamin32876b32015-09-20 12:17:03 -04001263 if (ssl->version >= TLS1_VERSION && ssl->ctx != NULL &&
1264 ssl->ctx->cipher_list_tls10 != NULL) {
1265 return ssl->ctx->cipher_list_tls10->ciphers;
Adam Langleycef75832015-09-03 14:51:12 -07001266 }
1267
David Benjamin32876b32015-09-20 12:17:03 -04001268 if (ssl->ctx != NULL && ssl->ctx->cipher_list != NULL) {
1269 return ssl->ctx->cipher_list->ciphers;
Adam Langleyfcf25832014-12-18 17:42:32 -08001270 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001271
Adam Langleyfcf25832014-12-18 17:42:32 -08001272 return NULL;
1273}
Adam Langley95c29f32014-06-20 12:00:00 -07001274
Adam Langleyfcf25832014-12-18 17:42:32 -08001275/* return a STACK of the ciphers available for the SSL and in order of
Adam Langley95c29f32014-06-20 12:00:00 -07001276 * algorithm id */
David Benjamin60da0cd2015-05-03 15:21:28 -04001277STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001278 if (s == NULL) {
1279 return NULL;
1280 }
Adam Langley95c29f32014-06-20 12:00:00 -07001281
Adam Langleyfcf25832014-12-18 17:42:32 -08001282 if (s->cipher_list_by_id != NULL) {
1283 return s->cipher_list_by_id;
1284 }
Adam Langley95c29f32014-06-20 12:00:00 -07001285
Adam Langleyfcf25832014-12-18 17:42:32 -08001286 if (s->ctx != NULL && s->ctx->cipher_list_by_id != NULL) {
1287 return s->ctx->cipher_list_by_id;
1288 }
Adam Langley95c29f32014-06-20 12:00:00 -07001289
Adam Langleyfcf25832014-12-18 17:42:32 -08001290 return NULL;
1291}
Adam Langley95c29f32014-06-20 12:00:00 -07001292
David Benjamin32876b32015-09-20 12:17:03 -04001293const char *SSL_get_cipher_list(const SSL *ssl, int n) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001294 const SSL_CIPHER *c;
David Benjamin60da0cd2015-05-03 15:21:28 -04001295 STACK_OF(SSL_CIPHER) *sk;
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001296
David Benjamin32876b32015-09-20 12:17:03 -04001297 if (ssl == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001298 return NULL;
1299 }
Adam Langley95c29f32014-06-20 12:00:00 -07001300
David Benjamin32876b32015-09-20 12:17:03 -04001301 sk = SSL_get_ciphers(ssl);
Adam Langleyfcf25832014-12-18 17:42:32 -08001302 if (sk == NULL || n < 0 || (size_t)n >= sk_SSL_CIPHER_num(sk)) {
1303 return NULL;
1304 }
Adam Langley95c29f32014-06-20 12:00:00 -07001305
Adam Langleyfcf25832014-12-18 17:42:32 -08001306 c = sk_SSL_CIPHER_value(sk, n);
1307 if (c == NULL) {
1308 return NULL;
1309 }
Adam Langley95c29f32014-06-20 12:00:00 -07001310
Adam Langleyfcf25832014-12-18 17:42:32 -08001311 return c->name;
1312}
David Benjamin5491e3f2014-09-29 19:33:09 -04001313
Adam Langleyfcf25832014-12-18 17:42:32 -08001314int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) {
David Benjamin32876b32015-09-20 12:17:03 -04001315 STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
1316 ctx->method, &ctx->cipher_list, &ctx->cipher_list_by_id, str);
1317 if (cipher_list == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001318 return 0;
David Benjamin32876b32015-09-20 12:17:03 -04001319 }
1320
1321 /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
1322 if (sk_SSL_CIPHER_num(cipher_list) == 0) {
David Benjamin3570d732015-06-29 00:28:17 -04001323 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
Adam Langleyfcf25832014-12-18 17:42:32 -08001324 return 0;
1325 }
Adam Langley95c29f32014-06-20 12:00:00 -07001326
Adam Langleyfcf25832014-12-18 17:42:32 -08001327 return 1;
1328}
David Benjamin39482a12014-07-20 13:30:15 -04001329
Adam Langleycef75832015-09-03 14:51:12 -07001330int SSL_CTX_set_cipher_list_tls10(SSL_CTX *ctx, const char *str) {
David Benjamin32876b32015-09-20 12:17:03 -04001331 STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
1332 ctx->method, &ctx->cipher_list_tls10, NULL, str);
1333 if (cipher_list == NULL) {
Adam Langleycef75832015-09-03 14:51:12 -07001334 return 0;
David Benjamin32876b32015-09-20 12:17:03 -04001335 }
1336
1337 /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
1338 if (sk_SSL_CIPHER_num(cipher_list) == 0) {
Adam Langleycef75832015-09-03 14:51:12 -07001339 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
1340 return 0;
1341 }
1342
1343 return 1;
1344}
1345
Adam Langleyfcf25832014-12-18 17:42:32 -08001346int SSL_CTX_set_cipher_list_tls11(SSL_CTX *ctx, const char *str) {
David Benjamin32876b32015-09-20 12:17:03 -04001347 STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
1348 ctx->method, &ctx->cipher_list_tls11, NULL, str);
1349 if (cipher_list == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001350 return 0;
David Benjamin32876b32015-09-20 12:17:03 -04001351 }
1352
1353 /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
1354 if (sk_SSL_CIPHER_num(cipher_list) == 0) {
David Benjamin3570d732015-06-29 00:28:17 -04001355 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
Adam Langleyfcf25832014-12-18 17:42:32 -08001356 return 0;
1357 }
David Benjamin9f2c0d72014-10-21 22:00:19 -04001358
Adam Langleyfcf25832014-12-18 17:42:32 -08001359 return 1;
1360}
Adam Langley95c29f32014-06-20 12:00:00 -07001361
David Benjamin32876b32015-09-20 12:17:03 -04001362int SSL_set_cipher_list(SSL *ssl, const char *str) {
1363 STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
1364 ssl->ctx->method, &ssl->cipher_list, &ssl->cipher_list_by_id, str);
1365 if (cipher_list == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001366 return 0;
David Benjamin32876b32015-09-20 12:17:03 -04001367 }
1368
1369 /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
1370 if (sk_SSL_CIPHER_num(cipher_list) == 0) {
David Benjamin3570d732015-06-29 00:28:17 -04001371 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
Adam Langleyfcf25832014-12-18 17:42:32 -08001372 return 0;
1373 }
David Benjamin39482a12014-07-20 13:30:15 -04001374
Adam Langleyfcf25832014-12-18 17:42:32 -08001375 return 1;
1376}
Adam Langley95c29f32014-06-20 12:00:00 -07001377
Adam Langleyfcf25832014-12-18 17:42:32 -08001378STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
1379 CBS cipher_suites = *cbs;
1380 const SSL_CIPHER *c;
David Benjamin60da0cd2015-05-03 15:21:28 -04001381 STACK_OF(SSL_CIPHER) *sk;
Adam Langleyfcf25832014-12-18 17:42:32 -08001382
1383 if (s->s3) {
1384 s->s3->send_connection_binding = 0;
1385 }
1386
1387 if (CBS_len(&cipher_suites) % 2 != 0) {
David Benjamin3570d732015-06-29 00:28:17 -04001388 OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
Adam Langleyfcf25832014-12-18 17:42:32 -08001389 return NULL;
1390 }
1391
1392 sk = sk_SSL_CIPHER_new_null();
1393 if (sk == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001394 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
Adam Langleyfcf25832014-12-18 17:42:32 -08001395 goto err;
1396 }
1397
Adam Langleyfcf25832014-12-18 17:42:32 -08001398 while (CBS_len(&cipher_suites) > 0) {
1399 uint16_t cipher_suite;
1400
1401 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
David Benjamin3570d732015-06-29 00:28:17 -04001402 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
Adam Langleyfcf25832014-12-18 17:42:32 -08001403 goto err;
1404 }
1405
1406 /* Check for SCSV. */
1407 if (s->s3 && cipher_suite == (SSL3_CK_SCSV & 0xffff)) {
1408 /* SCSV is fatal if renegotiating. */
David Benjamin20f6e972015-05-15 21:51:49 -04001409 if (s->s3->initial_handshake_complete) {
David Benjamin3570d732015-06-29 00:28:17 -04001410 OPENSSL_PUT_ERROR(SSL, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
Adam Langleyfcf25832014-12-18 17:42:32 -08001411 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
1412 goto err;
1413 }
1414 s->s3->send_connection_binding = 1;
1415 continue;
1416 }
1417
1418 /* Check for FALLBACK_SCSV. */
1419 if (s->s3 && cipher_suite == (SSL3_CK_FALLBACK_SCSV & 0xffff)) {
1420 uint16_t max_version = ssl3_get_max_server_version(s);
1421 if (SSL_IS_DTLS(s) ? (uint16_t)s->version > max_version
1422 : (uint16_t)s->version < max_version) {
David Benjamin3570d732015-06-29 00:28:17 -04001423 OPENSSL_PUT_ERROR(SSL, SSL_R_INAPPROPRIATE_FALLBACK);
Adam Langleyfcf25832014-12-18 17:42:32 -08001424 ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_INAPPROPRIATE_FALLBACK);
1425 goto err;
1426 }
1427 continue;
1428 }
1429
David Benjamina1c90a52015-05-30 17:03:14 -04001430 c = SSL_get_cipher_by_value(cipher_suite);
Adam Langleyfcf25832014-12-18 17:42:32 -08001431 if (c != NULL && !sk_SSL_CIPHER_push(sk, c)) {
David Benjamin3570d732015-06-29 00:28:17 -04001432 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
Adam Langleyfcf25832014-12-18 17:42:32 -08001433 goto err;
1434 }
1435 }
1436
1437 return sk;
David Benjamin9f2c0d72014-10-21 22:00:19 -04001438
Adam Langley95c29f32014-06-20 12:00:00 -07001439err:
David Benjamin2755a3e2015-04-22 16:17:58 -04001440 sk_SSL_CIPHER_free(sk);
Adam Langleyfcf25832014-12-18 17:42:32 -08001441 return NULL;
1442}
Adam Langley95c29f32014-06-20 12:00:00 -07001443
David Benjamin07e13842015-10-17 13:48:04 -04001444const char *SSL_get_servername(const SSL *ssl, const int type) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001445 if (type != TLSEXT_NAMETYPE_host_name) {
1446 return NULL;
1447 }
Adam Langley95c29f32014-06-20 12:00:00 -07001448
David Benjamin07e13842015-10-17 13:48:04 -04001449 /* Historically, |SSL_get_servername| was also the configuration getter
1450 * corresponding to |SSL_set_tlsext_host_name|. */
1451 if (ssl->tlsext_hostname != NULL) {
1452 return ssl->tlsext_hostname;
1453 }
1454
1455 if (ssl->session == NULL) {
1456 return NULL;
1457 }
1458 return ssl->session->tlsext_hostname;
Adam Langleyfcf25832014-12-18 17:42:32 -08001459}
Adam Langley95c29f32014-06-20 12:00:00 -07001460
David Benjamin07e13842015-10-17 13:48:04 -04001461int SSL_get_servername_type(const SSL *ssl) {
1462 if (ssl->session != NULL && ssl->session->tlsext_hostname != NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001463 return TLSEXT_NAMETYPE_host_name;
1464 }
Adam Langley95c29f32014-06-20 12:00:00 -07001465
Adam Langleyfcf25832014-12-18 17:42:32 -08001466 return -1;
1467}
Adam Langley95c29f32014-06-20 12:00:00 -07001468
Adam Langleyfcf25832014-12-18 17:42:32 -08001469void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx) {
1470 ctx->signed_cert_timestamps_enabled = 1;
1471}
HÃ¥vard Molland9169c962014-08-14 14:42:37 +02001472
Adam Langleyfcf25832014-12-18 17:42:32 -08001473int SSL_enable_signed_cert_timestamps(SSL *ssl) {
1474 ssl->signed_cert_timestamps_enabled = 1;
1475 return 1;
1476}
HÃ¥vard Molland9169c962014-08-14 14:42:37 +02001477
Adam Langleyfcf25832014-12-18 17:42:32 -08001478void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx) {
1479 ctx->ocsp_stapling_enabled = 1;
1480}
David Benjamin6c7aed02014-08-27 16:42:38 -04001481
Adam Langleyfcf25832014-12-18 17:42:32 -08001482int SSL_enable_ocsp_stapling(SSL *ssl) {
1483 ssl->ocsp_stapling_enabled = 1;
1484 return 1;
1485}
David Benjamin6c7aed02014-08-27 16:42:38 -04001486
Adam Langleyfcf25832014-12-18 17:42:32 -08001487void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out,
1488 size_t *out_len) {
1489 SSL_SESSION *session = ssl->session;
Adam Langley3cb50e02014-08-26 14:00:31 -07001490
Adam Langleyfcf25832014-12-18 17:42:32 -08001491 *out_len = 0;
1492 *out = NULL;
1493 if (ssl->server || !session || !session->tlsext_signed_cert_timestamp_list) {
1494 return;
1495 }
HÃ¥vard Molland9169c962014-08-14 14:42:37 +02001496
Adam Langleyfcf25832014-12-18 17:42:32 -08001497 *out = session->tlsext_signed_cert_timestamp_list;
1498 *out_len = session->tlsext_signed_cert_timestamp_list_length;
1499}
David Benjamin6c7aed02014-08-27 16:42:38 -04001500
Adam Langleyfcf25832014-12-18 17:42:32 -08001501void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
1502 size_t *out_len) {
1503 SSL_SESSION *session = ssl->session;
1504
1505 *out_len = 0;
1506 *out = NULL;
1507 if (ssl->server || !session || !session->ocsp_response) {
1508 return;
1509 }
1510 *out = session->ocsp_response;
1511 *out_len = session->ocsp_response_length;
1512}
David Benjamin6c7aed02014-08-27 16:42:38 -04001513
Paul Lietar4fac72e2015-09-09 13:44:55 +01001514int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list,
1515 size_t list_len) {
1516 OPENSSL_free(ctx->signed_cert_timestamp_list);
1517 ctx->signed_cert_timestamp_list_length = 0;
1518
1519 ctx->signed_cert_timestamp_list = BUF_memdup(list, list_len);
1520 if (ctx->signed_cert_timestamp_list == NULL) {
1521 return 0;
1522 }
1523 ctx->signed_cert_timestamp_list_length = list_len;
1524
1525 return 1;
1526}
1527
Paul Lietaraeeff2c2015-08-12 11:47:11 +01001528int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response,
1529 size_t response_len) {
1530 OPENSSL_free(ctx->ocsp_response);
1531 ctx->ocsp_response_length = 0;
1532
1533 ctx->ocsp_response = BUF_memdup(response, response_len);
1534 if (ctx->ocsp_response == NULL) {
1535 return 0;
1536 }
1537 ctx->ocsp_response_length = response_len;
1538
1539 return 1;
1540}
1541
David Benjamin977547b2015-09-16 00:25:52 -04001542int SSL_select_next_proto(uint8_t **out, uint8_t *out_len,
1543 const uint8_t *server, unsigned server_len,
1544 const uint8_t *client, unsigned client_len) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001545 unsigned int i, j;
1546 const uint8_t *result;
1547 int status = OPENSSL_NPN_UNSUPPORTED;
Adam Langley95c29f32014-06-20 12:00:00 -07001548
Adam Langleyfcf25832014-12-18 17:42:32 -08001549 /* For each protocol in server preference order, see if we support it. */
1550 for (i = 0; i < server_len;) {
1551 for (j = 0; j < client_len;) {
1552 if (server[i] == client[j] &&
1553 memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) {
1554 /* We found a match */
1555 result = &server[i];
1556 status = OPENSSL_NPN_NEGOTIATED;
1557 goto found;
1558 }
1559 j += client[j];
1560 j++;
1561 }
1562 i += server[i];
1563 i++;
1564 }
Adam Langley95c29f32014-06-20 12:00:00 -07001565
Adam Langleyfcf25832014-12-18 17:42:32 -08001566 /* There's no overlap between our protocols and the server's list. */
1567 result = client;
1568 status = OPENSSL_NPN_NO_OVERLAP;
Adam Langley95c29f32014-06-20 12:00:00 -07001569
Adam Langleyfcf25832014-12-18 17:42:32 -08001570found:
1571 *out = (uint8_t *)result + 1;
David Benjamin977547b2015-09-16 00:25:52 -04001572 *out_len = result[0];
Adam Langleyfcf25832014-12-18 17:42:32 -08001573 return status;
1574}
Adam Langley95c29f32014-06-20 12:00:00 -07001575
David Benjamin977547b2015-09-16 00:25:52 -04001576void SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data,
1577 unsigned *out_len) {
1578 *out_data = ssl->next_proto_negotiated;
1579 if (*out_data == NULL) {
1580 *out_len = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001581 } else {
David Benjamin977547b2015-09-16 00:25:52 -04001582 *out_len = ssl->next_proto_negotiated_len;
Adam Langleyfcf25832014-12-18 17:42:32 -08001583 }
Adam Langley95c29f32014-06-20 12:00:00 -07001584}
1585
Adam Langleyfcf25832014-12-18 17:42:32 -08001586void SSL_CTX_set_next_protos_advertised_cb(
1587 SSL_CTX *ctx,
David Benjamin977547b2015-09-16 00:25:52 -04001588 int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg),
Adam Langleyfcf25832014-12-18 17:42:32 -08001589 void *arg) {
1590 ctx->next_protos_advertised_cb = cb;
1591 ctx->next_protos_advertised_cb_arg = arg;
1592}
Adam Langley95c29f32014-06-20 12:00:00 -07001593
Adam Langleyfcf25832014-12-18 17:42:32 -08001594void SSL_CTX_set_next_proto_select_cb(
David Benjamin977547b2015-09-16 00:25:52 -04001595 SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len,
1596 const uint8_t *in, unsigned in_len, void *arg),
Adam Langleyfcf25832014-12-18 17:42:32 -08001597 void *arg) {
1598 ctx->next_proto_select_cb = cb;
1599 ctx->next_proto_select_cb_arg = arg;
1600}
Adam Langley95c29f32014-06-20 12:00:00 -07001601
Adam Langleyfcf25832014-12-18 17:42:32 -08001602int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos,
1603 unsigned protos_len) {
David Benjamin2755a3e2015-04-22 16:17:58 -04001604 OPENSSL_free(ctx->alpn_client_proto_list);
Adam Langleyfcf25832014-12-18 17:42:32 -08001605 ctx->alpn_client_proto_list = BUF_memdup(protos, protos_len);
1606 if (!ctx->alpn_client_proto_list) {
1607 return 1;
1608 }
1609 ctx->alpn_client_proto_list_len = protos_len;
Adam Langley95c29f32014-06-20 12:00:00 -07001610
Adam Langleyfcf25832014-12-18 17:42:32 -08001611 return 0;
1612}
Adam Langley95c29f32014-06-20 12:00:00 -07001613
Adam Langleyfcf25832014-12-18 17:42:32 -08001614int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) {
David Benjamin2755a3e2015-04-22 16:17:58 -04001615 OPENSSL_free(ssl->alpn_client_proto_list);
Adam Langleyfcf25832014-12-18 17:42:32 -08001616 ssl->alpn_client_proto_list = BUF_memdup(protos, protos_len);
1617 if (!ssl->alpn_client_proto_list) {
1618 return 1;
1619 }
1620 ssl->alpn_client_proto_list_len = protos_len;
Adam Langley95c29f32014-06-20 12:00:00 -07001621
Adam Langleyfcf25832014-12-18 17:42:32 -08001622 return 0;
1623}
Adam Langley95c29f32014-06-20 12:00:00 -07001624
Adam Langleyfcf25832014-12-18 17:42:32 -08001625void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
1626 int (*cb)(SSL *ssl, const uint8_t **out,
David Benjamin8984f1f2015-09-16 00:10:19 -04001627 uint8_t *out_len, const uint8_t *in,
1628 unsigned in_len, void *arg),
Adam Langleyfcf25832014-12-18 17:42:32 -08001629 void *arg) {
1630 ctx->alpn_select_cb = cb;
1631 ctx->alpn_select_cb_arg = arg;
1632}
Adam Langley95c29f32014-06-20 12:00:00 -07001633
David Benjamin8984f1f2015-09-16 00:10:19 -04001634void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data,
1635 unsigned *out_len) {
1636 *out_data = NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -08001637 if (ssl->s3) {
David Benjamin8984f1f2015-09-16 00:10:19 -04001638 *out_data = ssl->s3->alpn_selected;
Adam Langleyfcf25832014-12-18 17:42:32 -08001639 }
David Benjamin8984f1f2015-09-16 00:10:19 -04001640 if (*out_data == NULL) {
1641 *out_len = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001642 } else {
David Benjamin8984f1f2015-09-16 00:10:19 -04001643 *out_len = ssl->s3->alpn_selected_len;
Adam Langleyfcf25832014-12-18 17:42:32 -08001644 }
1645}
Adam Langley95c29f32014-06-20 12:00:00 -07001646
David Benjamin07e13842015-10-17 13:48:04 -04001647int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
David Benjamincfd248b2015-04-03 11:02:24 -04001648 const char *label, size_t label_len,
1649 const uint8_t *context, size_t context_len,
1650 int use_context) {
David Benjamin07e13842015-10-17 13:48:04 -04001651 if (ssl->version < TLS1_VERSION) {
David Benjaminc565ebb2015-04-03 04:06:36 -04001652 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001653 }
Adam Langley95c29f32014-06-20 12:00:00 -07001654
David Benjamin07e13842015-10-17 13:48:04 -04001655 return ssl->enc_method->export_keying_material(
1656 ssl, out, out_len, label, label_len, context, context_len, use_context);
Adam Langleyfcf25832014-12-18 17:42:32 -08001657}
Adam Langley95c29f32014-06-20 12:00:00 -07001658
Adam Langleyfcf25832014-12-18 17:42:32 -08001659void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
David Benjamin59937042015-09-19 13:04:22 -04001660 int (*cb)(X509_STORE_CTX *store_ctx,
1661 void *arg),
Adam Langleyfcf25832014-12-18 17:42:32 -08001662 void *arg) {
1663 ctx->app_verify_callback = cb;
1664 ctx->app_verify_arg = arg;
1665}
Adam Langley95c29f32014-06-20 12:00:00 -07001666
Adam Langleyfcf25832014-12-18 17:42:32 -08001667void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
1668 int (*cb)(int, X509_STORE_CTX *)) {
1669 ctx->verify_mode = mode;
1670 ctx->default_verify_callback = cb;
1671}
Adam Langley95c29f32014-06-20 12:00:00 -07001672
Adam Langleyfcf25832014-12-18 17:42:32 -08001673void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) {
1674 X509_VERIFY_PARAM_set_depth(ctx->param, depth);
1675}
Adam Langley1258b6a2014-06-20 12:00:00 -07001676
David Benjamin7481d392015-07-05 19:38:46 -04001677void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg),
Adam Langleyfcf25832014-12-18 17:42:32 -08001678 void *arg) {
David Benjamin7481d392015-07-05 19:38:46 -04001679 ssl_cert_set_cert_cb(ctx->cert, cb, arg);
Adam Langleyfcf25832014-12-18 17:42:32 -08001680}
David Benjamin859ec3c2014-09-02 16:29:36 -04001681
David Benjamin7481d392015-07-05 19:38:46 -04001682void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) {
1683 ssl_cert_set_cert_cb(ssl->cert, cb, arg);
Adam Langleyfcf25832014-12-18 17:42:32 -08001684}
Adam Langley95c29f32014-06-20 12:00:00 -07001685
David Benjamin107db582015-04-08 00:41:59 -04001686void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k,
1687 uint32_t *out_mask_a) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001688 CERT *c = s->cert;
David Benjamind1d80782015-07-05 11:54:09 -04001689 int have_rsa_cert = 0, dh_tmp;
David Benjamin107db582015-04-08 00:41:59 -04001690 uint32_t mask_k, mask_a;
David Benjamind1d80782015-07-05 11:54:09 -04001691 int have_ecc_cert = 0, ecdsa_ok;
Adam Langleyfcf25832014-12-18 17:42:32 -08001692 X509 *x;
Adam Langley95c29f32014-06-20 12:00:00 -07001693
Adam Langleyfcf25832014-12-18 17:42:32 -08001694 dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
Adam Langley95c29f32014-06-20 12:00:00 -07001695
nagendra modadugu601448a2015-07-24 09:31:31 -07001696 if (s->cert->x509 != NULL && ssl_has_private_key(s)) {
1697 if (ssl_private_key_type(s) == EVP_PKEY_RSA) {
David Benjamind1d80782015-07-05 11:54:09 -04001698 have_rsa_cert = 1;
nagendra modadugu601448a2015-07-24 09:31:31 -07001699 } else if (ssl_private_key_type(s) == EVP_PKEY_EC) {
David Benjamind1d80782015-07-05 11:54:09 -04001700 have_ecc_cert = 1;
1701 }
1702 }
nagendra modadugu601448a2015-07-24 09:31:31 -07001703
Adam Langleyfcf25832014-12-18 17:42:32 -08001704 mask_k = 0;
1705 mask_a = 0;
David Benjaminf31e6812014-11-13 18:05:55 -05001706
Adam Langleyfcf25832014-12-18 17:42:32 -08001707 if (dh_tmp) {
David Benjamin7061e282015-03-19 11:10:48 -04001708 mask_k |= SSL_kDHE;
Adam Langleyfcf25832014-12-18 17:42:32 -08001709 }
David Benjaminbb20f522015-07-04 17:18:14 -04001710 if (have_rsa_cert) {
1711 mask_k |= SSL_kRSA;
Adam Langleyfcf25832014-12-18 17:42:32 -08001712 mask_a |= SSL_aRSA;
1713 }
Adam Langley95c29f32014-06-20 12:00:00 -07001714
Adam Langleyfcf25832014-12-18 17:42:32 -08001715 /* An ECC certificate may be usable for ECDSA cipher suites depending on the
1716 * key usage extension and on the client's curve preferences. */
1717 if (have_ecc_cert) {
David Benjamind1d80782015-07-05 11:54:09 -04001718 x = c->x509;
Adam Langleyfcf25832014-12-18 17:42:32 -08001719 /* This call populates extension flags (ex_flags). */
1720 X509_check_purpose(x, -1, 0);
1721 ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE)
1722 ? (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)
1723 : 1;
1724 if (!tls1_check_ec_cert(s, x)) {
1725 ecdsa_ok = 0;
1726 }
1727 if (ecdsa_ok) {
1728 mask_a |= SSL_aECDSA;
1729 }
1730 }
Adam Langley95c29f32014-06-20 12:00:00 -07001731
Adam Langleyfcf25832014-12-18 17:42:32 -08001732 /* If we are considering an ECC cipher suite that uses an ephemeral EC
David Benjamin5ddffbb2015-12-04 21:08:47 -05001733 * key, check for a shared curve. */
David Benjamin4298d772015-12-19 00:18:25 -05001734 uint16_t unused;
1735 if (tls1_get_shared_curve(s, &unused)) {
David Benjamin7061e282015-03-19 11:10:48 -04001736 mask_k |= SSL_kECDHE;
Adam Langleyfcf25832014-12-18 17:42:32 -08001737 }
Adam Langley95c29f32014-06-20 12:00:00 -07001738
Adam Langleyfcf25832014-12-18 17:42:32 -08001739 /* PSK requires a server callback. */
1740 if (s->psk_server_callback != NULL) {
1741 mask_k |= SSL_kPSK;
1742 mask_a |= SSL_aPSK;
1743 }
Adam Langley95c29f32014-06-20 12:00:00 -07001744
Adam Langleyfcf25832014-12-18 17:42:32 -08001745 *out_mask_k = mask_k;
1746 *out_mask_a = mask_a;
1747}
Adam Langley95c29f32014-06-20 12:00:00 -07001748
David Benjamin1269ddd2015-10-18 15:18:55 -04001749void ssl_update_cache(SSL *ssl, int mode) {
1750 SSL_CTX *ctx = ssl->initial_ctx;
David Benjaminb6d0c6d2015-03-19 19:07:26 -04001751 /* Never cache sessions with empty session IDs. */
David Benjamin1269ddd2015-10-18 15:18:55 -04001752 if (ssl->session->session_id_length == 0 ||
1753 (ctx->session_cache_mode & mode) != mode) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001754 return;
1755 }
Adam Langley95c29f32014-06-20 12:00:00 -07001756
David Benjamin1269ddd2015-10-18 15:18:55 -04001757 /* Clients never use the internal session cache. */
1758 int use_internal_cache = ssl->server && !(ctx->session_cache_mode &
1759 SSL_SESS_CACHE_NO_INTERNAL_STORE);
David Benjamin95d31822015-06-15 19:53:32 -04001760
David Benjamin1269ddd2015-10-18 15:18:55 -04001761 /* A client may see new sessions on abbreviated handshakes if the server
1762 * decides to renew the ticket. Once the handshake is completed, it should be
1763 * inserted into the cache. */
1764 if (!ssl->hit || (!ssl->server && ssl->tlsext_ticket_expected)) {
1765 if (use_internal_cache) {
1766 SSL_CTX_add_session(ctx, ssl->session);
1767 }
1768 if (ctx->new_session_cb != NULL &&
1769 !ctx->new_session_cb(ssl, SSL_SESSION_up_ref(ssl->session))) {
1770 /* |new_session_cb|'s return value signals whether it took ownership. */
1771 SSL_SESSION_free(ssl->session);
Adam Langleyfcf25832014-12-18 17:42:32 -08001772 }
1773 }
Adam Langley95c29f32014-06-20 12:00:00 -07001774
David Benjamin1269ddd2015-10-18 15:18:55 -04001775 if (use_internal_cache &&
1776 !(ctx->session_cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR)) {
David Benjaminb6d0c6d2015-03-19 19:07:26 -04001777 /* Automatically flush the internal session cache every 255 connections. */
1778 int flush_cache = 0;
Adam Langley4bdb6e42015-05-15 15:29:21 -07001779 CRYPTO_MUTEX_lock_write(&ctx->lock);
David Benjaminb6d0c6d2015-03-19 19:07:26 -04001780 ctx->handshakes_since_cache_flush++;
1781 if (ctx->handshakes_since_cache_flush >= 255) {
1782 flush_cache = 1;
1783 ctx->handshakes_since_cache_flush = 0;
1784 }
Adam Langley4bdb6e42015-05-15 15:29:21 -07001785 CRYPTO_MUTEX_unlock(&ctx->lock);
David Benjaminb6d0c6d2015-03-19 19:07:26 -04001786
1787 if (flush_cache) {
1788 SSL_CTX_flush_sessions(ctx, (unsigned long)time(NULL));
Adam Langleyfcf25832014-12-18 17:42:32 -08001789 }
1790 }
1791}
Adam Langley95c29f32014-06-20 12:00:00 -07001792
Adam Langleyfcf25832014-12-18 17:42:32 -08001793static const char *ssl_get_version(int version) {
1794 switch (version) {
1795 case TLS1_2_VERSION:
1796 return "TLSv1.2";
Adam Langley95c29f32014-06-20 12:00:00 -07001797
Adam Langleyfcf25832014-12-18 17:42:32 -08001798 case TLS1_1_VERSION:
1799 return "TLSv1.1";
Adam Langley95c29f32014-06-20 12:00:00 -07001800
Adam Langleyfcf25832014-12-18 17:42:32 -08001801 case TLS1_VERSION:
1802 return "TLSv1";
Adam Langley95c29f32014-06-20 12:00:00 -07001803
Adam Langleyfcf25832014-12-18 17:42:32 -08001804 case SSL3_VERSION:
1805 return "SSLv3";
Adam Langley95c29f32014-06-20 12:00:00 -07001806
David Benjamin1c722b72015-04-20 13:53:10 -04001807 case DTLS1_VERSION:
1808 return "DTLSv1";
1809
1810 case DTLS1_2_VERSION:
1811 return "DTLSv1.2";
1812
Adam Langleyfcf25832014-12-18 17:42:32 -08001813 default:
1814 return "unknown";
1815 }
1816}
Adam Langley95c29f32014-06-20 12:00:00 -07001817
David Benjamin42fea372015-09-19 01:22:44 -04001818const char *SSL_get_version(const SSL *ssl) {
1819 return ssl_get_version(ssl->version);
Adam Langleyfcf25832014-12-18 17:42:32 -08001820}
Adam Langley95c29f32014-06-20 12:00:00 -07001821
David Benjamina6b8cdf2015-09-13 14:07:33 -04001822const char *SSL_SESSION_get_version(const SSL_SESSION *session) {
1823 return ssl_get_version(session->ssl_version);
Adam Langleyfcf25832014-12-18 17:42:32 -08001824}
Adam Langley95c29f32014-06-20 12:00:00 -07001825
Adam Langleyfcf25832014-12-18 17:42:32 -08001826void ssl_clear_cipher_ctx(SSL *s) {
David Benjamin31a07792015-03-03 14:20:26 -05001827 SSL_AEAD_CTX_free(s->aead_read_ctx);
1828 s->aead_read_ctx = NULL;
1829 SSL_AEAD_CTX_free(s->aead_write_ctx);
1830 s->aead_write_ctx = NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -08001831}
Adam Langley95c29f32014-06-20 12:00:00 -07001832
Adam Langleyfcf25832014-12-18 17:42:32 -08001833X509 *SSL_get_certificate(const SSL *s) {
1834 if (s->cert != NULL) {
David Benjamind1d80782015-07-05 11:54:09 -04001835 return s->cert->x509;
Adam Langleyfcf25832014-12-18 17:42:32 -08001836 }
1837
1838 return NULL;
1839}
1840
1841EVP_PKEY *SSL_get_privatekey(const SSL *s) {
1842 if (s->cert != NULL) {
David Benjamind1d80782015-07-05 11:54:09 -04001843 return s->cert->privatekey;
Adam Langleyfcf25832014-12-18 17:42:32 -08001844 }
1845
1846 return NULL;
1847}
1848
1849X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
1850 if (ctx->cert != NULL) {
David Benjamind1d80782015-07-05 11:54:09 -04001851 return ctx->cert->x509;
Adam Langleyfcf25832014-12-18 17:42:32 -08001852 }
1853
1854 return NULL;
1855}
1856
1857EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) {
1858 if (ctx->cert != NULL) {
David Benjamind1d80782015-07-05 11:54:09 -04001859 return ctx->cert->privatekey;
Adam Langleyfcf25832014-12-18 17:42:32 -08001860 }
1861
1862 return NULL;
1863}
1864
David Benjamin42fea372015-09-19 01:22:44 -04001865const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl) {
1866 if (ssl->aead_write_ctx == NULL) {
David Benjamina07c0fc2015-05-13 13:19:42 -04001867 return NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -08001868 }
David Benjamin42fea372015-09-19 01:22:44 -04001869 return ssl->aead_write_ctx->cipher;
Adam Langleyfcf25832014-12-18 17:42:32 -08001870}
1871
Matt Braithwaite6a1275b2015-06-26 12:09:10 -07001872const COMP_METHOD *SSL_get_current_compression(SSL *s) { return NULL; }
Adam Langleyfcf25832014-12-18 17:42:32 -08001873
Matt Braithwaite6a1275b2015-06-26 12:09:10 -07001874const COMP_METHOD *SSL_get_current_expansion(SSL *s) { return NULL; }
Adam Langleyfcf25832014-12-18 17:42:32 -08001875
1876int ssl_init_wbio_buffer(SSL *s, int push) {
1877 BIO *bbio;
1878
1879 if (s->bbio == NULL) {
1880 bbio = BIO_new(BIO_f_buffer());
1881 if (bbio == NULL) {
1882 return 0;
1883 }
1884 s->bbio = bbio;
1885 } else {
1886 bbio = s->bbio;
1887 if (s->bbio == s->wbio) {
1888 s->wbio = BIO_pop(s->wbio);
1889 }
1890 }
1891
1892 BIO_reset(bbio);
1893 if (!BIO_set_read_buffer_size(bbio, 1)) {
David Benjamin3570d732015-06-29 00:28:17 -04001894 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
Adam Langleyfcf25832014-12-18 17:42:32 -08001895 return 0;
1896 }
1897
1898 if (push) {
1899 if (s->wbio != bbio) {
1900 s->wbio = BIO_push(bbio, s->wbio);
1901 }
1902 } else {
1903 if (s->wbio == bbio) {
1904 s->wbio = BIO_pop(bbio);
1905 }
1906 }
1907
1908 return 1;
1909}
1910
1911void ssl_free_wbio_buffer(SSL *s) {
1912 if (s->bbio == NULL) {
1913 return;
1914 }
1915
1916 if (s->bbio == s->wbio) {
1917 /* remove buffering */
1918 s->wbio = BIO_pop(s->wbio);
1919 }
1920
1921 BIO_free(s->bbio);
1922 s->bbio = NULL;
1923}
1924
1925void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) {
Adam Langleybb85f3d2015-10-28 18:44:11 -07001926 ctx->quiet_shutdown = (mode != 0);
Adam Langleyfcf25832014-12-18 17:42:32 -08001927}
1928
1929int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) {
1930 return ctx->quiet_shutdown;
1931}
1932
Adam Langleybb85f3d2015-10-28 18:44:11 -07001933void SSL_set_quiet_shutdown(SSL *ssl, int mode) {
1934 ssl->quiet_shutdown = (mode != 0);
1935}
Adam Langleyfcf25832014-12-18 17:42:32 -08001936
David Benjamin9f859492015-10-03 10:44:30 -04001937int SSL_get_quiet_shutdown(const SSL *ssl) { return ssl->quiet_shutdown; }
Adam Langleyfcf25832014-12-18 17:42:32 -08001938
David Benjamin63006a92015-10-18 00:00:06 -04001939void SSL_set_shutdown(SSL *ssl, int mode) {
1940 /* It is an error to clear any bits that have already been set. (We can't try
1941 * to get a second close_notify or send two.) */
Piotr Sikora7063b6d2015-10-29 02:47:40 -07001942 assert((ssl->shutdown & mode) == ssl->shutdown);
David Benjamin63006a92015-10-18 00:00:06 -04001943
1944 ssl->shutdown |= mode;
1945}
Adam Langleyfcf25832014-12-18 17:42:32 -08001946
David Benjamin9f859492015-10-03 10:44:30 -04001947int SSL_get_shutdown(const SSL *ssl) { return ssl->shutdown; }
Adam Langleyfcf25832014-12-18 17:42:32 -08001948
David Benjamin9f859492015-10-03 10:44:30 -04001949int SSL_version(const SSL *ssl) { return ssl->version; }
Adam Langleyfcf25832014-12-18 17:42:32 -08001950
1951SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return ssl->ctx; }
1952
1953SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) {
1954 if (ssl->ctx == ctx) {
1955 return ssl->ctx;
1956 }
1957
1958 if (ctx == NULL) {
1959 ctx = ssl->initial_ctx;
1960 }
1961
David Benjamin2755a3e2015-04-22 16:17:58 -04001962 ssl_cert_free(ssl->cert);
Adam Langleyfcf25832014-12-18 17:42:32 -08001963 ssl->cert = ssl_cert_dup(ctx->cert);
David Benjamin2755a3e2015-04-22 16:17:58 -04001964
Adam Langley0b5e3902015-05-15 13:08:38 -07001965 CRYPTO_refcount_inc(&ctx->references);
David Benjamin2755a3e2015-04-22 16:17:58 -04001966 SSL_CTX_free(ssl->ctx); /* decrement reference count */
Adam Langleyfcf25832014-12-18 17:42:32 -08001967 ssl->ctx = ctx;
1968
1969 ssl->sid_ctx_length = ctx->sid_ctx_length;
1970 assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx));
1971 memcpy(ssl->sid_ctx, ctx->sid_ctx, sizeof(ssl->sid_ctx));
1972
1973 return ssl->ctx;
1974}
1975
1976int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) {
1977 return X509_STORE_set_default_paths(ctx->cert_store);
1978}
Adam Langley95c29f32014-06-20 12:00:00 -07001979
David Benjamin59937042015-09-19 13:04:22 -04001980int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file,
1981 const char *ca_dir) {
1982 return X509_STORE_load_locations(ctx->cert_store, ca_file, ca_dir);
Adam Langleyfcf25832014-12-18 17:42:32 -08001983}
Adam Langley95c29f32014-06-20 12:00:00 -07001984
1985void SSL_set_info_callback(SSL *ssl,
David Benjamin82170242015-10-17 22:51:17 -04001986 void (*cb)(const SSL *ssl, int type, int value)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001987 ssl->info_callback = cb;
1988}
Adam Langley95c29f32014-06-20 12:00:00 -07001989
David Benjamin82170242015-10-17 22:51:17 -04001990void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, int type,
1991 int value) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001992 return ssl->info_callback;
1993}
Adam Langley95c29f32014-06-20 12:00:00 -07001994
Adam Langleyfcf25832014-12-18 17:42:32 -08001995int SSL_state(const SSL *ssl) { return ssl->state; }
Adam Langley95c29f32014-06-20 12:00:00 -07001996
David Benjaminece089c2015-05-15 23:52:42 -04001997void SSL_set_state(SSL *ssl, int state) { }
Adam Langley95c29f32014-06-20 12:00:00 -07001998
David Benjamin59937042015-09-19 13:04:22 -04001999void SSL_set_verify_result(SSL *ssl, long result) {
2000 ssl->verify_result = result;
2001}
Adam Langley95c29f32014-06-20 12:00:00 -07002002
Adam Langleyfcf25832014-12-18 17:42:32 -08002003long SSL_get_verify_result(const SSL *ssl) { return ssl->verify_result; }
Adam Langley95c29f32014-06-20 12:00:00 -07002004
David Benjamin8a589332015-12-04 23:14:35 -05002005int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
Adam Langleyfcf25832014-12-18 17:42:32 -08002006 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
David Benjamin9f33fc62015-04-15 17:29:53 -04002007 int index;
2008 if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl, &index, argl, argp,
David Benjamin8a589332015-12-04 23:14:35 -05002009 dup_func, free_func)) {
David Benjamin9f33fc62015-04-15 17:29:53 -04002010 return -1;
2011 }
2012 return index;
Adam Langleyfcf25832014-12-18 17:42:32 -08002013}
Adam Langley95c29f32014-06-20 12:00:00 -07002014
David Benjamin1ac08fe2015-09-15 01:36:22 -04002015int SSL_set_ex_data(SSL *ssl, int idx, void *arg) {
2016 return CRYPTO_set_ex_data(&ssl->ex_data, idx, arg);
Adam Langleyfcf25832014-12-18 17:42:32 -08002017}
Adam Langley95c29f32014-06-20 12:00:00 -07002018
David Benjamin1ac08fe2015-09-15 01:36:22 -04002019void *SSL_get_ex_data(const SSL *ssl, int idx) {
2020 return CRYPTO_get_ex_data(&ssl->ex_data, idx);
Adam Langleyfcf25832014-12-18 17:42:32 -08002021}
Adam Langley95c29f32014-06-20 12:00:00 -07002022
David Benjamin8a589332015-12-04 23:14:35 -05002023int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
Adam Langleyfcf25832014-12-18 17:42:32 -08002024 CRYPTO_EX_dup *dup_func,
2025 CRYPTO_EX_free *free_func) {
David Benjamin9f33fc62015-04-15 17:29:53 -04002026 int index;
2027 if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl_ctx, &index, argl, argp,
David Benjamin8a589332015-12-04 23:14:35 -05002028 dup_func, free_func)) {
David Benjamin9f33fc62015-04-15 17:29:53 -04002029 return -1;
2030 }
2031 return index;
Adam Langleyfcf25832014-12-18 17:42:32 -08002032}
Adam Langley95c29f32014-06-20 12:00:00 -07002033
David Benjamin1ac08fe2015-09-15 01:36:22 -04002034int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *arg) {
2035 return CRYPTO_set_ex_data(&ctx->ex_data, idx, arg);
Adam Langleyfcf25832014-12-18 17:42:32 -08002036}
Adam Langley95c29f32014-06-20 12:00:00 -07002037
David Benjamin1ac08fe2015-09-15 01:36:22 -04002038void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) {
2039 return CRYPTO_get_ex_data(&ctx->ex_data, idx);
Adam Langleyfcf25832014-12-18 17:42:32 -08002040}
Adam Langley95c29f32014-06-20 12:00:00 -07002041
Adam Langleyfcf25832014-12-18 17:42:32 -08002042X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
2043 return ctx->cert_store;
2044}
Adam Langley95c29f32014-06-20 12:00:00 -07002045
Adam Langleyfcf25832014-12-18 17:42:32 -08002046void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) {
David Benjamin2755a3e2015-04-22 16:17:58 -04002047 X509_STORE_free(ctx->cert_store);
Adam Langleyfcf25832014-12-18 17:42:32 -08002048 ctx->cert_store = store;
2049}
Adam Langley95c29f32014-06-20 12:00:00 -07002050
David Benjamin93d17492015-10-17 12:43:36 -04002051int SSL_want(const SSL *ssl) { return ssl->rwstate; }
Adam Langley95c29f32014-06-20 12:00:00 -07002052
Adam Langleyfcf25832014-12-18 17:42:32 -08002053void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
2054 RSA *(*cb)(SSL *ssl, int is_export,
2055 int keylength)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002056}
Adam Langley95c29f32014-06-20 12:00:00 -07002057
Adam Langleyfcf25832014-12-18 17:42:32 -08002058void SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb)(SSL *ssl, int is_export,
2059 int keylength)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002060}
2061
2062void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
David Benjamin59015c32015-04-26 13:13:55 -04002063 DH *(*callback)(SSL *ssl, int is_export,
2064 int keylength)) {
2065 ctx->cert->dh_tmp_cb = callback;
Adam Langleyfcf25832014-12-18 17:42:32 -08002066}
2067
David Benjamin59015c32015-04-26 13:13:55 -04002068void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*callback)(SSL *ssl, int is_export,
2069 int keylength)) {
2070 ssl->cert->dh_tmp_cb = callback;
Adam Langleyfcf25832014-12-18 17:42:32 -08002071}
2072
Adam Langleyfcf25832014-12-18 17:42:32 -08002073int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) {
2074 if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
David Benjamin3570d732015-06-29 00:28:17 -04002075 OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
Adam Langleyfcf25832014-12-18 17:42:32 -08002076 return 0;
2077 }
2078
David Benjamin2755a3e2015-04-22 16:17:58 -04002079 OPENSSL_free(ctx->psk_identity_hint);
Adam Langleyfcf25832014-12-18 17:42:32 -08002080
2081 if (identity_hint != NULL) {
2082 ctx->psk_identity_hint = BUF_strdup(identity_hint);
2083 if (ctx->psk_identity_hint == NULL) {
2084 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07002085 }
Adam Langleyfcf25832014-12-18 17:42:32 -08002086 } else {
2087 ctx->psk_identity_hint = NULL;
2088 }
Adam Langley95c29f32014-06-20 12:00:00 -07002089
Adam Langleyfcf25832014-12-18 17:42:32 -08002090 return 1;
2091}
2092
David Benjamine8814df2015-09-15 08:05:54 -04002093int SSL_use_psk_identity_hint(SSL *ssl, const char *identity_hint) {
2094 if (ssl == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002095 return 0;
2096 }
2097
2098 if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
David Benjamin3570d732015-06-29 00:28:17 -04002099 OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
Adam Langleyfcf25832014-12-18 17:42:32 -08002100 return 0;
2101 }
2102
2103 /* Clear currently configured hint, if any. */
David Benjamine8814df2015-09-15 08:05:54 -04002104 OPENSSL_free(ssl->psk_identity_hint);
2105 ssl->psk_identity_hint = NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -08002106
2107 if (identity_hint != NULL) {
David Benjamine8814df2015-09-15 08:05:54 -04002108 ssl->psk_identity_hint = BUF_strdup(identity_hint);
2109 if (ssl->psk_identity_hint == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002110 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07002111 }
Adam Langleyfcf25832014-12-18 17:42:32 -08002112 }
Adam Langley95c29f32014-06-20 12:00:00 -07002113
Adam Langleyfcf25832014-12-18 17:42:32 -08002114 return 1;
2115}
Adam Langley95c29f32014-06-20 12:00:00 -07002116
David Benjamine8814df2015-09-15 08:05:54 -04002117const char *SSL_get_psk_identity_hint(const SSL *ssl) {
2118 if (ssl == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002119 return NULL;
2120 }
David Benjamine8814df2015-09-15 08:05:54 -04002121 return ssl->psk_identity_hint;
Adam Langleyfcf25832014-12-18 17:42:32 -08002122}
Adam Langley95c29f32014-06-20 12:00:00 -07002123
David Benjamine8814df2015-09-15 08:05:54 -04002124const char *SSL_get_psk_identity(const SSL *ssl) {
2125 if (ssl == NULL || ssl->session == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002126 return NULL;
2127 }
Adam Langley95c29f32014-06-20 12:00:00 -07002128
David Benjamine8814df2015-09-15 08:05:54 -04002129 return ssl->session->psk_identity;
Adam Langleyfcf25832014-12-18 17:42:32 -08002130}
Adam Langley95c29f32014-06-20 12:00:00 -07002131
Adam Langleyfcf25832014-12-18 17:42:32 -08002132void SSL_set_psk_client_callback(
David Benjamine8814df2015-09-15 08:05:54 -04002133 SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity,
2134 unsigned max_identity_len, uint8_t *psk,
2135 unsigned max_psk_len)) {
2136 ssl->psk_client_callback = cb;
Adam Langleyfcf25832014-12-18 17:42:32 -08002137}
Adam Langley95c29f32014-06-20 12:00:00 -07002138
Adam Langleyfcf25832014-12-18 17:42:32 -08002139void SSL_CTX_set_psk_client_callback(
David Benjamine8814df2015-09-15 08:05:54 -04002140 SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *hint, char *identity,
2141 unsigned max_identity_len, uint8_t *psk,
2142 unsigned max_psk_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002143 ctx->psk_client_callback = cb;
2144}
Adam Langley95c29f32014-06-20 12:00:00 -07002145
Adam Langleyfcf25832014-12-18 17:42:32 -08002146void SSL_set_psk_server_callback(
David Benjamine8814df2015-09-15 08:05:54 -04002147 SSL *ssl, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk,
2148 unsigned max_psk_len)) {
2149 ssl->psk_server_callback = cb;
Adam Langleyfcf25832014-12-18 17:42:32 -08002150}
Adam Langley95c29f32014-06-20 12:00:00 -07002151
Adam Langleyfcf25832014-12-18 17:42:32 -08002152void SSL_CTX_set_psk_server_callback(
David Benjamine8814df2015-09-15 08:05:54 -04002153 SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *identity,
2154 uint8_t *psk, unsigned max_psk_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002155 ctx->psk_server_callback = cb;
2156}
Adam Langley95c29f32014-06-20 12:00:00 -07002157
Adam Langleyfcf25832014-12-18 17:42:32 -08002158void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
2159 void (*cb)(int write_p, int version,
2160 int content_type, const void *buf,
2161 size_t len, SSL *ssl, void *arg)) {
David Benjamin59015c32015-04-26 13:13:55 -04002162 ctx->msg_callback = cb;
Adam Langleyfcf25832014-12-18 17:42:32 -08002163}
David Benjamin61ecccf2015-05-05 09:44:51 -04002164
2165void SSL_CTX_set_msg_callback_arg(SSL_CTX *ctx, void *arg) {
2166 ctx->msg_callback_arg = arg;
2167}
2168
Adam Langleyfcf25832014-12-18 17:42:32 -08002169void SSL_set_msg_callback(SSL *ssl,
2170 void (*cb)(int write_p, int version, int content_type,
2171 const void *buf, size_t len, SSL *ssl,
2172 void *arg)) {
David Benjamin59015c32015-04-26 13:13:55 -04002173 ssl->msg_callback = cb;
Adam Langleyfcf25832014-12-18 17:42:32 -08002174}
Adam Langley95c29f32014-06-20 12:00:00 -07002175
David Benjamin61ecccf2015-05-05 09:44:51 -04002176void SSL_set_msg_callback_arg(SSL *ssl, void *arg) {
2177 ssl->msg_callback_arg = arg;
2178}
2179
David Benjamind28f59c2015-11-17 22:32:50 -05002180void SSL_CTX_set_keylog_callback(SSL_CTX *ctx,
2181 void (*cb)(const SSL *ssl, const char *line)) {
2182 ctx->keylog_callback = cb;
Adam Langleyfcf25832014-12-18 17:42:32 -08002183}
Adam Langley95c29f32014-06-20 12:00:00 -07002184
Adam Langleyfcf25832014-12-18 17:42:32 -08002185static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) {
2186 static const char hextable[] = "0123456789abcdef";
2187 uint8_t *out;
2188 size_t i;
Adam Langley95c29f32014-06-20 12:00:00 -07002189
Adam Langleyfcf25832014-12-18 17:42:32 -08002190 if (!CBB_add_space(cbb, &out, in_len * 2)) {
2191 return 0;
2192 }
Adam Langley95c29f32014-06-20 12:00:00 -07002193
Adam Langleyfcf25832014-12-18 17:42:32 -08002194 for (i = 0; i < in_len; i++) {
2195 *(out++) = (uint8_t)hextable[in[i] >> 4];
2196 *(out++) = (uint8_t)hextable[in[i] & 0xf];
2197 }
Adam Langley95c29f32014-06-20 12:00:00 -07002198
Adam Langleyfcf25832014-12-18 17:42:32 -08002199 return 1;
2200}
David Benjamin859ec3c2014-09-02 16:29:36 -04002201
David Benjamind28f59c2015-11-17 22:32:50 -05002202int ssl_log_rsa_client_key_exchange(const SSL *ssl,
2203 const uint8_t *encrypted_premaster,
2204 size_t encrypted_premaster_len,
2205 const uint8_t *premaster,
2206 size_t premaster_len) {
2207 if (ssl->ctx->keylog_callback == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002208 return 1;
2209 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002210
Adam Langleyfcf25832014-12-18 17:42:32 -08002211 if (encrypted_premaster_len < 8) {
David Benjamin3570d732015-06-29 00:28:17 -04002212 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
Adam Langleyfcf25832014-12-18 17:42:32 -08002213 return 0;
2214 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002215
David Benjamind28f59c2015-11-17 22:32:50 -05002216 CBB cbb;
2217 uint8_t *out;
2218 size_t out_len;
David Benjamina8653202015-06-28 01:26:10 -04002219 if (!CBB_init(&cbb, 4 + 16 + 1 + premaster_len * 2 + 1) ||
2220 !CBB_add_bytes(&cbb, (const uint8_t *)"RSA ", 4) ||
Adam Langleyfcf25832014-12-18 17:42:32 -08002221 /* Only the first 8 bytes of the encrypted premaster secret are
2222 * logged. */
2223 !cbb_add_hex(&cbb, encrypted_premaster, 8) ||
2224 !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
2225 !cbb_add_hex(&cbb, premaster, premaster_len) ||
David Benjamind28f59c2015-11-17 22:32:50 -05002226 !CBB_add_u8(&cbb, 0 /* NUL */) ||
Adam Langleyfcf25832014-12-18 17:42:32 -08002227 !CBB_finish(&cbb, &out, &out_len)) {
2228 CBB_cleanup(&cbb);
2229 return 0;
2230 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002231
David Benjamind28f59c2015-11-17 22:32:50 -05002232 ssl->ctx->keylog_callback(ssl, (const char *)out);
Adam Langleyfcf25832014-12-18 17:42:32 -08002233 OPENSSL_free(out);
David Benjamind28f59c2015-11-17 22:32:50 -05002234 return 1;
Adam Langley95f22882014-06-20 12:00:00 -07002235}
2236
David Benjamind28f59c2015-11-17 22:32:50 -05002237int ssl_log_master_secret(const SSL *ssl, const uint8_t *client_random,
2238 size_t client_random_len, const uint8_t *master,
2239 size_t master_len) {
2240 if (ssl->ctx->keylog_callback == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002241 return 1;
2242 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002243
Adam Langleyfcf25832014-12-18 17:42:32 -08002244 if (client_random_len != 32) {
David Benjamin3570d732015-06-29 00:28:17 -04002245 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
Adam Langleyfcf25832014-12-18 17:42:32 -08002246 return 0;
2247 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002248
David Benjamind28f59c2015-11-17 22:32:50 -05002249 CBB cbb;
2250 uint8_t *out;
2251 size_t out_len;
David Benjamina8653202015-06-28 01:26:10 -04002252 if (!CBB_init(&cbb, 14 + 64 + 1 + master_len * 2 + 1) ||
2253 !CBB_add_bytes(&cbb, (const uint8_t *)"CLIENT_RANDOM ", 14) ||
Adam Langleyfcf25832014-12-18 17:42:32 -08002254 !cbb_add_hex(&cbb, client_random, 32) ||
2255 !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
2256 !cbb_add_hex(&cbb, master, master_len) ||
David Benjamind28f59c2015-11-17 22:32:50 -05002257 !CBB_add_u8(&cbb, 0 /* NUL */) ||
Adam Langleyfcf25832014-12-18 17:42:32 -08002258 !CBB_finish(&cbb, &out, &out_len)) {
2259 CBB_cleanup(&cbb);
2260 return 0;
2261 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002262
David Benjamind28f59c2015-11-17 22:32:50 -05002263 ssl->ctx->keylog_callback(ssl, (const char *)out);
Adam Langleyfcf25832014-12-18 17:42:32 -08002264 OPENSSL_free(out);
David Benjamind28f59c2015-11-17 22:32:50 -05002265 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -07002266}
2267
David Benjamin5d8b1282015-10-17 23:26:35 -04002268int SSL_is_init_finished(const SSL *ssl) {
2269 return ssl->state == SSL_ST_OK;
2270}
2271
2272int SSL_in_init(const SSL *ssl) {
2273 return (ssl->state & SSL_ST_INIT) != 0;
2274}
2275
2276int SSL_in_false_start(const SSL *ssl) {
2277 return ssl->s3->tmp.in_false_start;
David Benjamined7c4752015-02-16 19:16:46 -05002278}
2279
Adam Langleyfcf25832014-12-18 17:42:32 -08002280int SSL_cutthrough_complete(const SSL *s) {
David Benjamined7c4752015-02-16 19:16:46 -05002281 return SSL_in_false_start(s);
Adam Langleyfcf25832014-12-18 17:42:32 -08002282}
Adam Langley95c29f32014-06-20 12:00:00 -07002283
Adam Langleyfcf25832014-12-18 17:42:32 -08002284void SSL_get_structure_sizes(size_t *ssl_size, size_t *ssl_ctx_size,
2285 size_t *ssl_session_size) {
2286 *ssl_size = sizeof(SSL);
2287 *ssl_ctx_size = sizeof(SSL_CTX);
2288 *ssl_session_size = sizeof(SSL_SESSION);
2289}
Feng Lu41aa3252014-11-21 22:47:56 -08002290
David Benjamined7c4752015-02-16 19:16:46 -05002291int ssl3_can_false_start(const SSL *s) {
David Benjamin195dc782015-02-19 13:27:05 -05002292 const SSL_CIPHER *const cipher = SSL_get_current_cipher(s);
Adam Langleyfcf25832014-12-18 17:42:32 -08002293
Adam Langleye631d962015-04-01 13:11:01 -07002294 /* False Start only for TLS 1.2 with an ECDHE+AEAD cipher and ALPN or NPN. */
David Benjamin195dc782015-02-19 13:27:05 -05002295 return !SSL_IS_DTLS(s) &&
2296 SSL_version(s) >= TLS1_2_VERSION &&
2297 (s->s3->alpn_selected || s->s3->next_proto_neg_seen) &&
2298 cipher != NULL &&
Adam Langleye631d962015-04-01 13:11:01 -07002299 cipher->algorithm_mkey == SSL_kECDHE &&
David Benjamin13414b32015-12-09 23:02:39 -05002300 cipher->algorithm_mac == SSL_AEAD;
Adam Langleyfcf25832014-12-18 17:42:32 -08002301}
2302
2303const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) {
2304 switch (version) {
2305 case SSL3_VERSION:
2306 return &SSLv3_enc_data;
2307
2308 case TLS1_VERSION:
2309 return &TLSv1_enc_data;
2310
David Benjamin9e13e1a2015-03-05 01:56:32 -05002311 case DTLS1_VERSION:
Adam Langleyfcf25832014-12-18 17:42:32 -08002312 case TLS1_1_VERSION:
2313 return &TLSv1_1_enc_data;
2314
David Benjamin9e13e1a2015-03-05 01:56:32 -05002315 case DTLS1_2_VERSION:
Adam Langleyfcf25832014-12-18 17:42:32 -08002316 case TLS1_2_VERSION:
2317 return &TLSv1_2_enc_data;
2318
Adam Langleyfcf25832014-12-18 17:42:32 -08002319 default:
2320 return NULL;
2321 }
2322}
2323
2324uint16_t ssl3_get_max_server_version(const SSL *s) {
2325 uint16_t max_version;
2326
2327 if (SSL_IS_DTLS(s)) {
2328 max_version = (s->max_version != 0) ? s->max_version : DTLS1_2_VERSION;
2329 if (!(s->options & SSL_OP_NO_DTLSv1_2) && DTLS1_2_VERSION >= max_version) {
2330 return DTLS1_2_VERSION;
2331 }
2332 if (!(s->options & SSL_OP_NO_DTLSv1) && DTLS1_VERSION >= max_version) {
2333 return DTLS1_VERSION;
2334 }
2335 return 0;
2336 }
2337
2338 max_version = (s->max_version != 0) ? s->max_version : TLS1_2_VERSION;
2339 if (!(s->options & SSL_OP_NO_TLSv1_2) && TLS1_2_VERSION <= max_version) {
2340 return TLS1_2_VERSION;
2341 }
2342 if (!(s->options & SSL_OP_NO_TLSv1_1) && TLS1_1_VERSION <= max_version) {
2343 return TLS1_1_VERSION;
2344 }
2345 if (!(s->options & SSL_OP_NO_TLSv1) && TLS1_VERSION <= max_version) {
2346 return TLS1_VERSION;
2347 }
2348 if (!(s->options & SSL_OP_NO_SSLv3) && SSL3_VERSION <= max_version) {
2349 return SSL3_VERSION;
2350 }
2351 return 0;
2352}
2353
2354uint16_t ssl3_get_mutual_version(SSL *s, uint16_t client_version) {
2355 uint16_t version = 0;
2356
2357 if (SSL_IS_DTLS(s)) {
2358 /* Clamp client_version to max_version. */
2359 if (s->max_version != 0 && client_version < s->max_version) {
2360 client_version = s->max_version;
2361 }
2362
2363 if (client_version <= DTLS1_2_VERSION && !(s->options & SSL_OP_NO_DTLSv1_2)) {
2364 version = DTLS1_2_VERSION;
2365 } else if (client_version <= DTLS1_VERSION &&
David Benjaminb18f0242015-03-10 18:30:08 -04002366 !(s->options & SSL_OP_NO_DTLSv1)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002367 version = DTLS1_VERSION;
2368 }
2369
2370 /* Check against min_version. */
2371 if (version != 0 && s->min_version != 0 && version > s->min_version) {
2372 return 0;
2373 }
2374 return version;
2375 } else {
2376 /* Clamp client_version to max_version. */
2377 if (s->max_version != 0 && client_version > s->max_version) {
2378 client_version = s->max_version;
2379 }
2380
2381 if (client_version >= TLS1_2_VERSION && !(s->options & SSL_OP_NO_TLSv1_2)) {
2382 version = TLS1_2_VERSION;
2383 } else if (client_version >= TLS1_1_VERSION &&
2384 !(s->options & SSL_OP_NO_TLSv1_1)) {
2385 version = TLS1_1_VERSION;
2386 } else if (client_version >= TLS1_VERSION && !(s->options & SSL_OP_NO_TLSv1)) {
2387 version = TLS1_VERSION;
2388 } else if (client_version >= SSL3_VERSION && !(s->options & SSL_OP_NO_SSLv3)) {
2389 version = SSL3_VERSION;
2390 }
2391
2392 /* Check against min_version. */
2393 if (version != 0 && s->min_version != 0 && version < s->min_version) {
2394 return 0;
2395 }
2396 return version;
2397 }
2398}
2399
2400uint16_t ssl3_get_max_client_version(SSL *s) {
David Benjamin123a8fd2015-04-26 14:16:41 -04002401 uint32_t options = s->options;
Adam Langleyfcf25832014-12-18 17:42:32 -08002402 uint16_t version = 0;
2403
2404 /* OpenSSL's API for controlling versions entails blacklisting individual
2405 * protocols. This has two problems. First, on the client, the protocol can
2406 * only express a contiguous range of versions. Second, a library consumer
2407 * trying to set a maximum version cannot disable protocol versions that get
2408 * added in a future version of the library.
2409 *
2410 * To account for both of these, OpenSSL interprets the client-side bitmask
2411 * as a min/max range by picking the lowest contiguous non-empty range of
2412 * enabled protocols. Note that this means it is impossible to set a maximum
2413 * version of TLS 1.2 in a future-proof way.
2414 *
2415 * By this scheme, the maximum version is the lowest version V such that V is
2416 * enabled and V+1 is disabled or unimplemented. */
2417 if (SSL_IS_DTLS(s)) {
2418 if (!(options & SSL_OP_NO_DTLSv1_2)) {
2419 version = DTLS1_2_VERSION;
2420 }
2421 if (!(options & SSL_OP_NO_DTLSv1) && (options & SSL_OP_NO_DTLSv1_2)) {
2422 version = DTLS1_VERSION;
2423 }
2424 if (s->max_version != 0 && version < s->max_version) {
2425 version = s->max_version;
2426 }
2427 } else {
2428 if (!(options & SSL_OP_NO_TLSv1_2)) {
2429 version = TLS1_2_VERSION;
2430 }
2431 if (!(options & SSL_OP_NO_TLSv1_1) && (options & SSL_OP_NO_TLSv1_2)) {
2432 version = TLS1_1_VERSION;
2433 }
2434 if (!(options & SSL_OP_NO_TLSv1) && (options & SSL_OP_NO_TLSv1_1)) {
2435 version = TLS1_VERSION;
2436 }
2437 if (!(options & SSL_OP_NO_SSLv3) && (options & SSL_OP_NO_TLSv1)) {
2438 version = SSL3_VERSION;
2439 }
2440 if (s->max_version != 0 && version > s->max_version) {
2441 version = s->max_version;
2442 }
2443 }
2444
2445 return version;
2446}
2447
2448int ssl3_is_version_enabled(SSL *s, uint16_t version) {
2449 if (SSL_IS_DTLS(s)) {
2450 if (s->max_version != 0 && version < s->max_version) {
2451 return 0;
2452 }
2453 if (s->min_version != 0 && version > s->min_version) {
2454 return 0;
2455 }
2456
2457 switch (version) {
2458 case DTLS1_VERSION:
2459 return !(s->options & SSL_OP_NO_DTLSv1);
2460
2461 case DTLS1_2_VERSION:
2462 return !(s->options & SSL_OP_NO_DTLSv1_2);
2463
2464 default:
2465 return 0;
2466 }
2467 } else {
2468 if (s->max_version != 0 && version > s->max_version) {
2469 return 0;
2470 }
2471 if (s->min_version != 0 && version < s->min_version) {
2472 return 0;
2473 }
2474
2475 switch (version) {
2476 case SSL3_VERSION:
2477 return !(s->options & SSL_OP_NO_SSLv3);
2478
2479 case TLS1_VERSION:
2480 return !(s->options & SSL_OP_NO_TLSv1);
2481
2482 case TLS1_1_VERSION:
2483 return !(s->options & SSL_OP_NO_TLSv1_1);
2484
2485 case TLS1_2_VERSION:
2486 return !(s->options & SSL_OP_NO_TLSv1_2);
2487
2488 default:
2489 return 0;
2490 }
2491 }
2492}
2493
David Benjaminea72bd02014-12-21 21:27:41 -05002494uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version) {
2495 if (!SSL_IS_DTLS(s)) {
2496 return wire_version;
2497 }
2498
2499 uint16_t tls_version = ~wire_version;
2500 uint16_t version = tls_version + 0x0201;
2501 /* If either component overflowed, clamp it so comparisons still work. */
2502 if ((version >> 8) < (tls_version >> 8)) {
2503 version = 0xff00 | (version & 0xff);
2504 }
2505 if ((version & 0xff) < (tls_version & 0xff)) {
2506 version = (version & 0xff00) | 0xff;
2507 }
2508 /* DTLS 1.0 maps to TLS 1.1, not TLS 1.0. */
2509 if (version == TLS1_VERSION) {
2510 version = TLS1_1_VERSION;
2511 }
2512 return version;
2513}
2514
David Benjamin42fea372015-09-19 01:22:44 -04002515int SSL_cache_hit(SSL *ssl) { return SSL_session_reused(ssl); }
Adam Langleyfcf25832014-12-18 17:42:32 -08002516
David Benjamin42fea372015-09-19 01:22:44 -04002517int SSL_is_server(SSL *ssl) { return ssl->server; }
Adam Langleyfcf25832014-12-18 17:42:32 -08002518
David Benjamind4c2bce2015-10-17 12:28:18 -04002519void SSL_CTX_set_select_certificate_cb(
2520 SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
2521 ctx->select_certificate_cb = cb;
2522}
2523
Adam Langley524e7172015-02-20 16:04:00 -08002524void SSL_CTX_set_dos_protection_cb(
2525 SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
2526 ctx->dos_protection_cb = cb;
2527}
2528
David Benjamin1d5ef3b2015-10-12 19:54:18 -04002529void SSL_set_renegotiate_mode(SSL *ssl, enum ssl_renegotiate_mode_t mode) {
2530 ssl->renegotiate_mode = mode;
2531}
2532
2533void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject) {
2534 SSL_set_renegotiate_mode(
2535 ssl, reject ? ssl_renegotiate_never : ssl_renegotiate_freely);
David Benjaminb16346b2015-04-08 19:16:58 -04002536}
2537
Adam Langley3f92d212015-02-20 15:32:52 -08002538int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
2539 const RC4_KEY **write_key) {
2540 if (ssl->aead_read_ctx == NULL || ssl->aead_write_ctx == NULL) {
2541 return 0;
2542 }
2543
2544 return EVP_AEAD_CTX_get_rc4_state(&ssl->aead_read_ctx->ctx, read_key) &&
2545 EVP_AEAD_CTX_get_rc4_state(&ssl->aead_write_ctx->ctx, write_key);
2546}
David Benjaminda881e92015-04-26 14:45:04 -04002547
Adam Langleyc2d32802015-11-03 18:36:10 -08002548int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv,
2549 const uint8_t **out_write_iv, size_t *out_iv_len) {
2550 if (ssl->aead_read_ctx == NULL || ssl->aead_write_ctx == NULL) {
2551 return 0;
2552 }
2553
2554 size_t write_iv_len;
2555 if (!EVP_AEAD_CTX_get_iv(&ssl->aead_read_ctx->ctx, out_read_iv, out_iv_len) ||
2556 !EVP_AEAD_CTX_get_iv(&ssl->aead_write_ctx->ctx, out_write_iv,
2557 &write_iv_len) ||
2558 *out_iv_len != write_iv_len) {
2559 return 0;
2560 }
2561
2562 return 1;
David Benjamine348ff42015-11-06 17:55:30 -05002563}
David Benjamin6e807652015-11-02 12:02:20 -05002564
2565uint8_t SSL_get_server_key_exchange_hash(const SSL *ssl) {
2566 return ssl->s3->tmp.server_key_exchange_hash;
Adam Langleyc2d32802015-11-03 18:36:10 -08002567}
2568
David Benjamin27bbae42015-09-13 00:54:37 -04002569int SSL_clear(SSL *ssl) {
2570 if (ssl->method == NULL) {
2571 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_METHOD_SPECIFIED);
2572 return 0;
2573 }
2574
2575 if (ssl_clear_bad_session(ssl)) {
2576 SSL_SESSION_free(ssl->session);
2577 ssl->session = NULL;
2578 }
2579
2580 ssl->hit = 0;
2581 ssl->shutdown = 0;
2582
2583 /* SSL_clear may be called before or after the |ssl| is initialized in either
2584 * accept or connect state. In the latter case, SSL_clear should preserve the
2585 * half and reset |ssl->state| accordingly. */
2586 if (ssl->handshake_func != NULL) {
2587 if (ssl->server) {
2588 SSL_set_accept_state(ssl);
2589 } else {
2590 SSL_set_connect_state(ssl);
2591 }
2592 } else {
2593 assert(ssl->state == 0);
2594 }
2595
2596 /* TODO(davidben): Some state on |ssl| is reset both in |SSL_new| and
2597 * |SSL_clear| because it is per-connection state rather than configuration
2598 * state. Per-connection state should be on |ssl->s3| and |ssl->d1| so it is
2599 * naturally reset at the right points between |SSL_new|, |SSL_clear|, and
2600 * |ssl3_new|. */
2601
2602 ssl->rwstate = SSL_NOTHING;
2603
2604 BUF_MEM_free(ssl->init_buf);
2605 ssl->init_buf = NULL;
2606
2607 ssl_clear_cipher_ctx(ssl);
2608
2609 OPENSSL_free(ssl->next_proto_negotiated);
2610 ssl->next_proto_negotiated = NULL;
2611 ssl->next_proto_negotiated_len = 0;
2612
2613 /* The ssl->d1->mtu is simultaneously configuration (preserved across
2614 * clear) and connection-specific state (gets reset).
2615 *
2616 * TODO(davidben): Avoid this. */
2617 unsigned mtu = 0;
2618 if (ssl->d1 != NULL) {
2619 mtu = ssl->d1->mtu;
2620 }
2621
2622 ssl->method->ssl_free(ssl);
2623 if (!ssl->method->ssl_new(ssl)) {
2624 return 0;
2625 }
2626 ssl->enc_method = ssl3_get_enc_method(ssl->version);
2627 assert(ssl->enc_method != NULL);
2628
2629 if (SSL_IS_DTLS(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
2630 ssl->d1->mtu = mtu;
2631 }
2632
2633 ssl->client_version = ssl->version;
2634
2635 return 1;
2636}
2637
David Benjaminda881e92015-04-26 14:45:04 -04002638int SSL_CTX_sess_connect(const SSL_CTX *ctx) { return 0; }
2639int SSL_CTX_sess_connect_good(const SSL_CTX *ctx) { return 0; }
2640int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx) { return 0; }
2641int SSL_CTX_sess_accept(const SSL_CTX *ctx) { return 0; }
2642int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx) { return 0; }
2643int SSL_CTX_sess_accept_good(const SSL_CTX *ctx) { return 0; }
2644int SSL_CTX_sess_hits(const SSL_CTX *ctx) { return 0; }
2645int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx) { return 0; }
2646int SSL_CTX_sess_misses(const SSL_CTX *ctx) { return 0; }
2647int SSL_CTX_sess_timeouts(const SSL_CTX *ctx) { return 0; }
2648int SSL_CTX_sess_cache_full(const SSL_CTX *ctx) { return 0; }
Matt Braithwaite4838d8a2015-08-20 13:20:03 -07002649void ERR_load_SSL_strings(void) {}
David Benjamin27bbae42015-09-13 00:54:37 -04002650void SSL_load_error_strings(void) {}