blob: aaebf329f9a23db37e07c11964dfcf0146101468 [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
277 CRYPTO_new_ex_data(&g_ex_data_class_ssl_ctx, ret, &ret->ex_data);
278
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
288 /* Default is to connect to non-RI servers. When RI is more widely deployed
289 * might change this. */
290 ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
291
292 /* Lock the SSL_CTX to the specified version, for compatibility with legacy
293 * uses of SSL_METHOD. */
294 if (method->version != 0) {
295 SSL_CTX_set_max_version(ret, method->version);
296 SSL_CTX_set_min_version(ret, method->version);
297 }
298
299 return ret;
300
301err:
302 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
303err2:
304 SSL_CTX_free(ret);
305 return NULL;
306}
307
308void SSL_CTX_free(SSL_CTX *ctx) {
309 if (ctx == NULL ||
310 !CRYPTO_refcount_dec_and_test_zero(&ctx->references)) {
311 return;
312 }
313
314 X509_VERIFY_PARAM_free(ctx->param);
315
316 /* Free internal session cache. However: the remove_cb() may reference the
317 * ex_data of SSL_CTX, thus the ex_data store can only be removed after the
318 * sessions were flushed. As the ex_data handling routines might also touch
319 * the session cache, the most secure solution seems to be: empty (flush) the
320 * cache, then free ex_data, then finally free the cache. (See ticket
321 * [openssl.org #212].) */
322 SSL_CTX_flush_sessions(ctx, 0);
323
324 CRYPTO_free_ex_data(&g_ex_data_class_ssl_ctx, ctx, &ctx->ex_data);
325
326 CRYPTO_MUTEX_cleanup(&ctx->lock);
327 lh_SSL_SESSION_free(ctx->sessions);
328 X509_STORE_free(ctx->cert_store);
329 ssl_cipher_preference_list_free(ctx->cipher_list);
330 sk_SSL_CIPHER_free(ctx->cipher_list_by_id);
331 ssl_cipher_preference_list_free(ctx->cipher_list_tls10);
332 ssl_cipher_preference_list_free(ctx->cipher_list_tls11);
333 ssl_cert_free(ctx->cert);
334 sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->client_custom_extensions,
335 SSL_CUSTOM_EXTENSION_free);
336 sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->server_custom_extensions,
337 SSL_CUSTOM_EXTENSION_free);
338 sk_X509_NAME_pop_free(ctx->client_CA, X509_NAME_free);
339 sk_SRTP_PROTECTION_PROFILE_free(ctx->srtp_profiles);
340 OPENSSL_free(ctx->psk_identity_hint);
341 OPENSSL_free(ctx->tlsext_ellipticcurvelist);
342 OPENSSL_free(ctx->alpn_client_proto_list);
343 OPENSSL_free(ctx->ocsp_response);
344 OPENSSL_free(ctx->signed_cert_timestamp_list);
345 EVP_PKEY_free(ctx->tlsext_channel_id_private);
David Benjamin27bbae42015-09-13 00:54:37 -0400346
347 OPENSSL_free(ctx);
Adam Langleyfcf25832014-12-18 17:42:32 -0800348}
Adam Langley95c29f32014-06-20 12:00:00 -0700349
Adam Langleyfcf25832014-12-18 17:42:32 -0800350SSL *SSL_new(SSL_CTX *ctx) {
351 SSL *s;
Adam Langley95c29f32014-06-20 12:00:00 -0700352
Adam Langleyfcf25832014-12-18 17:42:32 -0800353 if (ctx == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400354 OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_CTX);
Adam Langleyfcf25832014-12-18 17:42:32 -0800355 return NULL;
356 }
357 if (ctx->method == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -0400358 OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
Adam Langleyfcf25832014-12-18 17:42:32 -0800359 return NULL;
360 }
Adam Langley95c29f32014-06-20 12:00:00 -0700361
Adam Langleyfcf25832014-12-18 17:42:32 -0800362 s = (SSL *)OPENSSL_malloc(sizeof(SSL));
363 if (s == NULL) {
364 goto err;
365 }
366 memset(s, 0, sizeof(SSL));
Adam Langley95c29f32014-06-20 12:00:00 -0700367
Adam Langleyfcf25832014-12-18 17:42:32 -0800368 s->min_version = ctx->min_version;
369 s->max_version = ctx->max_version;
David Benjamin1eb367c2014-12-12 18:17:51 -0500370
Adam Langleyfcf25832014-12-18 17:42:32 -0800371 s->options = ctx->options;
372 s->mode = ctx->mode;
373 s->max_cert_list = ctx->max_cert_list;
Adam Langley95c29f32014-06-20 12:00:00 -0700374
David Benjamina5a3eeb2015-03-18 20:26:30 -0400375 s->cert = ssl_cert_dup(ctx->cert);
376 if (s->cert == NULL) {
377 goto err;
Adam Langleyfcf25832014-12-18 17:42:32 -0800378 }
Adam Langley95c29f32014-06-20 12:00:00 -0700379
Adam Langleyfcf25832014-12-18 17:42:32 -0800380 s->msg_callback = ctx->msg_callback;
381 s->msg_callback_arg = ctx->msg_callback_arg;
382 s->verify_mode = ctx->verify_mode;
383 s->sid_ctx_length = ctx->sid_ctx_length;
384 assert(s->sid_ctx_length <= sizeof s->sid_ctx);
385 memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx));
386 s->verify_callback = ctx->default_verify_callback;
Adam Langley95c29f32014-06-20 12:00:00 -0700387
Adam Langleyfcf25832014-12-18 17:42:32 -0800388 s->param = X509_VERIFY_PARAM_new();
389 if (!s->param) {
390 goto err;
391 }
392 X509_VERIFY_PARAM_inherit(s->param, ctx->param);
393 s->quiet_shutdown = ctx->quiet_shutdown;
394 s->max_send_fragment = ctx->max_send_fragment;
Adam Langley95c29f32014-06-20 12:00:00 -0700395
Adam Langley0b5e3902015-05-15 13:08:38 -0700396 CRYPTO_refcount_inc(&ctx->references);
Adam Langleyfcf25832014-12-18 17:42:32 -0800397 s->ctx = ctx;
Adam Langley0b5e3902015-05-15 13:08:38 -0700398 CRYPTO_refcount_inc(&ctx->references);
Adam Langleyfcf25832014-12-18 17:42:32 -0800399 s->initial_ctx = ctx;
Adam Langley95c29f32014-06-20 12:00:00 -0700400
Adam Langleyfcf25832014-12-18 17:42:32 -0800401 if (ctx->tlsext_ellipticcurvelist) {
402 s->tlsext_ellipticcurvelist =
403 BUF_memdup(ctx->tlsext_ellipticcurvelist,
404 ctx->tlsext_ellipticcurvelist_length * 2);
405 if (!s->tlsext_ellipticcurvelist) {
406 goto err;
407 }
408 s->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length;
409 }
Adam Langley95c29f32014-06-20 12:00:00 -0700410
Adam Langleyfcf25832014-12-18 17:42:32 -0800411 if (s->ctx->alpn_client_proto_list) {
412 s->alpn_client_proto_list = BUF_memdup(s->ctx->alpn_client_proto_list,
413 s->ctx->alpn_client_proto_list_len);
414 if (s->alpn_client_proto_list == NULL) {
415 goto err;
416 }
417 s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
418 }
Adam Langley95c29f32014-06-20 12:00:00 -0700419
Adam Langleyfcf25832014-12-18 17:42:32 -0800420 s->verify_result = X509_V_OK;
421 s->method = ctx->method;
Adam Langley95c29f32014-06-20 12:00:00 -0700422
Adam Langleyfcf25832014-12-18 17:42:32 -0800423 if (!s->method->ssl_new(s)) {
424 goto err;
425 }
426 s->enc_method = ssl3_get_enc_method(s->version);
427 assert(s->enc_method != NULL);
Adam Langley95c29f32014-06-20 12:00:00 -0700428
David Benjamin62fd1622015-01-11 13:30:01 -0500429 s->rwstate = SSL_NOTHING;
Adam Langley95c29f32014-06-20 12:00:00 -0700430
David Benjamin9f33fc62015-04-15 17:29:53 -0400431 CRYPTO_new_ex_data(&g_ex_data_class_ssl, s, &s->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700432
Adam Langleyfcf25832014-12-18 17:42:32 -0800433 s->psk_identity_hint = NULL;
434 if (ctx->psk_identity_hint) {
435 s->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint);
436 if (s->psk_identity_hint == NULL) {
437 goto err;
438 }
439 }
440 s->psk_client_callback = ctx->psk_client_callback;
441 s->psk_server_callback = ctx->psk_server_callback;
Adam Langley95c29f32014-06-20 12:00:00 -0700442
David Benjamin02ddbfd2015-01-11 13:09:11 -0500443 s->tlsext_channel_id_enabled = ctx->tlsext_channel_id_enabled;
444 if (ctx->tlsext_channel_id_private) {
David Benjamin9a10f8f2015-05-05 22:22:40 -0400445 s->tlsext_channel_id_private =
446 EVP_PKEY_up_ref(ctx->tlsext_channel_id_private);
David Benjamin02ddbfd2015-01-11 13:09:11 -0500447 }
448
Adam Langleyfcf25832014-12-18 17:42:32 -0800449 s->signed_cert_timestamps_enabled = s->ctx->signed_cert_timestamps_enabled;
450 s->ocsp_stapling_enabled = s->ctx->ocsp_stapling_enabled;
HÃ¥vard Molland9169c962014-08-14 14:42:37 +0200451
Adam Langleyfcf25832014-12-18 17:42:32 -0800452 return s;
453
Adam Langley95c29f32014-06-20 12:00:00 -0700454err:
David Benjamin2755a3e2015-04-22 16:17:58 -0400455 SSL_free(s);
David Benjamin3570d732015-06-29 00:28:17 -0400456 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700457
Adam Langleyfcf25832014-12-18 17:42:32 -0800458 return NULL;
459}
Adam Langley95c29f32014-06-20 12:00:00 -0700460
David Benjamin27bbae42015-09-13 00:54:37 -0400461void SSL_free(SSL *ssl) {
462 if (ssl == NULL) {
463 return;
464 }
465
466 X509_VERIFY_PARAM_free(ssl->param);
467
468 CRYPTO_free_ex_data(&g_ex_data_class_ssl, ssl, &ssl->ex_data);
469
470 if (ssl->bbio != NULL) {
471 /* If the buffering BIO is in place, pop it off */
472 if (ssl->bbio == ssl->wbio) {
473 ssl->wbio = BIO_pop(ssl->wbio);
474 }
475 BIO_free(ssl->bbio);
476 ssl->bbio = NULL;
477 }
478
479 int free_wbio = ssl->wbio != ssl->rbio;
480 BIO_free_all(ssl->rbio);
481 if (free_wbio) {
482 BIO_free_all(ssl->wbio);
483 }
484
485 BUF_MEM_free(ssl->init_buf);
486
487 /* add extra stuff */
488 ssl_cipher_preference_list_free(ssl->cipher_list);
489 sk_SSL_CIPHER_free(ssl->cipher_list_by_id);
490
491 ssl_clear_bad_session(ssl);
492 SSL_SESSION_free(ssl->session);
493
494 ssl_clear_cipher_ctx(ssl);
495
496 ssl_cert_free(ssl->cert);
497
498 OPENSSL_free(ssl->tlsext_hostname);
499 SSL_CTX_free(ssl->initial_ctx);
500 OPENSSL_free(ssl->tlsext_ellipticcurvelist);
501 OPENSSL_free(ssl->alpn_client_proto_list);
502 EVP_PKEY_free(ssl->tlsext_channel_id_private);
503 OPENSSL_free(ssl->psk_identity_hint);
504 sk_X509_NAME_pop_free(ssl->client_CA, X509_NAME_free);
505 OPENSSL_free(ssl->next_proto_negotiated);
506 sk_SRTP_PROTECTION_PROFILE_free(ssl->srtp_profiles);
507
508 if (ssl->method != NULL) {
509 ssl->method->ssl_free(ssl);
510 }
511 SSL_CTX_free(ssl->ctx);
512
513 OPENSSL_free(ssl);
514}
515
516void SSL_set_connect_state(SSL *ssl) {
517 ssl->server = 0;
518 ssl->shutdown = 0;
519 ssl->state = SSL_ST_CONNECT;
520 ssl->handshake_func = ssl->method->ssl_connect;
521 /* clear the current cipher */
522 ssl_clear_cipher_ctx(ssl);
523}
524
525void SSL_set_accept_state(SSL *ssl) {
526 ssl->server = 1;
527 ssl->shutdown = 0;
528 ssl->state = SSL_ST_ACCEPT;
529 ssl->handshake_func = ssl->method->ssl_accept;
530 /* clear the current cipher */
531 ssl_clear_cipher_ctx(ssl);
532}
533
534void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) {
535 /* If the output buffering BIO is still in place, remove it. */
536 if (ssl->bbio != NULL) {
537 if (ssl->wbio == ssl->bbio) {
538 ssl->wbio = ssl->wbio->next_bio;
539 ssl->bbio->next_bio = NULL;
540 }
541 }
542
543 if (ssl->rbio != rbio) {
544 BIO_free_all(ssl->rbio);
545 }
546 if (ssl->wbio != wbio && ssl->rbio != ssl->wbio) {
547 BIO_free_all(ssl->wbio);
548 }
549 ssl->rbio = rbio;
550 ssl->wbio = wbio;
551}
552
553BIO *SSL_get_rbio(const SSL *ssl) { return ssl->rbio; }
554
555BIO *SSL_get_wbio(const SSL *ssl) { return ssl->wbio; }
556
557int SSL_do_handshake(SSL *ssl) {
558 if (ssl->handshake_func == NULL) {
559 OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_TYPE_NOT_SET);
560 return -1;
561 }
562
563 if (!SSL_in_init(ssl)) {
564 return 1;
565 }
566
567 return ssl->handshake_func(ssl);
568}
569
570int SSL_connect(SSL *ssl) {
571 if (ssl->handshake_func == 0) {
572 /* Not properly initialized yet */
573 SSL_set_connect_state(ssl);
574 }
575
576 if (ssl->handshake_func != ssl->method->ssl_connect) {
577 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
578 return -1;
579 }
580
581 return ssl->handshake_func(ssl);
582}
583
584int SSL_accept(SSL *ssl) {
585 if (ssl->handshake_func == 0) {
586 /* Not properly initialized yet */
587 SSL_set_accept_state(ssl);
588 }
589
590 if (ssl->handshake_func != ssl->method->ssl_accept) {
591 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
592 return -1;
593 }
594
595 return ssl->handshake_func(ssl);
596}
597
598int SSL_read(SSL *ssl, void *buf, int num) {
599 if (ssl->handshake_func == 0) {
600 OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
601 return -1;
602 }
603
604 if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
605 ssl->rwstate = SSL_NOTHING;
606 return 0;
607 }
608
609 ERR_clear_system_error();
610 return ssl->method->ssl_read_app_data(ssl, buf, num, 0);
611}
612
613int SSL_peek(SSL *ssl, void *buf, int num) {
614 if (ssl->handshake_func == 0) {
615 OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
616 return -1;
617 }
618
619 if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
620 return 0;
621 }
622
623 ERR_clear_system_error();
624 return ssl->method->ssl_read_app_data(ssl, buf, num, 1);
625}
626
627int SSL_write(SSL *ssl, const void *buf, int num) {
628 if (ssl->handshake_func == 0) {
629 OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
630 return -1;
631 }
632
633 if (ssl->shutdown & SSL_SENT_SHUTDOWN) {
634 ssl->rwstate = SSL_NOTHING;
635 OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
636 return -1;
637 }
638
639 ERR_clear_system_error();
640 return ssl->method->ssl_write_app_data(ssl, buf, num);
641}
642
643int SSL_shutdown(SSL *ssl) {
644 /* Note that this function behaves differently from what one might expect.
645 * Return values are 0 for no success (yet), 1 for success; but calling it
646 * once is usually not enough, even if blocking I/O is used (see
647 * ssl3_shutdown). */
648
649 if (ssl->handshake_func == 0) {
650 OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
651 return -1;
652 }
653
654 if (SSL_in_init(ssl)) {
655 return 1;
656 }
657
658 /* Do nothing if configured not to send a close_notify. */
659 if (ssl->quiet_shutdown) {
660 ssl->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
661 return 1;
662 }
663
664 if (!(ssl->shutdown & SSL_SENT_SHUTDOWN)) {
665 ssl->shutdown |= SSL_SENT_SHUTDOWN;
666 ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
667
668 /* our shutdown alert has been sent now, and if it still needs to be
669 * written, ssl->s3->alert_dispatch will be true */
670 if (ssl->s3->alert_dispatch) {
671 return -1; /* return WANT_WRITE */
672 }
673 } else if (ssl->s3->alert_dispatch) {
674 /* resend it if not sent */
675 int ret = ssl->method->ssl_dispatch_alert(ssl);
676 if (ret == -1) {
677 /* we only get to return -1 here the 2nd/Nth invocation, we must have
678 * already signalled return 0 upon a previous invoation, return
679 * WANT_WRITE */
680 return ret;
681 }
682 } else if (!(ssl->shutdown & SSL_RECEIVED_SHUTDOWN)) {
683 /* If we are waiting for a close from our peer, we are closed */
684 ssl->method->ssl_read_close_notify(ssl);
685 if (!(ssl->shutdown & SSL_RECEIVED_SHUTDOWN)) {
686 return -1; /* return WANT_READ */
687 }
688 }
689
690 if (ssl->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN) &&
691 !ssl->s3->alert_dispatch) {
692 return 1;
693 } else {
694 return 0;
695 }
696}
697
698int SSL_get_error(const SSL *ssl, int ret_code) {
699 int reason;
700 uint32_t err;
701 BIO *bio;
702
703 if (ret_code > 0) {
704 return SSL_ERROR_NONE;
705 }
706
707 /* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
708 * where we do encode the error */
709 err = ERR_peek_error();
710 if (err != 0) {
711 if (ERR_GET_LIB(err) == ERR_LIB_SYS) {
712 return SSL_ERROR_SYSCALL;
713 }
714 return SSL_ERROR_SSL;
715 }
716
717 if (ret_code == 0) {
718 if ((ssl->shutdown & SSL_RECEIVED_SHUTDOWN) &&
719 (ssl->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) {
720 /* The socket was cleanly shut down with a close_notify. */
721 return SSL_ERROR_ZERO_RETURN;
722 }
723 /* An EOF was observed which violates the protocol, and the underlying
724 * transport does not participate in the error queue. Bubble up to the
725 * caller. */
726 return SSL_ERROR_SYSCALL;
727 }
728
729 if (SSL_want_session(ssl)) {
730 return SSL_ERROR_PENDING_SESSION;
731 }
732
733 if (SSL_want_certificate(ssl)) {
734 return SSL_ERROR_PENDING_CERTIFICATE;
735 }
736
737 if (SSL_want_read(ssl)) {
738 bio = SSL_get_rbio(ssl);
739 if (BIO_should_read(bio)) {
740 return SSL_ERROR_WANT_READ;
741 }
742
743 if (BIO_should_write(bio)) {
744 /* This one doesn't make too much sense ... We never try to write to the
745 * rbio, and an application program where rbio and wbio are separate
746 * couldn't even know what it should wait for. However if we ever set
747 * s->rwstate incorrectly (so that we have SSL_want_read(s) instead of
748 * SSL_want_write(s)) and rbio and wbio *are* the same, this test works
749 * around that bug; so it might be safer to keep it. */
750 return SSL_ERROR_WANT_WRITE;
751 }
752
753 if (BIO_should_io_special(bio)) {
754 reason = BIO_get_retry_reason(bio);
755 if (reason == BIO_RR_CONNECT) {
756 return SSL_ERROR_WANT_CONNECT;
757 }
758
759 if (reason == BIO_RR_ACCEPT) {
760 return SSL_ERROR_WANT_ACCEPT;
761 }
762
763 return SSL_ERROR_SYSCALL; /* unknown */
764 }
765 }
766
767 if (SSL_want_write(ssl)) {
768 bio = SSL_get_wbio(ssl);
769 if (BIO_should_write(bio)) {
770 return SSL_ERROR_WANT_WRITE;
771 }
772
773 if (BIO_should_read(bio)) {
774 /* See above (SSL_want_read(ssl) with BIO_should_write(bio)) */
775 return SSL_ERROR_WANT_READ;
776 }
777
778 if (BIO_should_io_special(bio)) {
779 reason = BIO_get_retry_reason(bio);
780 if (reason == BIO_RR_CONNECT) {
781 return SSL_ERROR_WANT_CONNECT;
782 }
783
784 if (reason == BIO_RR_ACCEPT) {
785 return SSL_ERROR_WANT_ACCEPT;
786 }
787
788 return SSL_ERROR_SYSCALL;
789 }
790 }
791
792 if (SSL_want_x509_lookup(ssl)) {
793 return SSL_ERROR_WANT_X509_LOOKUP;
794 }
795
796 if (SSL_want_channel_id_lookup(ssl)) {
797 return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP;
798 }
799
800 if (SSL_want_private_key_operation(ssl)) {
801 return SSL_ERROR_WANT_PRIVATE_KEY_OPERATION;
802 }
803
804 return SSL_ERROR_SYSCALL;
805}
806
807void SSL_CTX_set_min_version(SSL_CTX *ctx, uint16_t version) {
808 ctx->min_version = version;
809}
810
811void SSL_CTX_set_max_version(SSL_CTX *ctx, uint16_t version) {
812 ctx->max_version = version;
813}
814
815void SSL_set_min_version(SSL *ssl, uint16_t version) {
816 ssl->min_version = version;
817}
818
819void SSL_set_max_version(SSL *ssl, uint16_t version) {
820 ssl->max_version = version;
821}
822
823uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options) {
824 ctx->options |= options;
825 return ctx->options;
826}
827
828uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options) {
829 ctx->options &= ~options;
830 return ctx->options;
831}
832
833uint32_t SSL_CTX_get_options(const SSL_CTX *ctx) { return ctx->options; }
834
835uint32_t SSL_set_options(SSL *ssl, uint32_t options) {
836 ssl->options |= options;
837 return ssl->options;
838}
839
840uint32_t SSL_clear_options(SSL *ssl, uint32_t options) {
841 ssl->options &= ~options;
842 return ssl->options;
843}
844
845uint32_t SSL_get_options(const SSL *ssl) { return ssl->options; }
846
847uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode) {
848 ctx->mode |= mode;
849 return ctx->mode;
850}
851
852uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode) {
853 ctx->mode &= ~mode;
854 return ctx->mode;
855}
856
857uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx) { return ctx->mode; }
858
859uint32_t SSL_set_mode(SSL *ssl, uint32_t mode) {
860 ssl->mode |= mode;
861 return ssl->mode;
862}
863
864uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode) {
865 ssl->mode &= ~mode;
866 return ssl->mode;
867}
868
869uint32_t SSL_get_mode(const SSL *ssl) { return ssl->mode; }
870
David Benjaminee0c8272015-09-13 01:03:54 -0400871X509 *SSL_get_peer_certificate(const SSL *ssl) {
872 if (ssl == NULL || ssl->session == NULL || ssl->session->peer == NULL) {
873 return NULL;
874 }
875 return X509_up_ref(ssl->session->peer);
876}
877
878STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) {
879 if (ssl == NULL || ssl->session == NULL) {
880 return NULL;
881 }
882 return ssl->session->cert_chain;
883}
884
885int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len,
886 size_t max_out) {
887 /* The tls-unique value is the first Finished message in the handshake, which
888 * is the client's in a full handshake and the server's for a resumption. See
889 * https://tools.ietf.org/html/rfc5929#section-3.1. */
890 const uint8_t *finished = ssl->s3->previous_client_finished;
891 size_t finished_len = ssl->s3->previous_client_finished_len;
892 if (ssl->hit) {
893 /* tls-unique is broken for resumed sessions unless EMS is used. */
894 if (!ssl->session->extended_master_secret) {
895 goto err;
896 }
897 finished = ssl->s3->previous_server_finished;
898 finished_len = ssl->s3->previous_server_finished_len;
899 }
900
901 if (!ssl->s3->initial_handshake_complete ||
902 ssl->version < TLS1_VERSION) {
903 goto err;
904 }
905
906 *out_len = finished_len;
907 if (finished_len > max_out) {
908 *out_len = max_out;
909 }
910
911 memcpy(out, finished, *out_len);
912 return 1;
913
914err:
915 *out_len = 0;
916 memset(out, 0, max_out);
917 return 0;
918}
919
Adam Langleyfcf25832014-12-18 17:42:32 -0800920int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx,
David Benjamindafbdd42015-09-14 01:40:10 -0400921 unsigned sid_ctx_len) {
922 if (sid_ctx_len > sizeof(ctx->sid_ctx)) {
David Benjamin3570d732015-06-29 00:28:17 -0400923 OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
Adam Langleyfcf25832014-12-18 17:42:32 -0800924 return 0;
925 }
926 ctx->sid_ctx_length = sid_ctx_len;
927 memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len);
Adam Langley95c29f32014-06-20 12:00:00 -0700928
Adam Langleyfcf25832014-12-18 17:42:32 -0800929 return 1;
930}
Adam Langley95c29f32014-06-20 12:00:00 -0700931
Adam Langleyfcf25832014-12-18 17:42:32 -0800932int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
David Benjamindafbdd42015-09-14 01:40:10 -0400933 unsigned sid_ctx_len) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800934 if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
David Benjamin3570d732015-06-29 00:28:17 -0400935 OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
Adam Langleyfcf25832014-12-18 17:42:32 -0800936 return 0;
937 }
938 ssl->sid_ctx_length = sid_ctx_len;
939 memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len);
Adam Langley95c29f32014-06-20 12:00:00 -0700940
Adam Langleyfcf25832014-12-18 17:42:32 -0800941 return 1;
942}
Adam Langley95c29f32014-06-20 12:00:00 -0700943
David Benjamin59937042015-09-19 13:04:22 -0400944int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) {
945 return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
Adam Langleyfcf25832014-12-18 17:42:32 -0800946}
947
David Benjamin59937042015-09-19 13:04:22 -0400948int SSL_set_purpose(SSL *ssl, int purpose) {
949 return X509_VERIFY_PARAM_set_purpose(ssl->param, purpose);
Adam Langleyfcf25832014-12-18 17:42:32 -0800950}
951
David Benjamin59937042015-09-19 13:04:22 -0400952int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) {
953 return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
Adam Langleyfcf25832014-12-18 17:42:32 -0800954}
955
David Benjamin59937042015-09-19 13:04:22 -0400956int SSL_set_trust(SSL *ssl, int trust) {
957 return X509_VERIFY_PARAM_set_trust(ssl->param, trust);
Adam Langleyfcf25832014-12-18 17:42:32 -0800958}
959
David Benjamin59937042015-09-19 13:04:22 -0400960int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) {
961 return X509_VERIFY_PARAM_set1(ctx->param, param);
Adam Langleyfcf25832014-12-18 17:42:32 -0800962}
963
David Benjamin59937042015-09-19 13:04:22 -0400964int SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) {
965 return X509_VERIFY_PARAM_set1(ssl->param, param);
Adam Langleyfcf25832014-12-18 17:42:32 -0800966}
Adam Langley95c29f32014-06-20 12:00:00 -0700967
Adam Langley858a88d2014-06-20 12:00:00 -0700968void ssl_cipher_preference_list_free(
Adam Langleyfcf25832014-12-18 17:42:32 -0800969 struct ssl_cipher_preference_list_st *cipher_list) {
David Benjamin5d1ec732015-04-22 13:38:00 -0400970 if (cipher_list == NULL) {
971 return;
972 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800973 sk_SSL_CIPHER_free(cipher_list->ciphers);
974 OPENSSL_free(cipher_list->in_group_flags);
975 OPENSSL_free(cipher_list);
976}
Adam Langley858a88d2014-06-20 12:00:00 -0700977
Adam Langleyfcf25832014-12-18 17:42:32 -0800978struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_dup(
979 struct ssl_cipher_preference_list_st *cipher_list) {
980 struct ssl_cipher_preference_list_st *ret = NULL;
981 size_t n = sk_SSL_CIPHER_num(cipher_list->ciphers);
Adam Langley858a88d2014-06-20 12:00:00 -0700982
Adam Langleyfcf25832014-12-18 17:42:32 -0800983 ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
984 if (!ret) {
985 goto err;
986 }
987
988 ret->ciphers = NULL;
989 ret->in_group_flags = NULL;
990 ret->ciphers = sk_SSL_CIPHER_dup(cipher_list->ciphers);
991 if (!ret->ciphers) {
992 goto err;
993 }
994 ret->in_group_flags = BUF_memdup(cipher_list->in_group_flags, n);
995 if (!ret->in_group_flags) {
996 goto err;
997 }
998
999 return ret;
Adam Langley858a88d2014-06-20 12:00:00 -07001000
1001err:
David Benjamin2755a3e2015-04-22 16:17:58 -04001002 ssl_cipher_preference_list_free(ret);
Adam Langleyfcf25832014-12-18 17:42:32 -08001003 return NULL;
1004}
Adam Langley858a88d2014-06-20 12:00:00 -07001005
Adam Langleyfcf25832014-12-18 17:42:32 -08001006struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_from_ciphers(
David Benjamin60da0cd2015-05-03 15:21:28 -04001007 STACK_OF(SSL_CIPHER) *ciphers) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001008 struct ssl_cipher_preference_list_st *ret = NULL;
1009 size_t n = sk_SSL_CIPHER_num(ciphers);
Adam Langley858a88d2014-06-20 12:00:00 -07001010
Adam Langleyfcf25832014-12-18 17:42:32 -08001011 ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
1012 if (!ret) {
1013 goto err;
1014 }
1015 ret->ciphers = NULL;
1016 ret->in_group_flags = NULL;
1017 ret->ciphers = sk_SSL_CIPHER_dup(ciphers);
1018 if (!ret->ciphers) {
1019 goto err;
1020 }
1021 ret->in_group_flags = OPENSSL_malloc(n);
1022 if (!ret->in_group_flags) {
1023 goto err;
1024 }
1025 memset(ret->in_group_flags, 0, n);
1026 return ret;
Adam Langley858a88d2014-06-20 12:00:00 -07001027
1028err:
David Benjamin2755a3e2015-04-22 16:17:58 -04001029 ssl_cipher_preference_list_free(ret);
Adam Langleyfcf25832014-12-18 17:42:32 -08001030 return NULL;
1031}
Adam Langley858a88d2014-06-20 12:00:00 -07001032
Adam Langleyfcf25832014-12-18 17:42:32 -08001033X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { return ctx->param; }
Adam Langley95c29f32014-06-20 12:00:00 -07001034
Adam Langleyfcf25832014-12-18 17:42:32 -08001035X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { return ssl->param; }
Adam Langley95c29f32014-06-20 12:00:00 -07001036
David Benjamin7481d392015-07-05 19:38:46 -04001037void SSL_certs_clear(SSL *ssl) { ssl_cert_clear_certs(ssl->cert); }
Adam Langley95c29f32014-06-20 12:00:00 -07001038
David Benjamin066fe0a2015-10-17 21:11:33 -04001039int SSL_get_fd(const SSL *ssl) { return SSL_get_rfd(ssl); }
Adam Langley95c29f32014-06-20 12:00:00 -07001040
David Benjamin066fe0a2015-10-17 21:11:33 -04001041int SSL_get_rfd(const SSL *ssl) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001042 int ret = -1;
David Benjamin066fe0a2015-10-17 21:11:33 -04001043 BIO *b = BIO_find_type(SSL_get_rbio(ssl), BIO_TYPE_DESCRIPTOR);
1044 if (b != NULL) {
1045 BIO_get_fd(b, &ret);
Adam Langleyfcf25832014-12-18 17:42:32 -08001046 }
1047 return ret;
1048}
Adam Langley95c29f32014-06-20 12:00:00 -07001049
David Benjamin066fe0a2015-10-17 21:11:33 -04001050int SSL_get_wfd(const SSL *ssl) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001051 int ret = -1;
David Benjamin066fe0a2015-10-17 21:11:33 -04001052 BIO *b = BIO_find_type(SSL_get_wbio(ssl), BIO_TYPE_DESCRIPTOR);
1053 if (b != NULL) {
1054 BIO_get_fd(b, &ret);
Adam Langleyfcf25832014-12-18 17:42:32 -08001055 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001056 return ret;
1057}
Adam Langley95c29f32014-06-20 12:00:00 -07001058
David Benjamin066fe0a2015-10-17 21:11:33 -04001059int SSL_set_fd(SSL *ssl, int fd) {
1060 BIO *bio = BIO_new(BIO_s_fd());
Adam Langleyfcf25832014-12-18 17:42:32 -08001061 if (bio == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001062 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
David Benjamin066fe0a2015-10-17 21:11:33 -04001063 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001064 }
1065 BIO_set_fd(bio, fd, BIO_NOCLOSE);
David Benjamin066fe0a2015-10-17 21:11:33 -04001066 SSL_set_bio(ssl, bio, bio);
1067 return 1;
Adam Langleyfcf25832014-12-18 17:42:32 -08001068}
Adam Langley95c29f32014-06-20 12:00:00 -07001069
David Benjamin066fe0a2015-10-17 21:11:33 -04001070int SSL_set_wfd(SSL *ssl, int fd) {
1071 if (ssl->rbio == NULL ||
1072 BIO_method_type(ssl->rbio) != BIO_TYPE_FD ||
1073 BIO_get_fd(ssl->rbio, NULL) != fd) {
1074 BIO *bio = BIO_new(BIO_s_fd());
Adam Langleyfcf25832014-12-18 17:42:32 -08001075 if (bio == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001076 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
David Benjamin066fe0a2015-10-17 21:11:33 -04001077 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001078 }
1079 BIO_set_fd(bio, fd, BIO_NOCLOSE);
David Benjamin066fe0a2015-10-17 21:11:33 -04001080 SSL_set_bio(ssl, SSL_get_rbio(ssl), bio);
Adam Langleyfcf25832014-12-18 17:42:32 -08001081 } else {
David Benjamin066fe0a2015-10-17 21:11:33 -04001082 SSL_set_bio(ssl, SSL_get_rbio(ssl), SSL_get_rbio(ssl));
Adam Langleyfcf25832014-12-18 17:42:32 -08001083 }
1084
David Benjamin066fe0a2015-10-17 21:11:33 -04001085 return 1;
Adam Langleyfcf25832014-12-18 17:42:32 -08001086}
Adam Langley95c29f32014-06-20 12:00:00 -07001087
David Benjamin066fe0a2015-10-17 21:11:33 -04001088int SSL_set_rfd(SSL *ssl, int fd) {
1089 if (ssl->wbio == NULL || BIO_method_type(ssl->wbio) != BIO_TYPE_FD ||
1090 BIO_get_fd(ssl->wbio, NULL) != fd) {
1091 BIO *bio = BIO_new(BIO_s_fd());
Adam Langleyfcf25832014-12-18 17:42:32 -08001092 if (bio == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001093 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
David Benjamin066fe0a2015-10-17 21:11:33 -04001094 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001095 }
1096 BIO_set_fd(bio, fd, BIO_NOCLOSE);
David Benjamin066fe0a2015-10-17 21:11:33 -04001097 SSL_set_bio(ssl, bio, SSL_get_wbio(ssl));
Adam Langleyfcf25832014-12-18 17:42:32 -08001098 } else {
David Benjamin066fe0a2015-10-17 21:11:33 -04001099 SSL_set_bio(ssl, SSL_get_wbio(ssl), SSL_get_wbio(ssl));
Adam Langleyfcf25832014-12-18 17:42:32 -08001100 }
David Benjamin066fe0a2015-10-17 21:11:33 -04001101 return 1;
Adam Langleyfcf25832014-12-18 17:42:32 -08001102}
Adam Langley95c29f32014-06-20 12:00:00 -07001103
David Benjamin1a1b34d2015-10-17 12:51:52 -04001104size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001105 size_t ret = 0;
1106
David Benjamin1a1b34d2015-10-17 12:51:52 -04001107 if (ssl->s3 != NULL) {
1108 ret = ssl->s3->tmp.finish_md_len;
Adam Langleyfcf25832014-12-18 17:42:32 -08001109 if (count > ret) {
1110 count = ret;
1111 }
David Benjamin1a1b34d2015-10-17 12:51:52 -04001112 memcpy(buf, ssl->s3->tmp.finish_md, count);
Adam Langleyfcf25832014-12-18 17:42:32 -08001113 }
1114
1115 return ret;
1116}
Adam Langley95c29f32014-06-20 12:00:00 -07001117
David Benjamin1a1b34d2015-10-17 12:51:52 -04001118size_t SSL_get_peer_finished(const SSL *ssl, void *buf, size_t count) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001119 size_t ret = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001120
David Benjamin1a1b34d2015-10-17 12:51:52 -04001121 if (ssl->s3 != NULL) {
1122 ret = ssl->s3->tmp.peer_finish_md_len;
Adam Langleyfcf25832014-12-18 17:42:32 -08001123 if (count > ret) {
1124 count = ret;
1125 }
David Benjamin1a1b34d2015-10-17 12:51:52 -04001126 memcpy(buf, ssl->s3->tmp.peer_finish_md, count);
Adam Langleyfcf25832014-12-18 17:42:32 -08001127 }
Adam Langley95c29f32014-06-20 12:00:00 -07001128
Adam Langleyfcf25832014-12-18 17:42:32 -08001129 return ret;
1130}
Adam Langley95c29f32014-06-20 12:00:00 -07001131
David Benjamin59937042015-09-19 13:04:22 -04001132int SSL_get_verify_mode(const SSL *ssl) { return ssl->verify_mode; }
Adam Langley95c29f32014-06-20 12:00:00 -07001133
David Benjamin59937042015-09-19 13:04:22 -04001134int SSL_get_verify_depth(const SSL *ssl) {
1135 return X509_VERIFY_PARAM_get_depth(ssl->param);
Adam Langleyfcf25832014-12-18 17:42:32 -08001136}
Adam Langley95c29f32014-06-20 12:00:00 -07001137
David Benjamin42fea372015-09-19 01:22:44 -04001138int SSL_get_extms_support(const SSL *ssl) {
1139 return ssl->s3->tmp.extended_master_secret == 1;
Matt Braithwaitecd6f54b2015-09-17 12:54:42 -07001140}
1141
David Benjamin59937042015-09-19 13:04:22 -04001142int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) {
1143 return ssl->verify_callback;
Adam Langleyfcf25832014-12-18 17:42:32 -08001144}
Adam Langley95c29f32014-06-20 12:00:00 -07001145
Adam Langleyfcf25832014-12-18 17:42:32 -08001146int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { return ctx->verify_mode; }
Adam Langley95c29f32014-06-20 12:00:00 -07001147
Adam Langleyfcf25832014-12-18 17:42:32 -08001148int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) {
1149 return X509_VERIFY_PARAM_get_depth(ctx->param);
1150}
Adam Langley95c29f32014-06-20 12:00:00 -07001151
David Benjamin59937042015-09-19 13:04:22 -04001152int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
1153 int ok, X509_STORE_CTX *store_ctx) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001154 return ctx->default_verify_callback;
1155}
Adam Langley95c29f32014-06-20 12:00:00 -07001156
David Benjamin59937042015-09-19 13:04:22 -04001157void SSL_set_verify(SSL *ssl, int mode,
1158 int (*callback)(int ok, X509_STORE_CTX *store_ctx)) {
1159 ssl->verify_mode = mode;
Adam Langleyfcf25832014-12-18 17:42:32 -08001160 if (callback != NULL) {
David Benjamin59937042015-09-19 13:04:22 -04001161 ssl->verify_callback = callback;
Adam Langleyfcf25832014-12-18 17:42:32 -08001162 }
1163}
Adam Langley95c29f32014-06-20 12:00:00 -07001164
David Benjamin59937042015-09-19 13:04:22 -04001165void SSL_set_verify_depth(SSL *ssl, int depth) {
1166 X509_VERIFY_PARAM_set_depth(ssl->param, depth);
Adam Langleyfcf25832014-12-18 17:42:32 -08001167}
Adam Langley95c29f32014-06-20 12:00:00 -07001168
David Benjamin9a41d1b2015-05-16 01:30:09 -04001169int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; }
Adam Langley95c29f32014-06-20 12:00:00 -07001170
David Benjamin9a41d1b2015-05-16 01:30:09 -04001171int SSL_get_read_ahead(const SSL *s) { return 0; }
Adam Langley95c29f32014-06-20 12:00:00 -07001172
David Benjamin9a41d1b2015-05-16 01:30:09 -04001173void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { }
David Benjamin61ecccf2015-05-05 09:44:51 -04001174
David Benjamin9a41d1b2015-05-16 01:30:09 -04001175void SSL_set_read_ahead(SSL *s, int yes) { }
David Benjamin61ecccf2015-05-05 09:44:51 -04001176
David Benjamin9f859492015-10-03 10:44:30 -04001177int SSL_pending(const SSL *ssl) {
1178 if (ssl->s3->rrec.type != SSL3_RT_APPLICATION_DATA) {
1179 return 0;
1180 }
1181 return ssl->s3->rrec.length;
Adam Langleyfcf25832014-12-18 17:42:32 -08001182}
Adam Langley95c29f32014-06-20 12:00:00 -07001183
Adam Langley95c29f32014-06-20 12:00:00 -07001184/* Fix this so it checks all the valid key/cert options */
Adam Langleyfcf25832014-12-18 17:42:32 -08001185int SSL_CTX_check_private_key(const SSL_CTX *ctx) {
David Benjamin651b3d92015-08-09 12:07:25 -04001186 if (ctx->cert->x509 == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001187 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
Adam Langleyfcf25832014-12-18 17:42:32 -08001188 return 0;
1189 }
1190
David Benjamind1d80782015-07-05 11:54:09 -04001191 if (ctx->cert->privatekey == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001192 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
Adam Langleyfcf25832014-12-18 17:42:32 -08001193 return 0;
1194 }
1195
David Benjamind1d80782015-07-05 11:54:09 -04001196 return X509_check_private_key(ctx->cert->x509, ctx->cert->privatekey);
Adam Langleyfcf25832014-12-18 17:42:32 -08001197}
Adam Langley95c29f32014-06-20 12:00:00 -07001198
1199/* Fix this function so that it takes an optional type parameter */
Adam Langleyfcf25832014-12-18 17:42:32 -08001200int SSL_check_private_key(const SSL *ssl) {
David Benjamind1d80782015-07-05 11:54:09 -04001201 if (ssl->cert->x509 == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001202 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
Adam Langleyfcf25832014-12-18 17:42:32 -08001203 return 0;
1204 }
David Benjamin0b145c22014-11-26 20:10:09 -05001205
David Benjamind1d80782015-07-05 11:54:09 -04001206 if (ssl->cert->privatekey == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001207 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
Adam Langleyfcf25832014-12-18 17:42:32 -08001208 return 0;
1209 }
Adam Langley95c29f32014-06-20 12:00:00 -07001210
David Benjamind1d80782015-07-05 11:54:09 -04001211 return X509_check_private_key(ssl->cert->x509, ssl->cert->privatekey);
Adam Langleyfcf25832014-12-18 17:42:32 -08001212}
Adam Langley95c29f32014-06-20 12:00:00 -07001213
David Benjamin42fea372015-09-19 01:22:44 -04001214long SSL_get_default_timeout(const SSL *ssl) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001215 return SSL_DEFAULT_SESSION_TIMEOUT;
1216}
Adam Langley95c29f32014-06-20 12:00:00 -07001217
David Benjamin44d3eed2015-05-21 01:29:55 -04001218int SSL_renegotiate(SSL *ssl) {
1219 /* Caller-initiated renegotiation is not supported. */
David Benjamin3570d732015-06-29 00:28:17 -04001220 OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
David Benjamin44d3eed2015-05-21 01:29:55 -04001221 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001222}
Adam Langley95c29f32014-06-20 12:00:00 -07001223
David Benjamin44d3eed2015-05-21 01:29:55 -04001224int SSL_renegotiate_pending(SSL *ssl) {
1225 return SSL_in_init(ssl) && ssl->s3->initial_handshake_complete;
Adam Langleyfcf25832014-12-18 17:42:32 -08001226}
Adam Langley95c29f32014-06-20 12:00:00 -07001227
David Benjamin1d0a1942015-04-26 15:35:35 -04001228size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx) {
1229 return ctx->max_cert_list;
1230}
1231
1232void SSL_CTX_set_max_cert_list(SSL_CTX *ctx, size_t max_cert_list) {
1233 if (max_cert_list > kMaxHandshakeSize) {
1234 max_cert_list = kMaxHandshakeSize;
1235 }
1236 ctx->max_cert_list = (uint32_t)max_cert_list;
1237}
1238
1239size_t SSL_get_max_cert_list(const SSL *ssl) {
1240 return ssl->max_cert_list;
1241}
1242
1243void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list) {
1244 if (max_cert_list > kMaxHandshakeSize) {
1245 max_cert_list = kMaxHandshakeSize;
1246 }
1247 ssl->max_cert_list = (uint32_t)max_cert_list;
1248}
1249
1250void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, size_t max_send_fragment) {
1251 if (max_send_fragment < 512) {
1252 max_send_fragment = 512;
1253 }
1254 if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
1255 max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
1256 }
1257 ctx->max_send_fragment = (uint16_t)max_send_fragment;
1258}
1259
1260void SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment) {
1261 if (max_send_fragment < 512) {
1262 max_send_fragment = 512;
1263 }
1264 if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
1265 max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
1266 }
1267 ssl->max_send_fragment = (uint16_t)max_send_fragment;
1268}
1269
David Benjamincb9cf792015-05-05 09:46:14 -04001270int SSL_set_mtu(SSL *ssl, unsigned mtu) {
1271 if (!SSL_IS_DTLS(ssl) || mtu < dtls1_min_mtu()) {
1272 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001273 }
David Benjamincb9cf792015-05-05 09:46:14 -04001274 ssl->d1->mtu = mtu;
1275 return 1;
1276}
1277
1278int SSL_get_secure_renegotiation_support(const SSL *ssl) {
1279 return ssl->s3->send_connection_binding;
1280}
1281
Adam Langleyfcf25832014-12-18 17:42:32 -08001282LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) { return ctx->sessions; }
1283
David Benjamin71f7d3d2015-05-05 09:46:38 -04001284size_t SSL_CTX_sess_number(const SSL_CTX *ctx) {
1285 return lh_SSL_SESSION_num_items(ctx->sessions);
1286}
1287
1288unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx, unsigned long size) {
1289 unsigned long ret = ctx->session_cache_size;
1290 ctx->session_cache_size = size;
1291 return ret;
1292}
1293
1294unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx) {
1295 return ctx->session_cache_size;
1296}
1297
1298int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode) {
1299 int ret = ctx->session_cache_mode;
1300 ctx->session_cache_mode = mode;
1301 return ret;
1302}
1303
1304int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx) {
1305 return ctx->session_cache_mode;
1306}
1307
David Benjamin32876b32015-09-20 12:17:03 -04001308STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl) {
1309 if (ssl == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001310 return NULL;
1311 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001312
David Benjamin32876b32015-09-20 12:17:03 -04001313 if (ssl->cipher_list != NULL) {
1314 return ssl->cipher_list->ciphers;
Adam Langleyfcf25832014-12-18 17:42:32 -08001315 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001316
David Benjamin32876b32015-09-20 12:17:03 -04001317 if (ssl->version >= TLS1_1_VERSION && ssl->ctx != NULL &&
1318 ssl->ctx->cipher_list_tls11 != NULL) {
1319 return ssl->ctx->cipher_list_tls11->ciphers;
Adam Langleyfcf25832014-12-18 17:42:32 -08001320 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001321
David Benjamin32876b32015-09-20 12:17:03 -04001322 if (ssl->version >= TLS1_VERSION && ssl->ctx != NULL &&
1323 ssl->ctx->cipher_list_tls10 != NULL) {
1324 return ssl->ctx->cipher_list_tls10->ciphers;
Adam Langleycef75832015-09-03 14:51:12 -07001325 }
1326
David Benjamin32876b32015-09-20 12:17:03 -04001327 if (ssl->ctx != NULL && ssl->ctx->cipher_list != NULL) {
1328 return ssl->ctx->cipher_list->ciphers;
Adam Langleyfcf25832014-12-18 17:42:32 -08001329 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001330
Adam Langleyfcf25832014-12-18 17:42:32 -08001331 return NULL;
1332}
Adam Langley95c29f32014-06-20 12:00:00 -07001333
Adam Langleyfcf25832014-12-18 17:42:32 -08001334/* return a STACK of the ciphers available for the SSL and in order of
Adam Langley95c29f32014-06-20 12:00:00 -07001335 * algorithm id */
David Benjamin60da0cd2015-05-03 15:21:28 -04001336STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001337 if (s == NULL) {
1338 return NULL;
1339 }
Adam Langley95c29f32014-06-20 12:00:00 -07001340
Adam Langleyfcf25832014-12-18 17:42:32 -08001341 if (s->cipher_list_by_id != NULL) {
1342 return s->cipher_list_by_id;
1343 }
Adam Langley95c29f32014-06-20 12:00:00 -07001344
Adam Langleyfcf25832014-12-18 17:42:32 -08001345 if (s->ctx != NULL && s->ctx->cipher_list_by_id != NULL) {
1346 return s->ctx->cipher_list_by_id;
1347 }
Adam Langley95c29f32014-06-20 12:00:00 -07001348
Adam Langleyfcf25832014-12-18 17:42:32 -08001349 return NULL;
1350}
Adam Langley95c29f32014-06-20 12:00:00 -07001351
David Benjamin32876b32015-09-20 12:17:03 -04001352const char *SSL_get_cipher_list(const SSL *ssl, int n) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001353 const SSL_CIPHER *c;
David Benjamin60da0cd2015-05-03 15:21:28 -04001354 STACK_OF(SSL_CIPHER) *sk;
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001355
David Benjamin32876b32015-09-20 12:17:03 -04001356 if (ssl == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001357 return NULL;
1358 }
Adam Langley95c29f32014-06-20 12:00:00 -07001359
David Benjamin32876b32015-09-20 12:17:03 -04001360 sk = SSL_get_ciphers(ssl);
Adam Langleyfcf25832014-12-18 17:42:32 -08001361 if (sk == NULL || n < 0 || (size_t)n >= sk_SSL_CIPHER_num(sk)) {
1362 return NULL;
1363 }
Adam Langley95c29f32014-06-20 12:00:00 -07001364
Adam Langleyfcf25832014-12-18 17:42:32 -08001365 c = sk_SSL_CIPHER_value(sk, n);
1366 if (c == NULL) {
1367 return NULL;
1368 }
Adam Langley95c29f32014-06-20 12:00:00 -07001369
Adam Langleyfcf25832014-12-18 17:42:32 -08001370 return c->name;
1371}
David Benjamin5491e3f2014-09-29 19:33:09 -04001372
Adam Langleyfcf25832014-12-18 17:42:32 -08001373int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) {
David Benjamin32876b32015-09-20 12:17:03 -04001374 STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
1375 ctx->method, &ctx->cipher_list, &ctx->cipher_list_by_id, str);
1376 if (cipher_list == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001377 return 0;
David Benjamin32876b32015-09-20 12:17:03 -04001378 }
1379
1380 /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
1381 if (sk_SSL_CIPHER_num(cipher_list) == 0) {
David Benjamin3570d732015-06-29 00:28:17 -04001382 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
Adam Langleyfcf25832014-12-18 17:42:32 -08001383 return 0;
1384 }
Adam Langley95c29f32014-06-20 12:00:00 -07001385
Adam Langleyfcf25832014-12-18 17:42:32 -08001386 return 1;
1387}
David Benjamin39482a12014-07-20 13:30:15 -04001388
Adam Langleycef75832015-09-03 14:51:12 -07001389int SSL_CTX_set_cipher_list_tls10(SSL_CTX *ctx, const char *str) {
David Benjamin32876b32015-09-20 12:17:03 -04001390 STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
1391 ctx->method, &ctx->cipher_list_tls10, NULL, str);
1392 if (cipher_list == NULL) {
Adam Langleycef75832015-09-03 14:51:12 -07001393 return 0;
David Benjamin32876b32015-09-20 12:17:03 -04001394 }
1395
1396 /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
1397 if (sk_SSL_CIPHER_num(cipher_list) == 0) {
Adam Langleycef75832015-09-03 14:51:12 -07001398 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
1399 return 0;
1400 }
1401
1402 return 1;
1403}
1404
Adam Langleyfcf25832014-12-18 17:42:32 -08001405int SSL_CTX_set_cipher_list_tls11(SSL_CTX *ctx, const char *str) {
David Benjamin32876b32015-09-20 12:17:03 -04001406 STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
1407 ctx->method, &ctx->cipher_list_tls11, NULL, str);
1408 if (cipher_list == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001409 return 0;
David Benjamin32876b32015-09-20 12:17:03 -04001410 }
1411
1412 /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
1413 if (sk_SSL_CIPHER_num(cipher_list) == 0) {
David Benjamin3570d732015-06-29 00:28:17 -04001414 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
Adam Langleyfcf25832014-12-18 17:42:32 -08001415 return 0;
1416 }
David Benjamin9f2c0d72014-10-21 22:00:19 -04001417
Adam Langleyfcf25832014-12-18 17:42:32 -08001418 return 1;
1419}
Adam Langley95c29f32014-06-20 12:00:00 -07001420
David Benjamin32876b32015-09-20 12:17:03 -04001421int SSL_set_cipher_list(SSL *ssl, const char *str) {
1422 STACK_OF(SSL_CIPHER) *cipher_list = ssl_create_cipher_list(
1423 ssl->ctx->method, &ssl->cipher_list, &ssl->cipher_list_by_id, str);
1424 if (cipher_list == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001425 return 0;
David Benjamin32876b32015-09-20 12:17:03 -04001426 }
1427
1428 /* |ssl_create_cipher_list| may succeed but return an empty cipher list. */
1429 if (sk_SSL_CIPHER_num(cipher_list) == 0) {
David Benjamin3570d732015-06-29 00:28:17 -04001430 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
Adam Langleyfcf25832014-12-18 17:42:32 -08001431 return 0;
1432 }
David Benjamin39482a12014-07-20 13:30:15 -04001433
Adam Langleyfcf25832014-12-18 17:42:32 -08001434 return 1;
1435}
Adam Langley95c29f32014-06-20 12:00:00 -07001436
Adam Langleyfcf25832014-12-18 17:42:32 -08001437STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
1438 CBS cipher_suites = *cbs;
1439 const SSL_CIPHER *c;
David Benjamin60da0cd2015-05-03 15:21:28 -04001440 STACK_OF(SSL_CIPHER) *sk;
Adam Langleyfcf25832014-12-18 17:42:32 -08001441
1442 if (s->s3) {
1443 s->s3->send_connection_binding = 0;
1444 }
1445
1446 if (CBS_len(&cipher_suites) % 2 != 0) {
David Benjamin3570d732015-06-29 00:28:17 -04001447 OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
Adam Langleyfcf25832014-12-18 17:42:32 -08001448 return NULL;
1449 }
1450
1451 sk = sk_SSL_CIPHER_new_null();
1452 if (sk == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001453 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
Adam Langleyfcf25832014-12-18 17:42:32 -08001454 goto err;
1455 }
1456
Adam Langleyfcf25832014-12-18 17:42:32 -08001457 while (CBS_len(&cipher_suites) > 0) {
1458 uint16_t cipher_suite;
1459
1460 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
David Benjamin3570d732015-06-29 00:28:17 -04001461 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
Adam Langleyfcf25832014-12-18 17:42:32 -08001462 goto err;
1463 }
1464
1465 /* Check for SCSV. */
1466 if (s->s3 && cipher_suite == (SSL3_CK_SCSV & 0xffff)) {
1467 /* SCSV is fatal if renegotiating. */
David Benjamin20f6e972015-05-15 21:51:49 -04001468 if (s->s3->initial_handshake_complete) {
David Benjamin3570d732015-06-29 00:28:17 -04001469 OPENSSL_PUT_ERROR(SSL, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
Adam Langleyfcf25832014-12-18 17:42:32 -08001470 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
1471 goto err;
1472 }
1473 s->s3->send_connection_binding = 1;
1474 continue;
1475 }
1476
1477 /* Check for FALLBACK_SCSV. */
1478 if (s->s3 && cipher_suite == (SSL3_CK_FALLBACK_SCSV & 0xffff)) {
1479 uint16_t max_version = ssl3_get_max_server_version(s);
1480 if (SSL_IS_DTLS(s) ? (uint16_t)s->version > max_version
1481 : (uint16_t)s->version < max_version) {
David Benjamin3570d732015-06-29 00:28:17 -04001482 OPENSSL_PUT_ERROR(SSL, SSL_R_INAPPROPRIATE_FALLBACK);
Adam Langleyfcf25832014-12-18 17:42:32 -08001483 ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_INAPPROPRIATE_FALLBACK);
1484 goto err;
1485 }
1486 continue;
1487 }
1488
David Benjamina1c90a52015-05-30 17:03:14 -04001489 c = SSL_get_cipher_by_value(cipher_suite);
Adam Langleyfcf25832014-12-18 17:42:32 -08001490 if (c != NULL && !sk_SSL_CIPHER_push(sk, c)) {
David Benjamin3570d732015-06-29 00:28:17 -04001491 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
Adam Langleyfcf25832014-12-18 17:42:32 -08001492 goto err;
1493 }
1494 }
1495
1496 return sk;
David Benjamin9f2c0d72014-10-21 22:00:19 -04001497
Adam Langley95c29f32014-06-20 12:00:00 -07001498err:
David Benjamin2755a3e2015-04-22 16:17:58 -04001499 sk_SSL_CIPHER_free(sk);
Adam Langleyfcf25832014-12-18 17:42:32 -08001500 return NULL;
1501}
Adam Langley95c29f32014-06-20 12:00:00 -07001502
David Benjamin07e13842015-10-17 13:48:04 -04001503const char *SSL_get_servername(const SSL *ssl, const int type) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001504 if (type != TLSEXT_NAMETYPE_host_name) {
1505 return NULL;
1506 }
Adam Langley95c29f32014-06-20 12:00:00 -07001507
David Benjamin07e13842015-10-17 13:48:04 -04001508 /* Historically, |SSL_get_servername| was also the configuration getter
1509 * corresponding to |SSL_set_tlsext_host_name|. */
1510 if (ssl->tlsext_hostname != NULL) {
1511 return ssl->tlsext_hostname;
1512 }
1513
1514 if (ssl->session == NULL) {
1515 return NULL;
1516 }
1517 return ssl->session->tlsext_hostname;
Adam Langleyfcf25832014-12-18 17:42:32 -08001518}
Adam Langley95c29f32014-06-20 12:00:00 -07001519
David Benjamin07e13842015-10-17 13:48:04 -04001520int SSL_get_servername_type(const SSL *ssl) {
1521 if (ssl->session != NULL && ssl->session->tlsext_hostname != NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001522 return TLSEXT_NAMETYPE_host_name;
1523 }
Adam Langley95c29f32014-06-20 12:00:00 -07001524
Adam Langleyfcf25832014-12-18 17:42:32 -08001525 return -1;
1526}
Adam Langley95c29f32014-06-20 12:00:00 -07001527
Adam Langleyfcf25832014-12-18 17:42:32 -08001528void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx) {
1529 ctx->signed_cert_timestamps_enabled = 1;
1530}
HÃ¥vard Molland9169c962014-08-14 14:42:37 +02001531
Adam Langleyfcf25832014-12-18 17:42:32 -08001532int SSL_enable_signed_cert_timestamps(SSL *ssl) {
1533 ssl->signed_cert_timestamps_enabled = 1;
1534 return 1;
1535}
HÃ¥vard Molland9169c962014-08-14 14:42:37 +02001536
Adam Langleyfcf25832014-12-18 17:42:32 -08001537void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx) {
1538 ctx->ocsp_stapling_enabled = 1;
1539}
David Benjamin6c7aed02014-08-27 16:42:38 -04001540
Adam Langleyfcf25832014-12-18 17:42:32 -08001541int SSL_enable_ocsp_stapling(SSL *ssl) {
1542 ssl->ocsp_stapling_enabled = 1;
1543 return 1;
1544}
David Benjamin6c7aed02014-08-27 16:42:38 -04001545
Adam Langleyfcf25832014-12-18 17:42:32 -08001546void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out,
1547 size_t *out_len) {
1548 SSL_SESSION *session = ssl->session;
Adam Langley3cb50e02014-08-26 14:00:31 -07001549
Adam Langleyfcf25832014-12-18 17:42:32 -08001550 *out_len = 0;
1551 *out = NULL;
1552 if (ssl->server || !session || !session->tlsext_signed_cert_timestamp_list) {
1553 return;
1554 }
HÃ¥vard Molland9169c962014-08-14 14:42:37 +02001555
Adam Langleyfcf25832014-12-18 17:42:32 -08001556 *out = session->tlsext_signed_cert_timestamp_list;
1557 *out_len = session->tlsext_signed_cert_timestamp_list_length;
1558}
David Benjamin6c7aed02014-08-27 16:42:38 -04001559
Adam Langleyfcf25832014-12-18 17:42:32 -08001560void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
1561 size_t *out_len) {
1562 SSL_SESSION *session = ssl->session;
1563
1564 *out_len = 0;
1565 *out = NULL;
1566 if (ssl->server || !session || !session->ocsp_response) {
1567 return;
1568 }
1569 *out = session->ocsp_response;
1570 *out_len = session->ocsp_response_length;
1571}
David Benjamin6c7aed02014-08-27 16:42:38 -04001572
Paul Lietar4fac72e2015-09-09 13:44:55 +01001573int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list,
1574 size_t list_len) {
1575 OPENSSL_free(ctx->signed_cert_timestamp_list);
1576 ctx->signed_cert_timestamp_list_length = 0;
1577
1578 ctx->signed_cert_timestamp_list = BUF_memdup(list, list_len);
1579 if (ctx->signed_cert_timestamp_list == NULL) {
1580 return 0;
1581 }
1582 ctx->signed_cert_timestamp_list_length = list_len;
1583
1584 return 1;
1585}
1586
Paul Lietaraeeff2c2015-08-12 11:47:11 +01001587int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response,
1588 size_t response_len) {
1589 OPENSSL_free(ctx->ocsp_response);
1590 ctx->ocsp_response_length = 0;
1591
1592 ctx->ocsp_response = BUF_memdup(response, response_len);
1593 if (ctx->ocsp_response == NULL) {
1594 return 0;
1595 }
1596 ctx->ocsp_response_length = response_len;
1597
1598 return 1;
1599}
1600
David Benjamin977547b2015-09-16 00:25:52 -04001601int SSL_select_next_proto(uint8_t **out, uint8_t *out_len,
1602 const uint8_t *server, unsigned server_len,
1603 const uint8_t *client, unsigned client_len) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001604 unsigned int i, j;
1605 const uint8_t *result;
1606 int status = OPENSSL_NPN_UNSUPPORTED;
Adam Langley95c29f32014-06-20 12:00:00 -07001607
Adam Langleyfcf25832014-12-18 17:42:32 -08001608 /* For each protocol in server preference order, see if we support it. */
1609 for (i = 0; i < server_len;) {
1610 for (j = 0; j < client_len;) {
1611 if (server[i] == client[j] &&
1612 memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) {
1613 /* We found a match */
1614 result = &server[i];
1615 status = OPENSSL_NPN_NEGOTIATED;
1616 goto found;
1617 }
1618 j += client[j];
1619 j++;
1620 }
1621 i += server[i];
1622 i++;
1623 }
Adam Langley95c29f32014-06-20 12:00:00 -07001624
Adam Langleyfcf25832014-12-18 17:42:32 -08001625 /* There's no overlap between our protocols and the server's list. */
1626 result = client;
1627 status = OPENSSL_NPN_NO_OVERLAP;
Adam Langley95c29f32014-06-20 12:00:00 -07001628
Adam Langleyfcf25832014-12-18 17:42:32 -08001629found:
1630 *out = (uint8_t *)result + 1;
David Benjamin977547b2015-09-16 00:25:52 -04001631 *out_len = result[0];
Adam Langleyfcf25832014-12-18 17:42:32 -08001632 return status;
1633}
Adam Langley95c29f32014-06-20 12:00:00 -07001634
David Benjamin977547b2015-09-16 00:25:52 -04001635void SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data,
1636 unsigned *out_len) {
1637 *out_data = ssl->next_proto_negotiated;
1638 if (*out_data == NULL) {
1639 *out_len = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001640 } else {
David Benjamin977547b2015-09-16 00:25:52 -04001641 *out_len = ssl->next_proto_negotiated_len;
Adam Langleyfcf25832014-12-18 17:42:32 -08001642 }
Adam Langley95c29f32014-06-20 12:00:00 -07001643}
1644
Adam Langleyfcf25832014-12-18 17:42:32 -08001645void SSL_CTX_set_next_protos_advertised_cb(
1646 SSL_CTX *ctx,
David Benjamin977547b2015-09-16 00:25:52 -04001647 int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg),
Adam Langleyfcf25832014-12-18 17:42:32 -08001648 void *arg) {
1649 ctx->next_protos_advertised_cb = cb;
1650 ctx->next_protos_advertised_cb_arg = arg;
1651}
Adam Langley95c29f32014-06-20 12:00:00 -07001652
Adam Langleyfcf25832014-12-18 17:42:32 -08001653void SSL_CTX_set_next_proto_select_cb(
David Benjamin977547b2015-09-16 00:25:52 -04001654 SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len,
1655 const uint8_t *in, unsigned in_len, void *arg),
Adam Langleyfcf25832014-12-18 17:42:32 -08001656 void *arg) {
1657 ctx->next_proto_select_cb = cb;
1658 ctx->next_proto_select_cb_arg = arg;
1659}
Adam Langley95c29f32014-06-20 12:00:00 -07001660
Adam Langleyfcf25832014-12-18 17:42:32 -08001661int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos,
1662 unsigned protos_len) {
David Benjamin2755a3e2015-04-22 16:17:58 -04001663 OPENSSL_free(ctx->alpn_client_proto_list);
Adam Langleyfcf25832014-12-18 17:42:32 -08001664 ctx->alpn_client_proto_list = BUF_memdup(protos, protos_len);
1665 if (!ctx->alpn_client_proto_list) {
1666 return 1;
1667 }
1668 ctx->alpn_client_proto_list_len = protos_len;
Adam Langley95c29f32014-06-20 12:00:00 -07001669
Adam Langleyfcf25832014-12-18 17:42:32 -08001670 return 0;
1671}
Adam Langley95c29f32014-06-20 12:00:00 -07001672
Adam Langleyfcf25832014-12-18 17:42:32 -08001673int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) {
David Benjamin2755a3e2015-04-22 16:17:58 -04001674 OPENSSL_free(ssl->alpn_client_proto_list);
Adam Langleyfcf25832014-12-18 17:42:32 -08001675 ssl->alpn_client_proto_list = BUF_memdup(protos, protos_len);
1676 if (!ssl->alpn_client_proto_list) {
1677 return 1;
1678 }
1679 ssl->alpn_client_proto_list_len = protos_len;
Adam Langley95c29f32014-06-20 12:00:00 -07001680
Adam Langleyfcf25832014-12-18 17:42:32 -08001681 return 0;
1682}
Adam Langley95c29f32014-06-20 12:00:00 -07001683
Adam Langleyfcf25832014-12-18 17:42:32 -08001684void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
1685 int (*cb)(SSL *ssl, const uint8_t **out,
David Benjamin8984f1f2015-09-16 00:10:19 -04001686 uint8_t *out_len, const uint8_t *in,
1687 unsigned in_len, void *arg),
Adam Langleyfcf25832014-12-18 17:42:32 -08001688 void *arg) {
1689 ctx->alpn_select_cb = cb;
1690 ctx->alpn_select_cb_arg = arg;
1691}
Adam Langley95c29f32014-06-20 12:00:00 -07001692
David Benjamin8984f1f2015-09-16 00:10:19 -04001693void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data,
1694 unsigned *out_len) {
1695 *out_data = NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -08001696 if (ssl->s3) {
David Benjamin8984f1f2015-09-16 00:10:19 -04001697 *out_data = ssl->s3->alpn_selected;
Adam Langleyfcf25832014-12-18 17:42:32 -08001698 }
David Benjamin8984f1f2015-09-16 00:10:19 -04001699 if (*out_data == NULL) {
1700 *out_len = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001701 } else {
David Benjamin8984f1f2015-09-16 00:10:19 -04001702 *out_len = ssl->s3->alpn_selected_len;
Adam Langleyfcf25832014-12-18 17:42:32 -08001703 }
1704}
Adam Langley95c29f32014-06-20 12:00:00 -07001705
David Benjamin07e13842015-10-17 13:48:04 -04001706int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
David Benjamincfd248b2015-04-03 11:02:24 -04001707 const char *label, size_t label_len,
1708 const uint8_t *context, size_t context_len,
1709 int use_context) {
David Benjamin07e13842015-10-17 13:48:04 -04001710 if (ssl->version < TLS1_VERSION) {
David Benjaminc565ebb2015-04-03 04:06:36 -04001711 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001712 }
Adam Langley95c29f32014-06-20 12:00:00 -07001713
David Benjamin07e13842015-10-17 13:48:04 -04001714 return ssl->enc_method->export_keying_material(
1715 ssl, out, out_len, label, label_len, context, context_len, use_context);
Adam Langleyfcf25832014-12-18 17:42:32 -08001716}
Adam Langley95c29f32014-06-20 12:00:00 -07001717
Adam Langleyfcf25832014-12-18 17:42:32 -08001718void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
David Benjamin59937042015-09-19 13:04:22 -04001719 int (*cb)(X509_STORE_CTX *store_ctx,
1720 void *arg),
Adam Langleyfcf25832014-12-18 17:42:32 -08001721 void *arg) {
1722 ctx->app_verify_callback = cb;
1723 ctx->app_verify_arg = arg;
1724}
Adam Langley95c29f32014-06-20 12:00:00 -07001725
Adam Langleyfcf25832014-12-18 17:42:32 -08001726void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
1727 int (*cb)(int, X509_STORE_CTX *)) {
1728 ctx->verify_mode = mode;
1729 ctx->default_verify_callback = cb;
1730}
Adam Langley95c29f32014-06-20 12:00:00 -07001731
Adam Langleyfcf25832014-12-18 17:42:32 -08001732void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) {
1733 X509_VERIFY_PARAM_set_depth(ctx->param, depth);
1734}
Adam Langley1258b6a2014-06-20 12:00:00 -07001735
David Benjamin7481d392015-07-05 19:38:46 -04001736void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg),
Adam Langleyfcf25832014-12-18 17:42:32 -08001737 void *arg) {
David Benjamin7481d392015-07-05 19:38:46 -04001738 ssl_cert_set_cert_cb(ctx->cert, cb, arg);
Adam Langleyfcf25832014-12-18 17:42:32 -08001739}
David Benjamin859ec3c2014-09-02 16:29:36 -04001740
David Benjamin7481d392015-07-05 19:38:46 -04001741void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) {
1742 ssl_cert_set_cert_cb(ssl->cert, cb, arg);
Adam Langleyfcf25832014-12-18 17:42:32 -08001743}
Adam Langley95c29f32014-06-20 12:00:00 -07001744
David Benjamin107db582015-04-08 00:41:59 -04001745void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k,
1746 uint32_t *out_mask_a) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001747 CERT *c = s->cert;
David Benjamind1d80782015-07-05 11:54:09 -04001748 int have_rsa_cert = 0, dh_tmp;
David Benjamin107db582015-04-08 00:41:59 -04001749 uint32_t mask_k, mask_a;
David Benjamind1d80782015-07-05 11:54:09 -04001750 int have_ecc_cert = 0, ecdsa_ok;
Adam Langleyfcf25832014-12-18 17:42:32 -08001751 X509 *x;
Adam Langley95c29f32014-06-20 12:00:00 -07001752
Adam Langleyfcf25832014-12-18 17:42:32 -08001753 dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
Adam Langley95c29f32014-06-20 12:00:00 -07001754
nagendra modadugu601448a2015-07-24 09:31:31 -07001755 if (s->cert->x509 != NULL && ssl_has_private_key(s)) {
1756 if (ssl_private_key_type(s) == EVP_PKEY_RSA) {
David Benjamind1d80782015-07-05 11:54:09 -04001757 have_rsa_cert = 1;
nagendra modadugu601448a2015-07-24 09:31:31 -07001758 } else if (ssl_private_key_type(s) == EVP_PKEY_EC) {
David Benjamind1d80782015-07-05 11:54:09 -04001759 have_ecc_cert = 1;
1760 }
1761 }
nagendra modadugu601448a2015-07-24 09:31:31 -07001762
Adam Langleyfcf25832014-12-18 17:42:32 -08001763 mask_k = 0;
1764 mask_a = 0;
David Benjaminf31e6812014-11-13 18:05:55 -05001765
Adam Langleyfcf25832014-12-18 17:42:32 -08001766 if (dh_tmp) {
David Benjamin7061e282015-03-19 11:10:48 -04001767 mask_k |= SSL_kDHE;
Adam Langleyfcf25832014-12-18 17:42:32 -08001768 }
David Benjaminbb20f522015-07-04 17:18:14 -04001769 if (have_rsa_cert) {
1770 mask_k |= SSL_kRSA;
Adam Langleyfcf25832014-12-18 17:42:32 -08001771 mask_a |= SSL_aRSA;
1772 }
Adam Langley95c29f32014-06-20 12:00:00 -07001773
Adam Langleyfcf25832014-12-18 17:42:32 -08001774 /* An ECC certificate may be usable for ECDSA cipher suites depending on the
1775 * key usage extension and on the client's curve preferences. */
1776 if (have_ecc_cert) {
David Benjamind1d80782015-07-05 11:54:09 -04001777 x = c->x509;
Adam Langleyfcf25832014-12-18 17:42:32 -08001778 /* This call populates extension flags (ex_flags). */
1779 X509_check_purpose(x, -1, 0);
1780 ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE)
1781 ? (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)
1782 : 1;
1783 if (!tls1_check_ec_cert(s, x)) {
1784 ecdsa_ok = 0;
1785 }
1786 if (ecdsa_ok) {
1787 mask_a |= SSL_aECDSA;
1788 }
1789 }
Adam Langley95c29f32014-06-20 12:00:00 -07001790
Adam Langleyfcf25832014-12-18 17:42:32 -08001791 /* If we are considering an ECC cipher suite that uses an ephemeral EC
1792 * key, check it. */
David Benjamindd978782015-04-24 15:20:13 -04001793 if (tls1_check_ec_tmp_key(s)) {
David Benjamin7061e282015-03-19 11:10:48 -04001794 mask_k |= SSL_kECDHE;
Adam Langleyfcf25832014-12-18 17:42:32 -08001795 }
Adam Langley95c29f32014-06-20 12:00:00 -07001796
Adam Langleyfcf25832014-12-18 17:42:32 -08001797 /* PSK requires a server callback. */
1798 if (s->psk_server_callback != NULL) {
1799 mask_k |= SSL_kPSK;
1800 mask_a |= SSL_aPSK;
1801 }
Adam Langley95c29f32014-06-20 12:00:00 -07001802
Adam Langleyfcf25832014-12-18 17:42:32 -08001803 *out_mask_k = mask_k;
1804 *out_mask_a = mask_a;
1805}
Adam Langley95c29f32014-06-20 12:00:00 -07001806
David Benjamin1269ddd2015-10-18 15:18:55 -04001807void ssl_update_cache(SSL *ssl, int mode) {
1808 SSL_CTX *ctx = ssl->initial_ctx;
David Benjaminb6d0c6d2015-03-19 19:07:26 -04001809 /* Never cache sessions with empty session IDs. */
David Benjamin1269ddd2015-10-18 15:18:55 -04001810 if (ssl->session->session_id_length == 0 ||
1811 (ctx->session_cache_mode & mode) != mode) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001812 return;
1813 }
Adam Langley95c29f32014-06-20 12:00:00 -07001814
David Benjamin1269ddd2015-10-18 15:18:55 -04001815 /* Clients never use the internal session cache. */
1816 int use_internal_cache = ssl->server && !(ctx->session_cache_mode &
1817 SSL_SESS_CACHE_NO_INTERNAL_STORE);
David Benjamin95d31822015-06-15 19:53:32 -04001818
David Benjamin1269ddd2015-10-18 15:18:55 -04001819 /* A client may see new sessions on abbreviated handshakes if the server
1820 * decides to renew the ticket. Once the handshake is completed, it should be
1821 * inserted into the cache. */
1822 if (!ssl->hit || (!ssl->server && ssl->tlsext_ticket_expected)) {
1823 if (use_internal_cache) {
1824 SSL_CTX_add_session(ctx, ssl->session);
1825 }
1826 if (ctx->new_session_cb != NULL &&
1827 !ctx->new_session_cb(ssl, SSL_SESSION_up_ref(ssl->session))) {
1828 /* |new_session_cb|'s return value signals whether it took ownership. */
1829 SSL_SESSION_free(ssl->session);
Adam Langleyfcf25832014-12-18 17:42:32 -08001830 }
1831 }
Adam Langley95c29f32014-06-20 12:00:00 -07001832
David Benjamin1269ddd2015-10-18 15:18:55 -04001833 if (use_internal_cache &&
1834 !(ctx->session_cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR)) {
David Benjaminb6d0c6d2015-03-19 19:07:26 -04001835 /* Automatically flush the internal session cache every 255 connections. */
1836 int flush_cache = 0;
Adam Langley4bdb6e42015-05-15 15:29:21 -07001837 CRYPTO_MUTEX_lock_write(&ctx->lock);
David Benjaminb6d0c6d2015-03-19 19:07:26 -04001838 ctx->handshakes_since_cache_flush++;
1839 if (ctx->handshakes_since_cache_flush >= 255) {
1840 flush_cache = 1;
1841 ctx->handshakes_since_cache_flush = 0;
1842 }
Adam Langley4bdb6e42015-05-15 15:29:21 -07001843 CRYPTO_MUTEX_unlock(&ctx->lock);
David Benjaminb6d0c6d2015-03-19 19:07:26 -04001844
1845 if (flush_cache) {
1846 SSL_CTX_flush_sessions(ctx, (unsigned long)time(NULL));
Adam Langleyfcf25832014-12-18 17:42:32 -08001847 }
1848 }
1849}
Adam Langley95c29f32014-06-20 12:00:00 -07001850
Adam Langleyfcf25832014-12-18 17:42:32 -08001851static const char *ssl_get_version(int version) {
1852 switch (version) {
1853 case TLS1_2_VERSION:
1854 return "TLSv1.2";
Adam Langley95c29f32014-06-20 12:00:00 -07001855
Adam Langleyfcf25832014-12-18 17:42:32 -08001856 case TLS1_1_VERSION:
1857 return "TLSv1.1";
Adam Langley95c29f32014-06-20 12:00:00 -07001858
Adam Langleyfcf25832014-12-18 17:42:32 -08001859 case TLS1_VERSION:
1860 return "TLSv1";
Adam Langley95c29f32014-06-20 12:00:00 -07001861
Adam Langleyfcf25832014-12-18 17:42:32 -08001862 case SSL3_VERSION:
1863 return "SSLv3";
Adam Langley95c29f32014-06-20 12:00:00 -07001864
David Benjamin1c722b72015-04-20 13:53:10 -04001865 case DTLS1_VERSION:
1866 return "DTLSv1";
1867
1868 case DTLS1_2_VERSION:
1869 return "DTLSv1.2";
1870
Adam Langleyfcf25832014-12-18 17:42:32 -08001871 default:
1872 return "unknown";
1873 }
1874}
Adam Langley95c29f32014-06-20 12:00:00 -07001875
David Benjamin42fea372015-09-19 01:22:44 -04001876const char *SSL_get_version(const SSL *ssl) {
1877 return ssl_get_version(ssl->version);
Adam Langleyfcf25832014-12-18 17:42:32 -08001878}
Adam Langley95c29f32014-06-20 12:00:00 -07001879
David Benjamina6b8cdf2015-09-13 14:07:33 -04001880const char *SSL_SESSION_get_version(const SSL_SESSION *session) {
1881 return ssl_get_version(session->ssl_version);
Adam Langleyfcf25832014-12-18 17:42:32 -08001882}
Adam Langley95c29f32014-06-20 12:00:00 -07001883
Sigbjorn Vik2b23d242015-06-29 15:07:26 +02001884const char* SSL_get_curve_name(uint16_t curve_id) {
1885 return tls1_ec_curve_id2name(curve_id);
1886}
1887
Adam Langleyfcf25832014-12-18 17:42:32 -08001888void ssl_clear_cipher_ctx(SSL *s) {
David Benjamin31a07792015-03-03 14:20:26 -05001889 SSL_AEAD_CTX_free(s->aead_read_ctx);
1890 s->aead_read_ctx = NULL;
1891 SSL_AEAD_CTX_free(s->aead_write_ctx);
1892 s->aead_write_ctx = NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -08001893}
Adam Langley95c29f32014-06-20 12:00:00 -07001894
Adam Langleyfcf25832014-12-18 17:42:32 -08001895X509 *SSL_get_certificate(const SSL *s) {
1896 if (s->cert != NULL) {
David Benjamind1d80782015-07-05 11:54:09 -04001897 return s->cert->x509;
Adam Langleyfcf25832014-12-18 17:42:32 -08001898 }
1899
1900 return NULL;
1901}
1902
1903EVP_PKEY *SSL_get_privatekey(const SSL *s) {
1904 if (s->cert != NULL) {
David Benjamind1d80782015-07-05 11:54:09 -04001905 return s->cert->privatekey;
Adam Langleyfcf25832014-12-18 17:42:32 -08001906 }
1907
1908 return NULL;
1909}
1910
1911X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
1912 if (ctx->cert != NULL) {
David Benjamind1d80782015-07-05 11:54:09 -04001913 return ctx->cert->x509;
Adam Langleyfcf25832014-12-18 17:42:32 -08001914 }
1915
1916 return NULL;
1917}
1918
1919EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) {
1920 if (ctx->cert != NULL) {
David Benjamind1d80782015-07-05 11:54:09 -04001921 return ctx->cert->privatekey;
Adam Langleyfcf25832014-12-18 17:42:32 -08001922 }
1923
1924 return NULL;
1925}
1926
David Benjamin42fea372015-09-19 01:22:44 -04001927const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl) {
1928 if (ssl->aead_write_ctx == NULL) {
David Benjamina07c0fc2015-05-13 13:19:42 -04001929 return NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -08001930 }
David Benjamin42fea372015-09-19 01:22:44 -04001931 return ssl->aead_write_ctx->cipher;
Adam Langleyfcf25832014-12-18 17:42:32 -08001932}
1933
Matt Braithwaite6a1275b2015-06-26 12:09:10 -07001934const COMP_METHOD *SSL_get_current_compression(SSL *s) { return NULL; }
Adam Langleyfcf25832014-12-18 17:42:32 -08001935
Matt Braithwaite6a1275b2015-06-26 12:09:10 -07001936const COMP_METHOD *SSL_get_current_expansion(SSL *s) { return NULL; }
Adam Langleyfcf25832014-12-18 17:42:32 -08001937
1938int ssl_init_wbio_buffer(SSL *s, int push) {
1939 BIO *bbio;
1940
1941 if (s->bbio == NULL) {
1942 bbio = BIO_new(BIO_f_buffer());
1943 if (bbio == NULL) {
1944 return 0;
1945 }
1946 s->bbio = bbio;
1947 } else {
1948 bbio = s->bbio;
1949 if (s->bbio == s->wbio) {
1950 s->wbio = BIO_pop(s->wbio);
1951 }
1952 }
1953
1954 BIO_reset(bbio);
1955 if (!BIO_set_read_buffer_size(bbio, 1)) {
David Benjamin3570d732015-06-29 00:28:17 -04001956 OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
Adam Langleyfcf25832014-12-18 17:42:32 -08001957 return 0;
1958 }
1959
1960 if (push) {
1961 if (s->wbio != bbio) {
1962 s->wbio = BIO_push(bbio, s->wbio);
1963 }
1964 } else {
1965 if (s->wbio == bbio) {
1966 s->wbio = BIO_pop(bbio);
1967 }
1968 }
1969
1970 return 1;
1971}
1972
1973void ssl_free_wbio_buffer(SSL *s) {
1974 if (s->bbio == NULL) {
1975 return;
1976 }
1977
1978 if (s->bbio == s->wbio) {
1979 /* remove buffering */
1980 s->wbio = BIO_pop(s->wbio);
1981 }
1982
1983 BIO_free(s->bbio);
1984 s->bbio = NULL;
1985}
1986
1987void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) {
Adam Langleybb85f3d2015-10-28 18:44:11 -07001988 ctx->quiet_shutdown = (mode != 0);
Adam Langleyfcf25832014-12-18 17:42:32 -08001989}
1990
1991int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) {
1992 return ctx->quiet_shutdown;
1993}
1994
Adam Langleybb85f3d2015-10-28 18:44:11 -07001995void SSL_set_quiet_shutdown(SSL *ssl, int mode) {
1996 ssl->quiet_shutdown = (mode != 0);
1997}
Adam Langleyfcf25832014-12-18 17:42:32 -08001998
David Benjamin9f859492015-10-03 10:44:30 -04001999int SSL_get_quiet_shutdown(const SSL *ssl) { return ssl->quiet_shutdown; }
Adam Langleyfcf25832014-12-18 17:42:32 -08002000
David Benjamin63006a92015-10-18 00:00:06 -04002001void SSL_set_shutdown(SSL *ssl, int mode) {
2002 /* It is an error to clear any bits that have already been set. (We can't try
2003 * to get a second close_notify or send two.) */
Piotr Sikora7063b6d2015-10-29 02:47:40 -07002004 assert((ssl->shutdown & mode) == ssl->shutdown);
David Benjamin63006a92015-10-18 00:00:06 -04002005
2006 ssl->shutdown |= mode;
2007}
Adam Langleyfcf25832014-12-18 17:42:32 -08002008
David Benjamin9f859492015-10-03 10:44:30 -04002009int SSL_get_shutdown(const SSL *ssl) { return ssl->shutdown; }
Adam Langleyfcf25832014-12-18 17:42:32 -08002010
David Benjamin9f859492015-10-03 10:44:30 -04002011int SSL_version(const SSL *ssl) { return ssl->version; }
Adam Langleyfcf25832014-12-18 17:42:32 -08002012
2013SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return ssl->ctx; }
2014
2015SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) {
2016 if (ssl->ctx == ctx) {
2017 return ssl->ctx;
2018 }
2019
2020 if (ctx == NULL) {
2021 ctx = ssl->initial_ctx;
2022 }
2023
David Benjamin2755a3e2015-04-22 16:17:58 -04002024 ssl_cert_free(ssl->cert);
Adam Langleyfcf25832014-12-18 17:42:32 -08002025 ssl->cert = ssl_cert_dup(ctx->cert);
David Benjamin2755a3e2015-04-22 16:17:58 -04002026
Adam Langley0b5e3902015-05-15 13:08:38 -07002027 CRYPTO_refcount_inc(&ctx->references);
David Benjamin2755a3e2015-04-22 16:17:58 -04002028 SSL_CTX_free(ssl->ctx); /* decrement reference count */
Adam Langleyfcf25832014-12-18 17:42:32 -08002029 ssl->ctx = ctx;
2030
2031 ssl->sid_ctx_length = ctx->sid_ctx_length;
2032 assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx));
2033 memcpy(ssl->sid_ctx, ctx->sid_ctx, sizeof(ssl->sid_ctx));
2034
2035 return ssl->ctx;
2036}
2037
2038int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) {
2039 return X509_STORE_set_default_paths(ctx->cert_store);
2040}
Adam Langley95c29f32014-06-20 12:00:00 -07002041
David Benjamin59937042015-09-19 13:04:22 -04002042int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file,
2043 const char *ca_dir) {
2044 return X509_STORE_load_locations(ctx->cert_store, ca_file, ca_dir);
Adam Langleyfcf25832014-12-18 17:42:32 -08002045}
Adam Langley95c29f32014-06-20 12:00:00 -07002046
2047void SSL_set_info_callback(SSL *ssl,
David Benjamin82170242015-10-17 22:51:17 -04002048 void (*cb)(const SSL *ssl, int type, int value)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002049 ssl->info_callback = cb;
2050}
Adam Langley95c29f32014-06-20 12:00:00 -07002051
David Benjamin82170242015-10-17 22:51:17 -04002052void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, int type,
2053 int value) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002054 return ssl->info_callback;
2055}
Adam Langley95c29f32014-06-20 12:00:00 -07002056
Adam Langleyfcf25832014-12-18 17:42:32 -08002057int SSL_state(const SSL *ssl) { return ssl->state; }
Adam Langley95c29f32014-06-20 12:00:00 -07002058
David Benjaminece089c2015-05-15 23:52:42 -04002059void SSL_set_state(SSL *ssl, int state) { }
Adam Langley95c29f32014-06-20 12:00:00 -07002060
David Benjamin59937042015-09-19 13:04:22 -04002061void SSL_set_verify_result(SSL *ssl, long result) {
2062 ssl->verify_result = result;
2063}
Adam Langley95c29f32014-06-20 12:00:00 -07002064
Adam Langleyfcf25832014-12-18 17:42:32 -08002065long SSL_get_verify_result(const SSL *ssl) { return ssl->verify_result; }
Adam Langley95c29f32014-06-20 12:00:00 -07002066
Adam Langleyfcf25832014-12-18 17:42:32 -08002067int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
2068 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
David Benjamin9f33fc62015-04-15 17:29:53 -04002069 int index;
2070 if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl, &index, argl, argp,
2071 new_func, dup_func, free_func)) {
2072 return -1;
2073 }
2074 return index;
Adam Langleyfcf25832014-12-18 17:42:32 -08002075}
Adam Langley95c29f32014-06-20 12:00:00 -07002076
David Benjamin1ac08fe2015-09-15 01:36:22 -04002077int SSL_set_ex_data(SSL *ssl, int idx, void *arg) {
2078 return CRYPTO_set_ex_data(&ssl->ex_data, idx, arg);
Adam Langleyfcf25832014-12-18 17:42:32 -08002079}
Adam Langley95c29f32014-06-20 12:00:00 -07002080
David Benjamin1ac08fe2015-09-15 01:36:22 -04002081void *SSL_get_ex_data(const SSL *ssl, int idx) {
2082 return CRYPTO_get_ex_data(&ssl->ex_data, idx);
Adam Langleyfcf25832014-12-18 17:42:32 -08002083}
Adam Langley95c29f32014-06-20 12:00:00 -07002084
Adam Langleyfcf25832014-12-18 17:42:32 -08002085int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
2086 CRYPTO_EX_dup *dup_func,
2087 CRYPTO_EX_free *free_func) {
David Benjamin9f33fc62015-04-15 17:29:53 -04002088 int index;
2089 if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl_ctx, &index, argl, argp,
2090 new_func, dup_func, free_func)) {
2091 return -1;
2092 }
2093 return index;
Adam Langleyfcf25832014-12-18 17:42:32 -08002094}
Adam Langley95c29f32014-06-20 12:00:00 -07002095
David Benjamin1ac08fe2015-09-15 01:36:22 -04002096int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *arg) {
2097 return CRYPTO_set_ex_data(&ctx->ex_data, idx, arg);
Adam Langleyfcf25832014-12-18 17:42:32 -08002098}
Adam Langley95c29f32014-06-20 12:00:00 -07002099
David Benjamin1ac08fe2015-09-15 01:36:22 -04002100void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) {
2101 return CRYPTO_get_ex_data(&ctx->ex_data, idx);
Adam Langleyfcf25832014-12-18 17:42:32 -08002102}
Adam Langley95c29f32014-06-20 12:00:00 -07002103
Adam Langleyfcf25832014-12-18 17:42:32 -08002104X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
2105 return ctx->cert_store;
2106}
Adam Langley95c29f32014-06-20 12:00:00 -07002107
Adam Langleyfcf25832014-12-18 17:42:32 -08002108void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) {
David Benjamin2755a3e2015-04-22 16:17:58 -04002109 X509_STORE_free(ctx->cert_store);
Adam Langleyfcf25832014-12-18 17:42:32 -08002110 ctx->cert_store = store;
2111}
Adam Langley95c29f32014-06-20 12:00:00 -07002112
David Benjamin93d17492015-10-17 12:43:36 -04002113int SSL_want(const SSL *ssl) { return ssl->rwstate; }
Adam Langley95c29f32014-06-20 12:00:00 -07002114
Adam Langleyfcf25832014-12-18 17:42:32 -08002115void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
2116 RSA *(*cb)(SSL *ssl, int is_export,
2117 int keylength)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002118}
Adam Langley95c29f32014-06-20 12:00:00 -07002119
Adam Langleyfcf25832014-12-18 17:42:32 -08002120void SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb)(SSL *ssl, int is_export,
2121 int keylength)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002122}
2123
2124void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
David Benjamin59015c32015-04-26 13:13:55 -04002125 DH *(*callback)(SSL *ssl, int is_export,
2126 int keylength)) {
2127 ctx->cert->dh_tmp_cb = callback;
Adam Langleyfcf25832014-12-18 17:42:32 -08002128}
2129
David Benjamin59015c32015-04-26 13:13:55 -04002130void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*callback)(SSL *ssl, int is_export,
2131 int keylength)) {
2132 ssl->cert->dh_tmp_cb = callback;
Adam Langleyfcf25832014-12-18 17:42:32 -08002133}
2134
2135void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
David Benjamindd978782015-04-24 15:20:13 -04002136 EC_KEY *(*callback)(SSL *ssl, int is_export,
2137 int keylength)) {
David Benjamin59015c32015-04-26 13:13:55 -04002138 ctx->cert->ecdh_tmp_cb = callback;
Adam Langleyfcf25832014-12-18 17:42:32 -08002139}
2140
2141void SSL_set_tmp_ecdh_callback(SSL *ssl,
David Benjamindd978782015-04-24 15:20:13 -04002142 EC_KEY *(*callback)(SSL *ssl, int is_export,
2143 int keylength)) {
David Benjamin59015c32015-04-26 13:13:55 -04002144 ssl->cert->ecdh_tmp_cb = callback;
Adam Langleyfcf25832014-12-18 17:42:32 -08002145}
2146
2147int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) {
2148 if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
David Benjamin3570d732015-06-29 00:28:17 -04002149 OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
Adam Langleyfcf25832014-12-18 17:42:32 -08002150 return 0;
2151 }
2152
David Benjamin2755a3e2015-04-22 16:17:58 -04002153 OPENSSL_free(ctx->psk_identity_hint);
Adam Langleyfcf25832014-12-18 17:42:32 -08002154
2155 if (identity_hint != NULL) {
2156 ctx->psk_identity_hint = BUF_strdup(identity_hint);
2157 if (ctx->psk_identity_hint == NULL) {
2158 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07002159 }
Adam Langleyfcf25832014-12-18 17:42:32 -08002160 } else {
2161 ctx->psk_identity_hint = NULL;
2162 }
Adam Langley95c29f32014-06-20 12:00:00 -07002163
Adam Langleyfcf25832014-12-18 17:42:32 -08002164 return 1;
2165}
2166
David Benjamine8814df2015-09-15 08:05:54 -04002167int SSL_use_psk_identity_hint(SSL *ssl, const char *identity_hint) {
2168 if (ssl == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002169 return 0;
2170 }
2171
2172 if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
David Benjamin3570d732015-06-29 00:28:17 -04002173 OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
Adam Langleyfcf25832014-12-18 17:42:32 -08002174 return 0;
2175 }
2176
2177 /* Clear currently configured hint, if any. */
David Benjamine8814df2015-09-15 08:05:54 -04002178 OPENSSL_free(ssl->psk_identity_hint);
2179 ssl->psk_identity_hint = NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -08002180
2181 if (identity_hint != NULL) {
David Benjamine8814df2015-09-15 08:05:54 -04002182 ssl->psk_identity_hint = BUF_strdup(identity_hint);
2183 if (ssl->psk_identity_hint == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002184 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07002185 }
Adam Langleyfcf25832014-12-18 17:42:32 -08002186 }
Adam Langley95c29f32014-06-20 12:00:00 -07002187
Adam Langleyfcf25832014-12-18 17:42:32 -08002188 return 1;
2189}
Adam Langley95c29f32014-06-20 12:00:00 -07002190
David Benjamine8814df2015-09-15 08:05:54 -04002191const char *SSL_get_psk_identity_hint(const SSL *ssl) {
2192 if (ssl == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002193 return NULL;
2194 }
David Benjamine8814df2015-09-15 08:05:54 -04002195 return ssl->psk_identity_hint;
Adam Langleyfcf25832014-12-18 17:42:32 -08002196}
Adam Langley95c29f32014-06-20 12:00:00 -07002197
David Benjamine8814df2015-09-15 08:05:54 -04002198const char *SSL_get_psk_identity(const SSL *ssl) {
2199 if (ssl == NULL || ssl->session == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002200 return NULL;
2201 }
Adam Langley95c29f32014-06-20 12:00:00 -07002202
David Benjamine8814df2015-09-15 08:05:54 -04002203 return ssl->session->psk_identity;
Adam Langleyfcf25832014-12-18 17:42:32 -08002204}
Adam Langley95c29f32014-06-20 12:00:00 -07002205
Adam Langleyfcf25832014-12-18 17:42:32 -08002206void SSL_set_psk_client_callback(
David Benjamine8814df2015-09-15 08:05:54 -04002207 SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity,
2208 unsigned max_identity_len, uint8_t *psk,
2209 unsigned max_psk_len)) {
2210 ssl->psk_client_callback = cb;
Adam Langleyfcf25832014-12-18 17:42:32 -08002211}
Adam Langley95c29f32014-06-20 12:00:00 -07002212
Adam Langleyfcf25832014-12-18 17:42:32 -08002213void SSL_CTX_set_psk_client_callback(
David Benjamine8814df2015-09-15 08:05:54 -04002214 SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *hint, char *identity,
2215 unsigned max_identity_len, uint8_t *psk,
2216 unsigned max_psk_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002217 ctx->psk_client_callback = cb;
2218}
Adam Langley95c29f32014-06-20 12:00:00 -07002219
Adam Langleyfcf25832014-12-18 17:42:32 -08002220void SSL_set_psk_server_callback(
David Benjamine8814df2015-09-15 08:05:54 -04002221 SSL *ssl, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk,
2222 unsigned max_psk_len)) {
2223 ssl->psk_server_callback = cb;
Adam Langleyfcf25832014-12-18 17:42:32 -08002224}
Adam Langley95c29f32014-06-20 12:00:00 -07002225
Adam Langleyfcf25832014-12-18 17:42:32 -08002226void SSL_CTX_set_psk_server_callback(
David Benjamine8814df2015-09-15 08:05:54 -04002227 SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *identity,
2228 uint8_t *psk, unsigned max_psk_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002229 ctx->psk_server_callback = cb;
2230}
Adam Langley95c29f32014-06-20 12:00:00 -07002231
Adam Langleyfcf25832014-12-18 17:42:32 -08002232void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
2233 void (*cb)(int write_p, int version,
2234 int content_type, const void *buf,
2235 size_t len, SSL *ssl, void *arg)) {
David Benjamin59015c32015-04-26 13:13:55 -04002236 ctx->msg_callback = cb;
Adam Langleyfcf25832014-12-18 17:42:32 -08002237}
David Benjamin61ecccf2015-05-05 09:44:51 -04002238
2239void SSL_CTX_set_msg_callback_arg(SSL_CTX *ctx, void *arg) {
2240 ctx->msg_callback_arg = arg;
2241}
2242
Adam Langleyfcf25832014-12-18 17:42:32 -08002243void SSL_set_msg_callback(SSL *ssl,
2244 void (*cb)(int write_p, int version, int content_type,
2245 const void *buf, size_t len, SSL *ssl,
2246 void *arg)) {
David Benjamin59015c32015-04-26 13:13:55 -04002247 ssl->msg_callback = cb;
Adam Langleyfcf25832014-12-18 17:42:32 -08002248}
Adam Langley95c29f32014-06-20 12:00:00 -07002249
David Benjamin61ecccf2015-05-05 09:44:51 -04002250void SSL_set_msg_callback_arg(SSL *ssl, void *arg) {
2251 ssl->msg_callback_arg = arg;
2252}
2253
David Benjamind28f59c2015-11-17 22:32:50 -05002254void SSL_CTX_set_keylog_callback(SSL_CTX *ctx,
2255 void (*cb)(const SSL *ssl, const char *line)) {
2256 ctx->keylog_callback = cb;
Adam Langleyfcf25832014-12-18 17:42:32 -08002257}
Adam Langley95c29f32014-06-20 12:00:00 -07002258
Adam Langleyfcf25832014-12-18 17:42:32 -08002259static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) {
2260 static const char hextable[] = "0123456789abcdef";
2261 uint8_t *out;
2262 size_t i;
Adam Langley95c29f32014-06-20 12:00:00 -07002263
Adam Langleyfcf25832014-12-18 17:42:32 -08002264 if (!CBB_add_space(cbb, &out, in_len * 2)) {
2265 return 0;
2266 }
Adam Langley95c29f32014-06-20 12:00:00 -07002267
Adam Langleyfcf25832014-12-18 17:42:32 -08002268 for (i = 0; i < in_len; i++) {
2269 *(out++) = (uint8_t)hextable[in[i] >> 4];
2270 *(out++) = (uint8_t)hextable[in[i] & 0xf];
2271 }
Adam Langley95c29f32014-06-20 12:00:00 -07002272
Adam Langleyfcf25832014-12-18 17:42:32 -08002273 return 1;
2274}
David Benjamin859ec3c2014-09-02 16:29:36 -04002275
David Benjamind28f59c2015-11-17 22:32:50 -05002276int ssl_log_rsa_client_key_exchange(const SSL *ssl,
2277 const uint8_t *encrypted_premaster,
2278 size_t encrypted_premaster_len,
2279 const uint8_t *premaster,
2280 size_t premaster_len) {
2281 if (ssl->ctx->keylog_callback == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002282 return 1;
2283 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002284
Adam Langleyfcf25832014-12-18 17:42:32 -08002285 if (encrypted_premaster_len < 8) {
David Benjamin3570d732015-06-29 00:28:17 -04002286 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
Adam Langleyfcf25832014-12-18 17:42:32 -08002287 return 0;
2288 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002289
David Benjamind28f59c2015-11-17 22:32:50 -05002290 CBB cbb;
2291 uint8_t *out;
2292 size_t out_len;
David Benjamina8653202015-06-28 01:26:10 -04002293 if (!CBB_init(&cbb, 4 + 16 + 1 + premaster_len * 2 + 1) ||
2294 !CBB_add_bytes(&cbb, (const uint8_t *)"RSA ", 4) ||
Adam Langleyfcf25832014-12-18 17:42:32 -08002295 /* Only the first 8 bytes of the encrypted premaster secret are
2296 * logged. */
2297 !cbb_add_hex(&cbb, encrypted_premaster, 8) ||
2298 !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
2299 !cbb_add_hex(&cbb, premaster, premaster_len) ||
David Benjamind28f59c2015-11-17 22:32:50 -05002300 !CBB_add_u8(&cbb, 0 /* NUL */) ||
Adam Langleyfcf25832014-12-18 17:42:32 -08002301 !CBB_finish(&cbb, &out, &out_len)) {
2302 CBB_cleanup(&cbb);
2303 return 0;
2304 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002305
David Benjamind28f59c2015-11-17 22:32:50 -05002306 ssl->ctx->keylog_callback(ssl, (const char *)out);
Adam Langleyfcf25832014-12-18 17:42:32 -08002307 OPENSSL_free(out);
David Benjamind28f59c2015-11-17 22:32:50 -05002308 return 1;
Adam Langley95f22882014-06-20 12:00:00 -07002309}
2310
David Benjamind28f59c2015-11-17 22:32:50 -05002311int ssl_log_master_secret(const SSL *ssl, const uint8_t *client_random,
2312 size_t client_random_len, const uint8_t *master,
2313 size_t master_len) {
2314 if (ssl->ctx->keylog_callback == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002315 return 1;
2316 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002317
Adam Langleyfcf25832014-12-18 17:42:32 -08002318 if (client_random_len != 32) {
David Benjamin3570d732015-06-29 00:28:17 -04002319 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
Adam Langleyfcf25832014-12-18 17:42:32 -08002320 return 0;
2321 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002322
David Benjamind28f59c2015-11-17 22:32:50 -05002323 CBB cbb;
2324 uint8_t *out;
2325 size_t out_len;
David Benjamina8653202015-06-28 01:26:10 -04002326 if (!CBB_init(&cbb, 14 + 64 + 1 + master_len * 2 + 1) ||
2327 !CBB_add_bytes(&cbb, (const uint8_t *)"CLIENT_RANDOM ", 14) ||
Adam Langleyfcf25832014-12-18 17:42:32 -08002328 !cbb_add_hex(&cbb, client_random, 32) ||
2329 !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
2330 !cbb_add_hex(&cbb, master, master_len) ||
David Benjamind28f59c2015-11-17 22:32:50 -05002331 !CBB_add_u8(&cbb, 0 /* NUL */) ||
Adam Langleyfcf25832014-12-18 17:42:32 -08002332 !CBB_finish(&cbb, &out, &out_len)) {
2333 CBB_cleanup(&cbb);
2334 return 0;
2335 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002336
David Benjamind28f59c2015-11-17 22:32:50 -05002337 ssl->ctx->keylog_callback(ssl, (const char *)out);
Adam Langleyfcf25832014-12-18 17:42:32 -08002338 OPENSSL_free(out);
David Benjamind28f59c2015-11-17 22:32:50 -05002339 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -07002340}
2341
David Benjamin5d8b1282015-10-17 23:26:35 -04002342int SSL_is_init_finished(const SSL *ssl) {
2343 return ssl->state == SSL_ST_OK;
2344}
2345
2346int SSL_in_init(const SSL *ssl) {
2347 return (ssl->state & SSL_ST_INIT) != 0;
2348}
2349
2350int SSL_in_false_start(const SSL *ssl) {
2351 return ssl->s3->tmp.in_false_start;
David Benjamined7c4752015-02-16 19:16:46 -05002352}
2353
Adam Langleyfcf25832014-12-18 17:42:32 -08002354int SSL_cutthrough_complete(const SSL *s) {
David Benjamined7c4752015-02-16 19:16:46 -05002355 return SSL_in_false_start(s);
Adam Langleyfcf25832014-12-18 17:42:32 -08002356}
Adam Langley95c29f32014-06-20 12:00:00 -07002357
Adam Langleyfcf25832014-12-18 17:42:32 -08002358void SSL_get_structure_sizes(size_t *ssl_size, size_t *ssl_ctx_size,
2359 size_t *ssl_session_size) {
2360 *ssl_size = sizeof(SSL);
2361 *ssl_ctx_size = sizeof(SSL_CTX);
2362 *ssl_session_size = sizeof(SSL_SESSION);
2363}
Feng Lu41aa3252014-11-21 22:47:56 -08002364
David Benjamined7c4752015-02-16 19:16:46 -05002365int ssl3_can_false_start(const SSL *s) {
David Benjamin195dc782015-02-19 13:27:05 -05002366 const SSL_CIPHER *const cipher = SSL_get_current_cipher(s);
Adam Langleyfcf25832014-12-18 17:42:32 -08002367
Adam Langleye631d962015-04-01 13:11:01 -07002368 /* False Start only for TLS 1.2 with an ECDHE+AEAD cipher and ALPN or NPN. */
David Benjamin195dc782015-02-19 13:27:05 -05002369 return !SSL_IS_DTLS(s) &&
2370 SSL_version(s) >= TLS1_2_VERSION &&
2371 (s->s3->alpn_selected || s->s3->next_proto_neg_seen) &&
2372 cipher != NULL &&
Adam Langleye631d962015-04-01 13:11:01 -07002373 cipher->algorithm_mkey == SSL_kECDHE &&
David Benjamin195dc782015-02-19 13:27:05 -05002374 (cipher->algorithm_enc == SSL_AES128GCM ||
2375 cipher->algorithm_enc == SSL_AES256GCM ||
Brian Smith271777f2015-10-03 13:53:33 -10002376 cipher->algorithm_enc == SSL_CHACHA20POLY1305_OLD);
Adam Langleyfcf25832014-12-18 17:42:32 -08002377}
2378
2379const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) {
2380 switch (version) {
2381 case SSL3_VERSION:
2382 return &SSLv3_enc_data;
2383
2384 case TLS1_VERSION:
2385 return &TLSv1_enc_data;
2386
David Benjamin9e13e1a2015-03-05 01:56:32 -05002387 case DTLS1_VERSION:
Adam Langleyfcf25832014-12-18 17:42:32 -08002388 case TLS1_1_VERSION:
2389 return &TLSv1_1_enc_data;
2390
David Benjamin9e13e1a2015-03-05 01:56:32 -05002391 case DTLS1_2_VERSION:
Adam Langleyfcf25832014-12-18 17:42:32 -08002392 case TLS1_2_VERSION:
2393 return &TLSv1_2_enc_data;
2394
Adam Langleyfcf25832014-12-18 17:42:32 -08002395 default:
2396 return NULL;
2397 }
2398}
2399
2400uint16_t ssl3_get_max_server_version(const SSL *s) {
2401 uint16_t max_version;
2402
2403 if (SSL_IS_DTLS(s)) {
2404 max_version = (s->max_version != 0) ? s->max_version : DTLS1_2_VERSION;
2405 if (!(s->options & SSL_OP_NO_DTLSv1_2) && DTLS1_2_VERSION >= max_version) {
2406 return DTLS1_2_VERSION;
2407 }
2408 if (!(s->options & SSL_OP_NO_DTLSv1) && DTLS1_VERSION >= max_version) {
2409 return DTLS1_VERSION;
2410 }
2411 return 0;
2412 }
2413
2414 max_version = (s->max_version != 0) ? s->max_version : TLS1_2_VERSION;
2415 if (!(s->options & SSL_OP_NO_TLSv1_2) && TLS1_2_VERSION <= max_version) {
2416 return TLS1_2_VERSION;
2417 }
2418 if (!(s->options & SSL_OP_NO_TLSv1_1) && TLS1_1_VERSION <= max_version) {
2419 return TLS1_1_VERSION;
2420 }
2421 if (!(s->options & SSL_OP_NO_TLSv1) && TLS1_VERSION <= max_version) {
2422 return TLS1_VERSION;
2423 }
2424 if (!(s->options & SSL_OP_NO_SSLv3) && SSL3_VERSION <= max_version) {
2425 return SSL3_VERSION;
2426 }
2427 return 0;
2428}
2429
2430uint16_t ssl3_get_mutual_version(SSL *s, uint16_t client_version) {
2431 uint16_t version = 0;
2432
2433 if (SSL_IS_DTLS(s)) {
2434 /* Clamp client_version to max_version. */
2435 if (s->max_version != 0 && client_version < s->max_version) {
2436 client_version = s->max_version;
2437 }
2438
2439 if (client_version <= DTLS1_2_VERSION && !(s->options & SSL_OP_NO_DTLSv1_2)) {
2440 version = DTLS1_2_VERSION;
2441 } else if (client_version <= DTLS1_VERSION &&
David Benjaminb18f0242015-03-10 18:30:08 -04002442 !(s->options & SSL_OP_NO_DTLSv1)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08002443 version = DTLS1_VERSION;
2444 }
2445
2446 /* Check against min_version. */
2447 if (version != 0 && s->min_version != 0 && version > s->min_version) {
2448 return 0;
2449 }
2450 return version;
2451 } else {
2452 /* Clamp client_version to max_version. */
2453 if (s->max_version != 0 && client_version > s->max_version) {
2454 client_version = s->max_version;
2455 }
2456
2457 if (client_version >= TLS1_2_VERSION && !(s->options & SSL_OP_NO_TLSv1_2)) {
2458 version = TLS1_2_VERSION;
2459 } else if (client_version >= TLS1_1_VERSION &&
2460 !(s->options & SSL_OP_NO_TLSv1_1)) {
2461 version = TLS1_1_VERSION;
2462 } else if (client_version >= TLS1_VERSION && !(s->options & SSL_OP_NO_TLSv1)) {
2463 version = TLS1_VERSION;
2464 } else if (client_version >= SSL3_VERSION && !(s->options & SSL_OP_NO_SSLv3)) {
2465 version = SSL3_VERSION;
2466 }
2467
2468 /* Check against min_version. */
2469 if (version != 0 && s->min_version != 0 && version < s->min_version) {
2470 return 0;
2471 }
2472 return version;
2473 }
2474}
2475
2476uint16_t ssl3_get_max_client_version(SSL *s) {
David Benjamin123a8fd2015-04-26 14:16:41 -04002477 uint32_t options = s->options;
Adam Langleyfcf25832014-12-18 17:42:32 -08002478 uint16_t version = 0;
2479
2480 /* OpenSSL's API for controlling versions entails blacklisting individual
2481 * protocols. This has two problems. First, on the client, the protocol can
2482 * only express a contiguous range of versions. Second, a library consumer
2483 * trying to set a maximum version cannot disable protocol versions that get
2484 * added in a future version of the library.
2485 *
2486 * To account for both of these, OpenSSL interprets the client-side bitmask
2487 * as a min/max range by picking the lowest contiguous non-empty range of
2488 * enabled protocols. Note that this means it is impossible to set a maximum
2489 * version of TLS 1.2 in a future-proof way.
2490 *
2491 * By this scheme, the maximum version is the lowest version V such that V is
2492 * enabled and V+1 is disabled or unimplemented. */
2493 if (SSL_IS_DTLS(s)) {
2494 if (!(options & SSL_OP_NO_DTLSv1_2)) {
2495 version = DTLS1_2_VERSION;
2496 }
2497 if (!(options & SSL_OP_NO_DTLSv1) && (options & SSL_OP_NO_DTLSv1_2)) {
2498 version = DTLS1_VERSION;
2499 }
2500 if (s->max_version != 0 && version < s->max_version) {
2501 version = s->max_version;
2502 }
2503 } else {
2504 if (!(options & SSL_OP_NO_TLSv1_2)) {
2505 version = TLS1_2_VERSION;
2506 }
2507 if (!(options & SSL_OP_NO_TLSv1_1) && (options & SSL_OP_NO_TLSv1_2)) {
2508 version = TLS1_1_VERSION;
2509 }
2510 if (!(options & SSL_OP_NO_TLSv1) && (options & SSL_OP_NO_TLSv1_1)) {
2511 version = TLS1_VERSION;
2512 }
2513 if (!(options & SSL_OP_NO_SSLv3) && (options & SSL_OP_NO_TLSv1)) {
2514 version = SSL3_VERSION;
2515 }
2516 if (s->max_version != 0 && version > s->max_version) {
2517 version = s->max_version;
2518 }
2519 }
2520
2521 return version;
2522}
2523
2524int ssl3_is_version_enabled(SSL *s, uint16_t version) {
2525 if (SSL_IS_DTLS(s)) {
2526 if (s->max_version != 0 && version < s->max_version) {
2527 return 0;
2528 }
2529 if (s->min_version != 0 && version > s->min_version) {
2530 return 0;
2531 }
2532
2533 switch (version) {
2534 case DTLS1_VERSION:
2535 return !(s->options & SSL_OP_NO_DTLSv1);
2536
2537 case DTLS1_2_VERSION:
2538 return !(s->options & SSL_OP_NO_DTLSv1_2);
2539
2540 default:
2541 return 0;
2542 }
2543 } else {
2544 if (s->max_version != 0 && version > s->max_version) {
2545 return 0;
2546 }
2547 if (s->min_version != 0 && version < s->min_version) {
2548 return 0;
2549 }
2550
2551 switch (version) {
2552 case SSL3_VERSION:
2553 return !(s->options & SSL_OP_NO_SSLv3);
2554
2555 case TLS1_VERSION:
2556 return !(s->options & SSL_OP_NO_TLSv1);
2557
2558 case TLS1_1_VERSION:
2559 return !(s->options & SSL_OP_NO_TLSv1_1);
2560
2561 case TLS1_2_VERSION:
2562 return !(s->options & SSL_OP_NO_TLSv1_2);
2563
2564 default:
2565 return 0;
2566 }
2567 }
2568}
2569
David Benjaminea72bd02014-12-21 21:27:41 -05002570uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version) {
2571 if (!SSL_IS_DTLS(s)) {
2572 return wire_version;
2573 }
2574
2575 uint16_t tls_version = ~wire_version;
2576 uint16_t version = tls_version + 0x0201;
2577 /* If either component overflowed, clamp it so comparisons still work. */
2578 if ((version >> 8) < (tls_version >> 8)) {
2579 version = 0xff00 | (version & 0xff);
2580 }
2581 if ((version & 0xff) < (tls_version & 0xff)) {
2582 version = (version & 0xff00) | 0xff;
2583 }
2584 /* DTLS 1.0 maps to TLS 1.1, not TLS 1.0. */
2585 if (version == TLS1_VERSION) {
2586 version = TLS1_1_VERSION;
2587 }
2588 return version;
2589}
2590
David Benjamin42fea372015-09-19 01:22:44 -04002591int SSL_cache_hit(SSL *ssl) { return SSL_session_reused(ssl); }
Adam Langleyfcf25832014-12-18 17:42:32 -08002592
David Benjamin42fea372015-09-19 01:22:44 -04002593int SSL_is_server(SSL *ssl) { return ssl->server; }
Adam Langleyfcf25832014-12-18 17:42:32 -08002594
David Benjamind4c2bce2015-10-17 12:28:18 -04002595void SSL_CTX_set_select_certificate_cb(
2596 SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
2597 ctx->select_certificate_cb = cb;
2598}
2599
Adam Langley524e7172015-02-20 16:04:00 -08002600void SSL_CTX_set_dos_protection_cb(
2601 SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
2602 ctx->dos_protection_cb = cb;
2603}
2604
David Benjamin1d5ef3b2015-10-12 19:54:18 -04002605void SSL_set_renegotiate_mode(SSL *ssl, enum ssl_renegotiate_mode_t mode) {
2606 ssl->renegotiate_mode = mode;
2607}
2608
2609void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject) {
2610 SSL_set_renegotiate_mode(
2611 ssl, reject ? ssl_renegotiate_never : ssl_renegotiate_freely);
David Benjaminb16346b2015-04-08 19:16:58 -04002612}
2613
Adam Langley3f92d212015-02-20 15:32:52 -08002614int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
2615 const RC4_KEY **write_key) {
2616 if (ssl->aead_read_ctx == NULL || ssl->aead_write_ctx == NULL) {
2617 return 0;
2618 }
2619
2620 return EVP_AEAD_CTX_get_rc4_state(&ssl->aead_read_ctx->ctx, read_key) &&
2621 EVP_AEAD_CTX_get_rc4_state(&ssl->aead_write_ctx->ctx, write_key);
2622}
David Benjaminda881e92015-04-26 14:45:04 -04002623
Adam Langleyc2d32802015-11-03 18:36:10 -08002624int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv,
2625 const uint8_t **out_write_iv, size_t *out_iv_len) {
2626 if (ssl->aead_read_ctx == NULL || ssl->aead_write_ctx == NULL) {
2627 return 0;
2628 }
2629
2630 size_t write_iv_len;
2631 if (!EVP_AEAD_CTX_get_iv(&ssl->aead_read_ctx->ctx, out_read_iv, out_iv_len) ||
2632 !EVP_AEAD_CTX_get_iv(&ssl->aead_write_ctx->ctx, out_write_iv,
2633 &write_iv_len) ||
2634 *out_iv_len != write_iv_len) {
2635 return 0;
2636 }
2637
2638 return 1;
David Benjamine348ff42015-11-06 17:55:30 -05002639}
David Benjamin6e807652015-11-02 12:02:20 -05002640
2641uint8_t SSL_get_server_key_exchange_hash(const SSL *ssl) {
2642 return ssl->s3->tmp.server_key_exchange_hash;
Adam Langleyc2d32802015-11-03 18:36:10 -08002643}
2644
David Benjamin27bbae42015-09-13 00:54:37 -04002645int SSL_clear(SSL *ssl) {
2646 if (ssl->method == NULL) {
2647 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_METHOD_SPECIFIED);
2648 return 0;
2649 }
2650
2651 if (ssl_clear_bad_session(ssl)) {
2652 SSL_SESSION_free(ssl->session);
2653 ssl->session = NULL;
2654 }
2655
2656 ssl->hit = 0;
2657 ssl->shutdown = 0;
2658
2659 /* SSL_clear may be called before or after the |ssl| is initialized in either
2660 * accept or connect state. In the latter case, SSL_clear should preserve the
2661 * half and reset |ssl->state| accordingly. */
2662 if (ssl->handshake_func != NULL) {
2663 if (ssl->server) {
2664 SSL_set_accept_state(ssl);
2665 } else {
2666 SSL_set_connect_state(ssl);
2667 }
2668 } else {
2669 assert(ssl->state == 0);
2670 }
2671
2672 /* TODO(davidben): Some state on |ssl| is reset both in |SSL_new| and
2673 * |SSL_clear| because it is per-connection state rather than configuration
2674 * state. Per-connection state should be on |ssl->s3| and |ssl->d1| so it is
2675 * naturally reset at the right points between |SSL_new|, |SSL_clear|, and
2676 * |ssl3_new|. */
2677
2678 ssl->rwstate = SSL_NOTHING;
2679
2680 BUF_MEM_free(ssl->init_buf);
2681 ssl->init_buf = NULL;
2682
2683 ssl_clear_cipher_ctx(ssl);
2684
2685 OPENSSL_free(ssl->next_proto_negotiated);
2686 ssl->next_proto_negotiated = NULL;
2687 ssl->next_proto_negotiated_len = 0;
2688
2689 /* The ssl->d1->mtu is simultaneously configuration (preserved across
2690 * clear) and connection-specific state (gets reset).
2691 *
2692 * TODO(davidben): Avoid this. */
2693 unsigned mtu = 0;
2694 if (ssl->d1 != NULL) {
2695 mtu = ssl->d1->mtu;
2696 }
2697
2698 ssl->method->ssl_free(ssl);
2699 if (!ssl->method->ssl_new(ssl)) {
2700 return 0;
2701 }
2702 ssl->enc_method = ssl3_get_enc_method(ssl->version);
2703 assert(ssl->enc_method != NULL);
2704
2705 if (SSL_IS_DTLS(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
2706 ssl->d1->mtu = mtu;
2707 }
2708
2709 ssl->client_version = ssl->version;
2710
2711 return 1;
2712}
2713
David Benjaminda881e92015-04-26 14:45:04 -04002714int SSL_CTX_sess_connect(const SSL_CTX *ctx) { return 0; }
2715int SSL_CTX_sess_connect_good(const SSL_CTX *ctx) { return 0; }
2716int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx) { return 0; }
2717int SSL_CTX_sess_accept(const SSL_CTX *ctx) { return 0; }
2718int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx) { return 0; }
2719int SSL_CTX_sess_accept_good(const SSL_CTX *ctx) { return 0; }
2720int SSL_CTX_sess_hits(const SSL_CTX *ctx) { return 0; }
2721int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx) { return 0; }
2722int SSL_CTX_sess_misses(const SSL_CTX *ctx) { return 0; }
2723int SSL_CTX_sess_timeouts(const SSL_CTX *ctx) { return 0; }
2724int SSL_CTX_sess_cache_full(const SSL_CTX *ctx) { return 0; }
Matt Braithwaite4838d8a2015-08-20 13:20:03 -07002725void ERR_load_SSL_strings(void) {}
David Benjamin27bbae42015-09-13 00:54:37 -04002726void SSL_load_error_strings(void) {}