blob: 0118aa55bf69cf8fb0bd210206d18dddafe0692a [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
141#include <stdio.h>
142#include <assert.h>
143
David Benjamin39482a12014-07-20 13:30:15 -0400144#include <openssl/bytestring.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700145#include <openssl/dh.h>
146#include <openssl/engine.h>
147#include <openssl/lhash.h>
148#include <openssl/mem.h>
149#include <openssl/obj.h>
150#include <openssl/rand.h>
151#include <openssl/x509v3.h>
152
153#include "ssl_locl.h"
154
Adam Langleyfcf25832014-12-18 17:42:32 -0800155/* Some error codes are special. Ensure the make_errors.go script never
156 * regresses this. */
157OPENSSL_COMPILE_ASSERT(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION ==
158 SSL_AD_NO_RENEGOTIATION + SSL_AD_REASON_OFFSET,
159 ssl_alert_reason_code_mismatch);
David Benjamine1136082014-09-20 12:28:58 -0400160
Adam Langleyfcf25832014-12-18 17:42:32 -0800161int SSL_clear(SSL *s) {
162 if (s->method == NULL) {
163 OPENSSL_PUT_ERROR(SSL, SSL_clear, SSL_R_NO_METHOD_SPECIFIED);
164 return 0;
165 }
Adam Langley95c29f32014-06-20 12:00:00 -0700166
Adam Langleyfcf25832014-12-18 17:42:32 -0800167 if (ssl_clear_bad_session(s)) {
168 SSL_SESSION_free(s->session);
169 s->session = NULL;
170 }
Adam Langley95c29f32014-06-20 12:00:00 -0700171
Adam Langleyfcf25832014-12-18 17:42:32 -0800172 s->hit = 0;
173 s->shutdown = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700174
Adam Langleyfcf25832014-12-18 17:42:32 -0800175 if (s->renegotiate) {
176 OPENSSL_PUT_ERROR(SSL, SSL_clear, ERR_R_INTERNAL_ERROR);
177 return 0;
178 }
Adam Langley95c29f32014-06-20 12:00:00 -0700179
Adam Langleyfcf25832014-12-18 17:42:32 -0800180 /* SSL_clear may be called before or after the |s| is initialized in either
181 * accept or connect state. In the latter case, SSL_clear should preserve the
182 * half and reset |s->state| accordingly. */
183 if (s->handshake_func != NULL) {
184 if (s->server) {
185 SSL_set_accept_state(s);
186 } else {
187 SSL_set_connect_state(s);
188 }
189 } else {
190 assert(s->state == 0);
191 }
Adam Langley95c29f32014-06-20 12:00:00 -0700192
David Benjamin62fd1622015-01-11 13:30:01 -0500193 /* TODO(davidben): Some state on |s| is reset both in |SSL_new| and
194 * |SSL_clear| because it is per-connection state rather than configuration
195 * state. Per-connection state should be on |s->s3| and |s->d1| so it is
196 * naturally reset at the right points between |SSL_new|, |SSL_clear|, and
197 * |ssl3_new|. */
198
Adam Langleyfcf25832014-12-18 17:42:32 -0800199 s->rwstate = SSL_NOTHING;
200 s->rstate = SSL_ST_READ_HEADER;
Adam Langley95c29f32014-06-20 12:00:00 -0700201
Adam Langleyfcf25832014-12-18 17:42:32 -0800202 if (s->init_buf != NULL) {
203 BUF_MEM_free(s->init_buf);
204 s->init_buf = NULL;
205 }
Adam Langley95c29f32014-06-20 12:00:00 -0700206
David Benjamin62fd1622015-01-11 13:30:01 -0500207 s->packet = NULL;
208 s->packet_length = 0;
209
Adam Langleyfcf25832014-12-18 17:42:32 -0800210 ssl_clear_cipher_ctx(s);
211 ssl_clear_hash_ctx(&s->read_hash);
212 ssl_clear_hash_ctx(&s->write_hash);
Adam Langley95c29f32014-06-20 12:00:00 -0700213
David Benjamin62fd1622015-01-11 13:30:01 -0500214 if (s->next_proto_negotiated) {
215 OPENSSL_free(s->next_proto_negotiated);
216 s->next_proto_negotiated = NULL;
217 s->next_proto_negotiated_len = 0;
218 }
219
220 /* The s->d1->mtu is simultaneously configuration (preserved across
221 * clear) and connection-specific state (gets reset).
222 *
223 * TODO(davidben): Avoid this. */
224 unsigned mtu = 0;
225 if (s->d1 != NULL) {
226 mtu = s->d1->mtu;
227 }
228
229 s->method->ssl_free(s);
230 if (!s->method->ssl_new(s)) {
231 return 0;
232 }
233 s->enc_method = ssl3_get_enc_method(s->version);
234 assert(s->enc_method != NULL);
235
236 if (SSL_IS_DTLS(s) && (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
237 s->d1->mtu = mtu;
238 }
239
Adam Langleyfcf25832014-12-18 17:42:32 -0800240 s->client_version = s->version;
Adam Langley95c29f32014-06-20 12:00:00 -0700241
Adam Langleyfcf25832014-12-18 17:42:32 -0800242 return 1;
243}
Adam Langley95c29f32014-06-20 12:00:00 -0700244
Adam Langleyfcf25832014-12-18 17:42:32 -0800245SSL *SSL_new(SSL_CTX *ctx) {
246 SSL *s;
Adam Langley95c29f32014-06-20 12:00:00 -0700247
Adam Langleyfcf25832014-12-18 17:42:32 -0800248 if (ctx == NULL) {
249 OPENSSL_PUT_ERROR(SSL, SSL_new, SSL_R_NULL_SSL_CTX);
250 return NULL;
251 }
252 if (ctx->method == NULL) {
253 OPENSSL_PUT_ERROR(SSL, SSL_new, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
254 return NULL;
255 }
Adam Langley95c29f32014-06-20 12:00:00 -0700256
Adam Langleyfcf25832014-12-18 17:42:32 -0800257 s = (SSL *)OPENSSL_malloc(sizeof(SSL));
258 if (s == NULL) {
259 goto err;
260 }
261 memset(s, 0, sizeof(SSL));
Adam Langley95c29f32014-06-20 12:00:00 -0700262
Adam Langleyfcf25832014-12-18 17:42:32 -0800263 s->min_version = ctx->min_version;
264 s->max_version = ctx->max_version;
David Benjamin1eb367c2014-12-12 18:17:51 -0500265
Adam Langleyfcf25832014-12-18 17:42:32 -0800266 s->options = ctx->options;
267 s->mode = ctx->mode;
268 s->max_cert_list = ctx->max_cert_list;
Adam Langley95c29f32014-06-20 12:00:00 -0700269
Adam Langleyfcf25832014-12-18 17:42:32 -0800270 if (ctx->cert != NULL) {
271 /* Earlier library versions used to copy the pointer to the CERT, not its
272 * contents; only when setting new parameters for the per-SSL copy,
273 * ssl_cert_new would be called (and the direct reference to the
274 * per-SSL_CTX settings would be lost, but those still were indirectly
275 * accessed for various purposes, and for that reason they used to be known
276 * as s->ctx->default_cert). Now we don't look at the SSL_CTX's CERT after
277 * having duplicated it once. */
Adam Langley95c29f32014-06-20 12:00:00 -0700278
Adam Langleyfcf25832014-12-18 17:42:32 -0800279 s->cert = ssl_cert_dup(ctx->cert);
280 if (s->cert == NULL) {
281 goto err;
282 }
283 } else {
284 s->cert = NULL; /* Cannot really happen (see SSL_CTX_new) */
285 }
Adam Langley95c29f32014-06-20 12:00:00 -0700286
Adam Langleyfcf25832014-12-18 17:42:32 -0800287 s->read_ahead = ctx->read_ahead;
288 s->msg_callback = ctx->msg_callback;
289 s->msg_callback_arg = ctx->msg_callback_arg;
290 s->verify_mode = ctx->verify_mode;
291 s->sid_ctx_length = ctx->sid_ctx_length;
292 assert(s->sid_ctx_length <= sizeof s->sid_ctx);
293 memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx));
294 s->verify_callback = ctx->default_verify_callback;
295 s->generate_session_id = ctx->generate_session_id;
Adam Langley95c29f32014-06-20 12:00:00 -0700296
Adam Langleyfcf25832014-12-18 17:42:32 -0800297 s->param = X509_VERIFY_PARAM_new();
298 if (!s->param) {
299 goto err;
300 }
301 X509_VERIFY_PARAM_inherit(s->param, ctx->param);
302 s->quiet_shutdown = ctx->quiet_shutdown;
303 s->max_send_fragment = ctx->max_send_fragment;
Adam Langley95c29f32014-06-20 12:00:00 -0700304
Adam Langleyfcf25832014-12-18 17:42:32 -0800305 CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
306 s->ctx = ctx;
307 s->tlsext_debug_cb = 0;
308 s->tlsext_debug_arg = NULL;
309 s->tlsext_ticket_expected = 0;
310 CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
311 s->initial_ctx = ctx;
312 if (ctx->tlsext_ecpointformatlist) {
313 s->tlsext_ecpointformatlist = BUF_memdup(
314 ctx->tlsext_ecpointformatlist, ctx->tlsext_ecpointformatlist_length);
315 if (!s->tlsext_ecpointformatlist) {
316 goto err;
317 }
318 s->tlsext_ecpointformatlist_length = ctx->tlsext_ecpointformatlist_length;
319 }
Adam Langley95c29f32014-06-20 12:00:00 -0700320
Adam Langleyfcf25832014-12-18 17:42:32 -0800321 if (ctx->tlsext_ellipticcurvelist) {
322 s->tlsext_ellipticcurvelist =
323 BUF_memdup(ctx->tlsext_ellipticcurvelist,
324 ctx->tlsext_ellipticcurvelist_length * 2);
325 if (!s->tlsext_ellipticcurvelist) {
326 goto err;
327 }
328 s->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length;
329 }
330 s->next_proto_negotiated = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700331
Adam Langleyfcf25832014-12-18 17:42:32 -0800332 if (s->ctx->alpn_client_proto_list) {
333 s->alpn_client_proto_list = BUF_memdup(s->ctx->alpn_client_proto_list,
334 s->ctx->alpn_client_proto_list_len);
335 if (s->alpn_client_proto_list == NULL) {
336 goto err;
337 }
338 s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
339 }
Adam Langley95c29f32014-06-20 12:00:00 -0700340
Adam Langleyfcf25832014-12-18 17:42:32 -0800341 s->verify_result = X509_V_OK;
342 s->method = ctx->method;
Adam Langley95c29f32014-06-20 12:00:00 -0700343
Adam Langleyfcf25832014-12-18 17:42:32 -0800344 if (!s->method->ssl_new(s)) {
345 goto err;
346 }
347 s->enc_method = ssl3_get_enc_method(s->version);
348 assert(s->enc_method != NULL);
Adam Langley95c29f32014-06-20 12:00:00 -0700349
Adam Langleyfcf25832014-12-18 17:42:32 -0800350 s->references = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700351
David Benjamin62fd1622015-01-11 13:30:01 -0500352 s->rwstate = SSL_NOTHING;
353 s->rstate = SSL_ST_READ_HEADER;
Adam Langley95c29f32014-06-20 12:00:00 -0700354
Adam Langleyfcf25832014-12-18 17:42:32 -0800355 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700356
Adam Langleyfcf25832014-12-18 17:42:32 -0800357 s->psk_identity_hint = NULL;
358 if (ctx->psk_identity_hint) {
359 s->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint);
360 if (s->psk_identity_hint == NULL) {
361 goto err;
362 }
363 }
364 s->psk_client_callback = ctx->psk_client_callback;
365 s->psk_server_callback = ctx->psk_server_callback;
Adam Langley95c29f32014-06-20 12:00:00 -0700366
David Benjamin02ddbfd2015-01-11 13:09:11 -0500367 s->tlsext_channel_id_enabled = ctx->tlsext_channel_id_enabled;
368 if (ctx->tlsext_channel_id_private) {
369 s->tlsext_channel_id_private = EVP_PKEY_dup(ctx->tlsext_channel_id_private);
370 }
371
Adam Langleyfcf25832014-12-18 17:42:32 -0800372 s->signed_cert_timestamps_enabled = s->ctx->signed_cert_timestamps_enabled;
373 s->ocsp_stapling_enabled = s->ctx->ocsp_stapling_enabled;
HÃ¥vard Molland9169c962014-08-14 14:42:37 +0200374
Adam Langleyfcf25832014-12-18 17:42:32 -0800375 return s;
376
Adam Langley95c29f32014-06-20 12:00:00 -0700377err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800378 if (s != NULL) {
379 if (s->cert != NULL) {
380 ssl_cert_free(s->cert);
Adam Langley95c29f32014-06-20 12:00:00 -0700381 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800382 if (s->ctx != NULL) {
383 SSL_CTX_free(s->ctx);
Adam Langley95c29f32014-06-20 12:00:00 -0700384 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800385 OPENSSL_free(s);
386 }
387 OPENSSL_PUT_ERROR(SSL, SSL_new, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700388
Adam Langleyfcf25832014-12-18 17:42:32 -0800389 return NULL;
390}
Adam Langley95c29f32014-06-20 12:00:00 -0700391
Adam Langleyfcf25832014-12-18 17:42:32 -0800392int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx,
393 unsigned int sid_ctx_len) {
394 if (sid_ctx_len > sizeof ctx->sid_ctx) {
395 OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_session_id_context,
396 SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
397 return 0;
398 }
399 ctx->sid_ctx_length = sid_ctx_len;
400 memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len);
Adam Langley95c29f32014-06-20 12:00:00 -0700401
Adam Langleyfcf25832014-12-18 17:42:32 -0800402 return 1;
403}
Adam Langley95c29f32014-06-20 12:00:00 -0700404
Adam Langleyfcf25832014-12-18 17:42:32 -0800405int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
406 unsigned int sid_ctx_len) {
407 if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
408 OPENSSL_PUT_ERROR(SSL, SSL_set_session_id_context,
409 SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
410 return 0;
411 }
412 ssl->sid_ctx_length = sid_ctx_len;
413 memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len);
Adam Langley95c29f32014-06-20 12:00:00 -0700414
Adam Langleyfcf25832014-12-18 17:42:32 -0800415 return 1;
416}
Adam Langley95c29f32014-06-20 12:00:00 -0700417
Adam Langleyfcf25832014-12-18 17:42:32 -0800418int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) {
419 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
420 ctx->generate_session_id = cb;
421 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
422 return 1;
423}
Adam Langley95c29f32014-06-20 12:00:00 -0700424
Adam Langleyfcf25832014-12-18 17:42:32 -0800425int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) {
426 CRYPTO_w_lock(CRYPTO_LOCK_SSL);
427 ssl->generate_session_id = cb;
428 CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
429 return 1;
430}
Adam Langley95c29f32014-06-20 12:00:00 -0700431
Adam Langleyfcf25832014-12-18 17:42:32 -0800432int SSL_has_matching_session_id(const SSL *ssl, const uint8_t *id,
433 unsigned int id_len) {
434 /* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how we
435 * can "construct" a session to give us the desired check - ie. to find if
436 * there's a session in the hash table that would conflict with any new
437 * session built out of this id/id_len and the ssl_version in use by this
438 * SSL. */
439 SSL_SESSION r, *p;
Adam Langley95c29f32014-06-20 12:00:00 -0700440
Adam Langleyfcf25832014-12-18 17:42:32 -0800441 if (id_len > sizeof r.session_id) {
442 return 0;
443 }
Adam Langley95c29f32014-06-20 12:00:00 -0700444
Adam Langleyfcf25832014-12-18 17:42:32 -0800445 r.ssl_version = ssl->version;
446 r.session_id_length = id_len;
447 memcpy(r.session_id, id, id_len);
Adam Langley95c29f32014-06-20 12:00:00 -0700448
Adam Langleyfcf25832014-12-18 17:42:32 -0800449 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
450 p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r);
451 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
452 return p != NULL;
453}
Adam Langley95c29f32014-06-20 12:00:00 -0700454
Adam Langleyfcf25832014-12-18 17:42:32 -0800455int SSL_CTX_set_purpose(SSL_CTX *s, int purpose) {
456 return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
457}
458
459int SSL_set_purpose(SSL *s, int purpose) {
460 return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
461}
462
463int SSL_CTX_set_trust(SSL_CTX *s, int trust) {
464 return X509_VERIFY_PARAM_set_trust(s->param, trust);
465}
466
467int SSL_set_trust(SSL *s, int trust) {
468 return X509_VERIFY_PARAM_set_trust(s->param, trust);
469}
470
471int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) {
472 return X509_VERIFY_PARAM_set1(ctx->param, vpm);
473}
474
475int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) {
476 return X509_VERIFY_PARAM_set1(ssl->param, vpm);
477}
Adam Langley95c29f32014-06-20 12:00:00 -0700478
Adam Langley858a88d2014-06-20 12:00:00 -0700479void ssl_cipher_preference_list_free(
Adam Langleyfcf25832014-12-18 17:42:32 -0800480 struct ssl_cipher_preference_list_st *cipher_list) {
481 sk_SSL_CIPHER_free(cipher_list->ciphers);
482 OPENSSL_free(cipher_list->in_group_flags);
483 OPENSSL_free(cipher_list);
484}
Adam Langley858a88d2014-06-20 12:00:00 -0700485
Adam Langleyfcf25832014-12-18 17:42:32 -0800486struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_dup(
487 struct ssl_cipher_preference_list_st *cipher_list) {
488 struct ssl_cipher_preference_list_st *ret = NULL;
489 size_t n = sk_SSL_CIPHER_num(cipher_list->ciphers);
Adam Langley858a88d2014-06-20 12:00:00 -0700490
Adam Langleyfcf25832014-12-18 17:42:32 -0800491 ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
492 if (!ret) {
493 goto err;
494 }
495
496 ret->ciphers = NULL;
497 ret->in_group_flags = NULL;
498 ret->ciphers = sk_SSL_CIPHER_dup(cipher_list->ciphers);
499 if (!ret->ciphers) {
500 goto err;
501 }
502 ret->in_group_flags = BUF_memdup(cipher_list->in_group_flags, n);
503 if (!ret->in_group_flags) {
504 goto err;
505 }
506
507 return ret;
Adam Langley858a88d2014-06-20 12:00:00 -0700508
509err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800510 if (ret && ret->ciphers) {
511 sk_SSL_CIPHER_free(ret->ciphers);
512 }
513 if (ret) {
514 OPENSSL_free(ret);
515 }
516 return NULL;
517}
Adam Langley858a88d2014-06-20 12:00:00 -0700518
Adam Langleyfcf25832014-12-18 17:42:32 -0800519struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_from_ciphers(
520 STACK_OF(SSL_CIPHER) * ciphers) {
521 struct ssl_cipher_preference_list_st *ret = NULL;
522 size_t n = sk_SSL_CIPHER_num(ciphers);
Adam Langley858a88d2014-06-20 12:00:00 -0700523
Adam Langleyfcf25832014-12-18 17:42:32 -0800524 ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
525 if (!ret) {
526 goto err;
527 }
528 ret->ciphers = NULL;
529 ret->in_group_flags = NULL;
530 ret->ciphers = sk_SSL_CIPHER_dup(ciphers);
531 if (!ret->ciphers) {
532 goto err;
533 }
534 ret->in_group_flags = OPENSSL_malloc(n);
535 if (!ret->in_group_flags) {
536 goto err;
537 }
538 memset(ret->in_group_flags, 0, n);
539 return ret;
Adam Langley858a88d2014-06-20 12:00:00 -0700540
541err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800542 if (ret && ret->ciphers) {
543 sk_SSL_CIPHER_free(ret->ciphers);
544 }
545 if (ret) {
546 OPENSSL_free(ret);
547 }
548 return NULL;
549}
Adam Langley858a88d2014-06-20 12:00:00 -0700550
Adam Langleyfcf25832014-12-18 17:42:32 -0800551X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { return ctx->param; }
Adam Langley95c29f32014-06-20 12:00:00 -0700552
Adam Langleyfcf25832014-12-18 17:42:32 -0800553X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { return ssl->param; }
Adam Langley95c29f32014-06-20 12:00:00 -0700554
Adam Langleyfcf25832014-12-18 17:42:32 -0800555void SSL_certs_clear(SSL *s) { ssl_cert_clear_certs(s->cert); }
Adam Langley95c29f32014-06-20 12:00:00 -0700556
Adam Langleyfcf25832014-12-18 17:42:32 -0800557void SSL_free(SSL *s) {
558 int i;
Adam Langley95c29f32014-06-20 12:00:00 -0700559
Adam Langleyfcf25832014-12-18 17:42:32 -0800560 if (s == NULL) {
561 return;
562 }
Adam Langley95c29f32014-06-20 12:00:00 -0700563
Adam Langleyfcf25832014-12-18 17:42:32 -0800564 i = CRYPTO_add(&s->references, -1, CRYPTO_LOCK_SSL);
565 if (i > 0) {
566 return;
567 }
Adam Langley95c29f32014-06-20 12:00:00 -0700568
Adam Langleyfcf25832014-12-18 17:42:32 -0800569 if (s->param) {
570 X509_VERIFY_PARAM_free(s->param);
571 }
Adam Langley95c29f32014-06-20 12:00:00 -0700572
Adam Langleyfcf25832014-12-18 17:42:32 -0800573 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700574
Adam Langleyfcf25832014-12-18 17:42:32 -0800575 if (s->bbio != NULL) {
576 /* If the buffering BIO is in place, pop it off */
577 if (s->bbio == s->wbio) {
578 s->wbio = BIO_pop(s->wbio);
579 }
580 BIO_free(s->bbio);
581 s->bbio = NULL;
582 }
Adam Langley95c29f32014-06-20 12:00:00 -0700583
Adam Langleyfcf25832014-12-18 17:42:32 -0800584 if (s->rbio != NULL) {
585 BIO_free_all(s->rbio);
586 }
Adam Langley95c29f32014-06-20 12:00:00 -0700587
Adam Langleyfcf25832014-12-18 17:42:32 -0800588 if (s->wbio != NULL && s->wbio != s->rbio) {
589 BIO_free_all(s->wbio);
590 }
Adam Langley95c29f32014-06-20 12:00:00 -0700591
Adam Langleyfcf25832014-12-18 17:42:32 -0800592 if (s->init_buf != NULL) {
593 BUF_MEM_free(s->init_buf);
594 }
Adam Langley95c29f32014-06-20 12:00:00 -0700595
Adam Langleyfcf25832014-12-18 17:42:32 -0800596 /* add extra stuff */
597 if (s->cipher_list != NULL) {
598 ssl_cipher_preference_list_free(s->cipher_list);
599 }
600 if (s->cipher_list_by_id != NULL) {
601 sk_SSL_CIPHER_free(s->cipher_list_by_id);
602 }
Adam Langley95c29f32014-06-20 12:00:00 -0700603
Adam Langleyfcf25832014-12-18 17:42:32 -0800604 if (s->session != NULL) {
605 ssl_clear_bad_session(s);
606 SSL_SESSION_free(s->session);
607 }
Adam Langley95c29f32014-06-20 12:00:00 -0700608
Adam Langleyfcf25832014-12-18 17:42:32 -0800609 ssl_clear_cipher_ctx(s);
610 ssl_clear_hash_ctx(&s->read_hash);
611 ssl_clear_hash_ctx(&s->write_hash);
Adam Langley95c29f32014-06-20 12:00:00 -0700612
Adam Langleyfcf25832014-12-18 17:42:32 -0800613 if (s->cert != NULL) {
614 ssl_cert_free(s->cert);
615 }
Adam Langley0289c732014-06-20 12:00:00 -0700616
Adam Langleyfcf25832014-12-18 17:42:32 -0800617 if (s->tlsext_hostname) {
618 OPENSSL_free(s->tlsext_hostname);
619 }
620 if (s->initial_ctx) {
621 SSL_CTX_free(s->initial_ctx);
622 }
623 if (s->tlsext_ecpointformatlist) {
624 OPENSSL_free(s->tlsext_ecpointformatlist);
625 }
626 if (s->tlsext_ellipticcurvelist) {
627 OPENSSL_free(s->tlsext_ellipticcurvelist);
628 }
629 if (s->alpn_client_proto_list) {
630 OPENSSL_free(s->alpn_client_proto_list);
631 }
632 if (s->tlsext_channel_id_private) {
633 EVP_PKEY_free(s->tlsext_channel_id_private);
634 }
635 if (s->psk_identity_hint) {
636 OPENSSL_free(s->psk_identity_hint);
637 }
638 if (s->client_CA != NULL) {
639 sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
640 }
641 if (s->next_proto_negotiated) {
642 OPENSSL_free(s->next_proto_negotiated);
643 }
644 if (s->srtp_profiles) {
645 sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
646 }
Adam Langley95c29f32014-06-20 12:00:00 -0700647
Adam Langleyfcf25832014-12-18 17:42:32 -0800648 if (s->method != NULL) {
649 s->method->ssl_free(s);
650 }
651 if (s->ctx) {
652 SSL_CTX_free(s->ctx);
653 }
Adam Langley95c29f32014-06-20 12:00:00 -0700654
Adam Langleyfcf25832014-12-18 17:42:32 -0800655 OPENSSL_free(s);
656}
Adam Langley95c29f32014-06-20 12:00:00 -0700657
Adam Langleyfcf25832014-12-18 17:42:32 -0800658void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) {
659 /* If the output buffering BIO is still in place, remove it. */
660 if (s->bbio != NULL) {
661 if (s->wbio == s->bbio) {
662 s->wbio = s->wbio->next_bio;
663 s->bbio->next_bio = NULL;
664 }
665 }
Adam Langley95c29f32014-06-20 12:00:00 -0700666
Adam Langleyfcf25832014-12-18 17:42:32 -0800667 if (s->rbio != NULL && s->rbio != rbio) {
668 BIO_free_all(s->rbio);
669 }
670 if (s->wbio != NULL && s->wbio != wbio && s->rbio != s->wbio) {
671 BIO_free_all(s->wbio);
672 }
673 s->rbio = rbio;
674 s->wbio = wbio;
675}
Adam Langley95c29f32014-06-20 12:00:00 -0700676
Adam Langleyfcf25832014-12-18 17:42:32 -0800677BIO *SSL_get_rbio(const SSL *s) { return s->rbio; }
Adam Langley95c29f32014-06-20 12:00:00 -0700678
Adam Langleyfcf25832014-12-18 17:42:32 -0800679BIO *SSL_get_wbio(const SSL *s) { return s->wbio; }
Adam Langley95c29f32014-06-20 12:00:00 -0700680
Adam Langleyfcf25832014-12-18 17:42:32 -0800681int SSL_get_fd(const SSL *s) { return SSL_get_rfd(s); }
Adam Langley95c29f32014-06-20 12:00:00 -0700682
Adam Langleyfcf25832014-12-18 17:42:32 -0800683int SSL_get_rfd(const SSL *s) {
684 int ret = -1;
685 BIO *b, *r;
Adam Langley95c29f32014-06-20 12:00:00 -0700686
Adam Langleyfcf25832014-12-18 17:42:32 -0800687 b = SSL_get_rbio(s);
688 r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
689 if (r != NULL) {
690 BIO_get_fd(r, &ret);
691 }
692 return ret;
693}
Adam Langley95c29f32014-06-20 12:00:00 -0700694
Adam Langleyfcf25832014-12-18 17:42:32 -0800695int SSL_get_wfd(const SSL *s) {
696 int ret = -1;
697 BIO *b, *r;
Adam Langley95c29f32014-06-20 12:00:00 -0700698
Adam Langleyfcf25832014-12-18 17:42:32 -0800699 b = SSL_get_wbio(s);
700 r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
701 if (r != NULL) {
702 BIO_get_fd(r, &ret);
703 }
Adam Langley95c29f32014-06-20 12:00:00 -0700704
Adam Langleyfcf25832014-12-18 17:42:32 -0800705 return ret;
706}
Adam Langley95c29f32014-06-20 12:00:00 -0700707
Adam Langleyfcf25832014-12-18 17:42:32 -0800708int SSL_set_fd(SSL *s, int fd) {
709 int ret = 0;
710 BIO *bio = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700711
Adam Langleyfcf25832014-12-18 17:42:32 -0800712 bio = BIO_new(BIO_s_fd());
Adam Langley95c29f32014-06-20 12:00:00 -0700713
Adam Langleyfcf25832014-12-18 17:42:32 -0800714 if (bio == NULL) {
715 OPENSSL_PUT_ERROR(SSL, SSL_set_fd, ERR_R_BUF_LIB);
716 goto err;
717 }
718 BIO_set_fd(bio, fd, BIO_NOCLOSE);
719 SSL_set_bio(s, bio, bio);
720 ret = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700721
Adam Langley95c29f32014-06-20 12:00:00 -0700722err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800723 return ret;
724}
Adam Langley95c29f32014-06-20 12:00:00 -0700725
Adam Langleyfcf25832014-12-18 17:42:32 -0800726int SSL_set_wfd(SSL *s, int fd) {
727 int ret = 0;
728 BIO *bio = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700729
Adam Langleyfcf25832014-12-18 17:42:32 -0800730 if (s->rbio == NULL || BIO_method_type(s->rbio) != BIO_TYPE_FD ||
731 (int)BIO_get_fd(s->rbio, NULL) != fd) {
732 bio = BIO_new(BIO_s_fd());
Adam Langley95c29f32014-06-20 12:00:00 -0700733
Adam Langleyfcf25832014-12-18 17:42:32 -0800734 if (bio == NULL) {
735 OPENSSL_PUT_ERROR(SSL, SSL_set_wfd, ERR_R_BUF_LIB);
736 goto err;
737 }
738 BIO_set_fd(bio, fd, BIO_NOCLOSE);
739 SSL_set_bio(s, SSL_get_rbio(s), bio);
740 } else {
741 SSL_set_bio(s, SSL_get_rbio(s), SSL_get_rbio(s));
742 }
743
744 ret = 1;
745
Adam Langley95c29f32014-06-20 12:00:00 -0700746err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800747 return ret;
748}
Adam Langley95c29f32014-06-20 12:00:00 -0700749
Adam Langleyfcf25832014-12-18 17:42:32 -0800750int SSL_set_rfd(SSL *s, int fd) {
751 int ret = 0;
752 BIO *bio = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700753
Adam Langleyfcf25832014-12-18 17:42:32 -0800754 if (s->wbio == NULL || BIO_method_type(s->wbio) != BIO_TYPE_FD ||
755 (int)BIO_get_fd(s->wbio, NULL) != fd) {
756 bio = BIO_new(BIO_s_fd());
Adam Langley95c29f32014-06-20 12:00:00 -0700757
Adam Langleyfcf25832014-12-18 17:42:32 -0800758 if (bio == NULL) {
759 OPENSSL_PUT_ERROR(SSL, SSL_set_rfd, ERR_R_BUF_LIB);
760 goto err;
761 }
762 BIO_set_fd(bio, fd, BIO_NOCLOSE);
763 SSL_set_bio(s, bio, SSL_get_wbio(s));
764 } else {
765 SSL_set_bio(s, SSL_get_wbio(s), SSL_get_wbio(s));
766 }
767 ret = 1;
768
Adam Langley95c29f32014-06-20 12:00:00 -0700769err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800770 return ret;
771}
Adam Langley95c29f32014-06-20 12:00:00 -0700772
773/* return length of latest Finished message we sent, copy to 'buf' */
Adam Langleyfcf25832014-12-18 17:42:32 -0800774size_t SSL_get_finished(const SSL *s, void *buf, size_t count) {
775 size_t ret = 0;
776
777 if (s->s3 != NULL) {
778 ret = s->s3->tmp.finish_md_len;
779 if (count > ret) {
780 count = ret;
781 }
782 memcpy(buf, s->s3->tmp.finish_md, count);
783 }
784
785 return ret;
786}
Adam Langley95c29f32014-06-20 12:00:00 -0700787
788/* return length of latest Finished message we expected, copy to 'buf' */
Adam Langleyfcf25832014-12-18 17:42:32 -0800789size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count) {
790 size_t ret = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700791
Adam Langleyfcf25832014-12-18 17:42:32 -0800792 if (s->s3 != NULL) {
793 ret = s->s3->tmp.peer_finish_md_len;
794 if (count > ret) {
795 count = ret;
796 }
797 memcpy(buf, s->s3->tmp.peer_finish_md, count);
798 }
Adam Langley95c29f32014-06-20 12:00:00 -0700799
Adam Langleyfcf25832014-12-18 17:42:32 -0800800 return ret;
801}
Adam Langley95c29f32014-06-20 12:00:00 -0700802
Adam Langleyfcf25832014-12-18 17:42:32 -0800803int SSL_get_verify_mode(const SSL *s) { return s->verify_mode; }
Adam Langley95c29f32014-06-20 12:00:00 -0700804
Adam Langleyfcf25832014-12-18 17:42:32 -0800805int SSL_get_verify_depth(const SSL *s) {
806 return X509_VERIFY_PARAM_get_depth(s->param);
807}
Adam Langley95c29f32014-06-20 12:00:00 -0700808
Adam Langleyfcf25832014-12-18 17:42:32 -0800809int (*SSL_get_verify_callback(const SSL *s))(int, X509_STORE_CTX *) {
810 return s->verify_callback;
811}
Adam Langley95c29f32014-06-20 12:00:00 -0700812
Adam Langleyfcf25832014-12-18 17:42:32 -0800813int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { return ctx->verify_mode; }
Adam Langley95c29f32014-06-20 12:00:00 -0700814
Adam Langleyfcf25832014-12-18 17:42:32 -0800815int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) {
816 return X509_VERIFY_PARAM_get_depth(ctx->param);
817}
Adam Langley95c29f32014-06-20 12:00:00 -0700818
Adam Langleyfcf25832014-12-18 17:42:32 -0800819int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int, X509_STORE_CTX *) {
820 return ctx->default_verify_callback;
821}
Adam Langley95c29f32014-06-20 12:00:00 -0700822
Adam Langleyfcf25832014-12-18 17:42:32 -0800823void SSL_set_verify(SSL *s, int mode,
824 int (*callback)(int ok, X509_STORE_CTX *ctx)) {
825 s->verify_mode = mode;
826 if (callback != NULL) {
827 s->verify_callback = callback;
828 }
829}
Adam Langley95c29f32014-06-20 12:00:00 -0700830
Adam Langleyfcf25832014-12-18 17:42:32 -0800831void SSL_set_verify_depth(SSL *s, int depth) {
832 X509_VERIFY_PARAM_set_depth(s->param, depth);
833}
Adam Langley95c29f32014-06-20 12:00:00 -0700834
Adam Langleyfcf25832014-12-18 17:42:32 -0800835void SSL_set_read_ahead(SSL *s, int yes) { s->read_ahead = yes; }
Adam Langley95c29f32014-06-20 12:00:00 -0700836
Adam Langleyfcf25832014-12-18 17:42:32 -0800837int SSL_get_read_ahead(const SSL *s) { return s->read_ahead; }
Adam Langley95c29f32014-06-20 12:00:00 -0700838
Adam Langleyfcf25832014-12-18 17:42:32 -0800839int SSL_pending(const SSL *s) {
840 /* SSL_pending cannot work properly if read-ahead is enabled
841 * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)), and it is
842 * impossible to fix since SSL_pending cannot report errors that may be
843 * observed while scanning the new data. (Note that SSL_pending() is often
844 * used as a boolean value, so we'd better not return -1.). */
845 return s->method->ssl_pending(s);
846}
Adam Langley95c29f32014-06-20 12:00:00 -0700847
Adam Langleyfcf25832014-12-18 17:42:32 -0800848X509 *SSL_get_peer_certificate(const SSL *s) {
849 X509 *r;
Adam Langley95c29f32014-06-20 12:00:00 -0700850
Adam Langleyfcf25832014-12-18 17:42:32 -0800851 if (s == NULL || s->session == NULL) {
852 r = NULL;
853 } else {
854 r = s->session->peer;
855 }
Adam Langley95c29f32014-06-20 12:00:00 -0700856
Adam Langleyfcf25832014-12-18 17:42:32 -0800857 if (r == NULL) {
858 return NULL;
859 }
Adam Langley95c29f32014-06-20 12:00:00 -0700860
Adam Langleyfcf25832014-12-18 17:42:32 -0800861 return X509_up_ref(r);
862}
863
864STACK_OF(X509) * SSL_get_peer_cert_chain(const SSL *s) {
865 STACK_OF(X509) * r;
866
867 if (s == NULL || s->session == NULL || s->session->sess_cert == NULL) {
868 r = NULL;
869 } else {
870 r = s->session->sess_cert->cert_chain;
871 }
872
873 /* If we are a client, cert_chain includes the peer's own certificate; if we
874 * are a server, it does not. */
875 return r;
876}
Adam Langley95c29f32014-06-20 12:00:00 -0700877
Adam Langley95c29f32014-06-20 12:00:00 -0700878/* Fix this so it checks all the valid key/cert options */
Adam Langleyfcf25832014-12-18 17:42:32 -0800879int SSL_CTX_check_private_key(const SSL_CTX *ctx) {
880 if (ctx == NULL || ctx->cert == NULL || ctx->cert->key->x509 == NULL) {
881 OPENSSL_PUT_ERROR(SSL, SSL_CTX_check_private_key,
882 SSL_R_NO_CERTIFICATE_ASSIGNED);
883 return 0;
884 }
885
886 if (ctx->cert->key->privatekey == NULL) {
887 OPENSSL_PUT_ERROR(SSL, SSL_CTX_check_private_key,
888 SSL_R_NO_PRIVATE_KEY_ASSIGNED);
889 return 0;
890 }
891
892 return X509_check_private_key(ctx->cert->key->x509,
893 ctx->cert->key->privatekey);
894}
Adam Langley95c29f32014-06-20 12:00:00 -0700895
896/* Fix this function so that it takes an optional type parameter */
Adam Langleyfcf25832014-12-18 17:42:32 -0800897int SSL_check_private_key(const SSL *ssl) {
898 if (ssl == NULL) {
899 OPENSSL_PUT_ERROR(SSL, SSL_check_private_key, ERR_R_PASSED_NULL_PARAMETER);
900 return 0;
901 }
Adam Langley95c29f32014-06-20 12:00:00 -0700902
Adam Langleyfcf25832014-12-18 17:42:32 -0800903 if (ssl->cert == NULL) {
904 OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
905 SSL_R_NO_CERTIFICATE_ASSIGNED);
906 return 0;
907 }
Adam Langley95c29f32014-06-20 12:00:00 -0700908
Adam Langleyfcf25832014-12-18 17:42:32 -0800909 if (ssl->cert->key->x509 == NULL) {
910 OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
911 SSL_R_NO_CERTIFICATE_ASSIGNED);
912 return 0;
913 }
David Benjamin0b145c22014-11-26 20:10:09 -0500914
Adam Langleyfcf25832014-12-18 17:42:32 -0800915 if (ssl->cert->key->privatekey == NULL) {
916 OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
917 SSL_R_NO_PRIVATE_KEY_ASSIGNED);
918 return 0;
919 }
Adam Langley95c29f32014-06-20 12:00:00 -0700920
Adam Langleyfcf25832014-12-18 17:42:32 -0800921 return X509_check_private_key(ssl->cert->key->x509,
922 ssl->cert->key->privatekey);
923}
Adam Langley95c29f32014-06-20 12:00:00 -0700924
Adam Langleyfcf25832014-12-18 17:42:32 -0800925int SSL_accept(SSL *s) {
926 if (s->handshake_func == 0) {
927 /* Not properly initialized yet */
928 SSL_set_accept_state(s);
929 }
David Benjamin0b145c22014-11-26 20:10:09 -0500930
Adam Langleyfcf25832014-12-18 17:42:32 -0800931 if (s->handshake_func != s->method->ssl_accept) {
932 OPENSSL_PUT_ERROR(SSL, SSL_connect, ERR_R_INTERNAL_ERROR);
933 return -1;
934 }
Adam Langley95c29f32014-06-20 12:00:00 -0700935
Adam Langleyfcf25832014-12-18 17:42:32 -0800936 return s->handshake_func(s);
937}
Adam Langley95c29f32014-06-20 12:00:00 -0700938
Adam Langleyfcf25832014-12-18 17:42:32 -0800939int SSL_connect(SSL *s) {
940 if (s->handshake_func == 0) {
941 /* Not properly initialized yet */
942 SSL_set_connect_state(s);
943 }
Adam Langley95c29f32014-06-20 12:00:00 -0700944
Adam Langleyfcf25832014-12-18 17:42:32 -0800945 if (s->handshake_func != s->method->ssl_connect) {
946 OPENSSL_PUT_ERROR(SSL, SSL_connect, ERR_R_INTERNAL_ERROR);
947 return -1;
948 }
Adam Langley95c29f32014-06-20 12:00:00 -0700949
Adam Langleyfcf25832014-12-18 17:42:32 -0800950 return s->handshake_func(s);
951}
Adam Langley95c29f32014-06-20 12:00:00 -0700952
Adam Langleyfcf25832014-12-18 17:42:32 -0800953long SSL_get_default_timeout(const SSL *s) {
954 return SSL_DEFAULT_SESSION_TIMEOUT;
955}
Adam Langley95c29f32014-06-20 12:00:00 -0700956
Adam Langleyfcf25832014-12-18 17:42:32 -0800957int SSL_read(SSL *s, void *buf, int num) {
958 if (s->handshake_func == 0) {
959 OPENSSL_PUT_ERROR(SSL, SSL_read, SSL_R_UNINITIALIZED);
960 return -1;
961 }
Adam Langley95c29f32014-06-20 12:00:00 -0700962
Adam Langleyfcf25832014-12-18 17:42:32 -0800963 if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
964 s->rwstate = SSL_NOTHING;
965 return 0;
966 }
Adam Langley95c29f32014-06-20 12:00:00 -0700967
Adam Langleyfcf25832014-12-18 17:42:32 -0800968 return s->method->ssl_read(s, buf, num);
969}
Adam Langley95c29f32014-06-20 12:00:00 -0700970
Adam Langleyfcf25832014-12-18 17:42:32 -0800971int SSL_peek(SSL *s, void *buf, int num) {
972 if (s->handshake_func == 0) {
973 OPENSSL_PUT_ERROR(SSL, SSL_peek, SSL_R_UNINITIALIZED);
974 return -1;
975 }
Adam Langley95c29f32014-06-20 12:00:00 -0700976
Adam Langleyfcf25832014-12-18 17:42:32 -0800977 if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
978 return 0;
979 }
Adam Langley95c29f32014-06-20 12:00:00 -0700980
Adam Langleyfcf25832014-12-18 17:42:32 -0800981 return s->method->ssl_peek(s, buf, num);
982}
Adam Langley95c29f32014-06-20 12:00:00 -0700983
Adam Langleyfcf25832014-12-18 17:42:32 -0800984int SSL_write(SSL *s, const void *buf, int num) {
985 if (s->handshake_func == 0) {
986 OPENSSL_PUT_ERROR(SSL, SSL_write, SSL_R_UNINITIALIZED);
987 return -1;
988 }
Adam Langley95c29f32014-06-20 12:00:00 -0700989
Adam Langleyfcf25832014-12-18 17:42:32 -0800990 if (s->shutdown & SSL_SENT_SHUTDOWN) {
991 s->rwstate = SSL_NOTHING;
992 OPENSSL_PUT_ERROR(SSL, SSL_write, SSL_R_PROTOCOL_IS_SHUTDOWN);
993 return -1;
994 }
Adam Langley95c29f32014-06-20 12:00:00 -0700995
Adam Langleyfcf25832014-12-18 17:42:32 -0800996 return s->method->ssl_write(s, buf, num);
997}
Adam Langley95c29f32014-06-20 12:00:00 -0700998
Adam Langleyfcf25832014-12-18 17:42:32 -0800999int SSL_shutdown(SSL *s) {
1000 /* Note that this function behaves differently from what one might expect.
1001 * Return values are 0 for no success (yet), 1 for success; but calling it
1002 * once is usually not enough, even if blocking I/O is used (see
1003 * ssl3_shutdown). */
Adam Langley95c29f32014-06-20 12:00:00 -07001004
Adam Langleyfcf25832014-12-18 17:42:32 -08001005 if (s->handshake_func == 0) {
1006 OPENSSL_PUT_ERROR(SSL, SSL_shutdown, SSL_R_UNINITIALIZED);
1007 return -1;
1008 }
Adam Langley95c29f32014-06-20 12:00:00 -07001009
Adam Langleyfcf25832014-12-18 17:42:32 -08001010 if (!SSL_in_init(s)) {
1011 return s->method->ssl_shutdown(s);
1012 }
Adam Langley95c29f32014-06-20 12:00:00 -07001013
Adam Langleyfcf25832014-12-18 17:42:32 -08001014 return 1;
1015}
Adam Langley95c29f32014-06-20 12:00:00 -07001016
Adam Langleyfcf25832014-12-18 17:42:32 -08001017int SSL_renegotiate(SSL *s) {
1018 if (s->renegotiate == 0) {
1019 s->renegotiate = 1;
1020 }
Adam Langley95c29f32014-06-20 12:00:00 -07001021
Adam Langleyfcf25832014-12-18 17:42:32 -08001022 s->new_session = 1;
1023 return s->method->ssl_renegotiate(s);
1024}
Adam Langley95c29f32014-06-20 12:00:00 -07001025
Adam Langleyfcf25832014-12-18 17:42:32 -08001026int SSL_renegotiate_abbreviated(SSL *s) {
1027 if (s->renegotiate == 0) {
1028 s->renegotiate = 1;
1029 }
Adam Langley95c29f32014-06-20 12:00:00 -07001030
Adam Langleyfcf25832014-12-18 17:42:32 -08001031 s->new_session = 0;
1032 return s->method->ssl_renegotiate(s);
1033}
Adam Langley95c29f32014-06-20 12:00:00 -07001034
Adam Langleyfcf25832014-12-18 17:42:32 -08001035int SSL_renegotiate_pending(SSL *s) {
1036 /* becomes true when negotiation is requested; false again once a handshake
1037 * has finished */
1038 return s->renegotiate != 0;
1039}
Adam Langley95c29f32014-06-20 12:00:00 -07001040
Adam Langleyfcf25832014-12-18 17:42:32 -08001041long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) {
1042 long l;
Adam Langley95c29f32014-06-20 12:00:00 -07001043
Adam Langleyfcf25832014-12-18 17:42:32 -08001044 switch (cmd) {
1045 case SSL_CTRL_GET_READ_AHEAD:
1046 return s->read_ahead;
Adam Langley95c29f32014-06-20 12:00:00 -07001047
Adam Langleyfcf25832014-12-18 17:42:32 -08001048 case SSL_CTRL_SET_READ_AHEAD:
1049 l = s->read_ahead;
1050 s->read_ahead = larg;
1051 return l;
Adam Langley95c29f32014-06-20 12:00:00 -07001052
Adam Langleyfcf25832014-12-18 17:42:32 -08001053 case SSL_CTRL_SET_MSG_CALLBACK_ARG:
1054 s->msg_callback_arg = parg;
1055 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -07001056
Adam Langleyfcf25832014-12-18 17:42:32 -08001057 case SSL_CTRL_OPTIONS:
1058 return s->options |= larg;
Adam Langley95c29f32014-06-20 12:00:00 -07001059
Adam Langleyfcf25832014-12-18 17:42:32 -08001060 case SSL_CTRL_CLEAR_OPTIONS:
1061 return s->options &= ~larg;
Adam Langley95c29f32014-06-20 12:00:00 -07001062
Adam Langleyfcf25832014-12-18 17:42:32 -08001063 case SSL_CTRL_MODE:
1064 return s->mode |= larg;
Adam Langley95c29f32014-06-20 12:00:00 -07001065
Adam Langleyfcf25832014-12-18 17:42:32 -08001066 case SSL_CTRL_CLEAR_MODE:
1067 return s->mode &= ~larg;
Adam Langley95c29f32014-06-20 12:00:00 -07001068
Adam Langleyfcf25832014-12-18 17:42:32 -08001069 case SSL_CTRL_GET_MAX_CERT_LIST:
1070 return s->max_cert_list;
Adam Langley95c29f32014-06-20 12:00:00 -07001071
Adam Langleyfcf25832014-12-18 17:42:32 -08001072 case SSL_CTRL_SET_MAX_CERT_LIST:
1073 l = s->max_cert_list;
1074 s->max_cert_list = larg;
1075 return l;
Adam Langley95c29f32014-06-20 12:00:00 -07001076
Adam Langleyfcf25832014-12-18 17:42:32 -08001077 case SSL_CTRL_SET_MTU:
1078 if (larg < (long)dtls1_min_mtu()) {
1079 return 0;
1080 }
1081 if (SSL_IS_DTLS(s)) {
1082 s->d1->mtu = larg;
1083 return larg;
1084 }
1085 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001086
Adam Langleyfcf25832014-12-18 17:42:32 -08001087 case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
1088 if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) {
1089 return 0;
1090 }
1091 s->max_send_fragment = larg;
1092 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -07001093
Adam Langleyfcf25832014-12-18 17:42:32 -08001094 case SSL_CTRL_GET_RI_SUPPORT:
1095 if (s->s3) {
1096 return s->s3->send_connection_binding;
1097 }
1098 return 0;
1099
1100 case SSL_CTRL_CERT_FLAGS:
1101 return s->cert->cert_flags |= larg;
1102
1103 case SSL_CTRL_CLEAR_CERT_FLAGS:
1104 return s->cert->cert_flags &= ~larg;
1105
1106 case SSL_CTRL_GET_RAW_CIPHERLIST:
1107 if (parg) {
1108 if (s->cert->ciphers_raw == NULL) {
1109 return 0;
1110 }
1111 *(uint8_t **)parg = s->cert->ciphers_raw;
1112 return (int)s->cert->ciphers_rawlen;
1113 }
1114
1115 /* Passing a NULL |parg| returns the size of a single
1116 * cipher suite value. */
1117 return 2;
1118
1119 default:
1120 return s->method->ssl_ctrl(s, cmd, larg, parg);
1121 }
1122}
1123
1124long SSL_callback_ctrl(SSL *s, int cmd, void (*fp)(void)) {
1125 switch (cmd) {
1126 case SSL_CTRL_SET_MSG_CALLBACK:
1127 s->msg_callback =
1128 (void (*)(int write_p, int version, int content_type, const void *buf,
1129 size_t len, SSL *ssl, void *arg))(fp);
1130 return 1;
1131
1132 default:
1133 return s->method->ssl_callback_ctrl(s, cmd, fp);
1134 }
1135}
1136
1137LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) { return ctx->sessions; }
1138
1139long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) {
1140 long l;
1141
1142 switch (cmd) {
1143 case SSL_CTRL_GET_READ_AHEAD:
1144 return ctx->read_ahead;
1145
1146 case SSL_CTRL_SET_READ_AHEAD:
1147 l = ctx->read_ahead;
1148 ctx->read_ahead = larg;
1149 return l;
1150
1151 case SSL_CTRL_SET_MSG_CALLBACK_ARG:
1152 ctx->msg_callback_arg = parg;
1153 return 1;
1154
1155 case SSL_CTRL_GET_MAX_CERT_LIST:
1156 return ctx->max_cert_list;
1157
1158 case SSL_CTRL_SET_MAX_CERT_LIST:
1159 l = ctx->max_cert_list;
1160 ctx->max_cert_list = larg;
1161 return l;
1162
1163 case SSL_CTRL_SET_SESS_CACHE_SIZE:
1164 l = ctx->session_cache_size;
1165 ctx->session_cache_size = larg;
1166 return l;
1167
1168 case SSL_CTRL_GET_SESS_CACHE_SIZE:
1169 return ctx->session_cache_size;
1170
1171 case SSL_CTRL_SET_SESS_CACHE_MODE:
1172 l = ctx->session_cache_mode;
1173 ctx->session_cache_mode = larg;
1174 return l;
1175
1176 case SSL_CTRL_GET_SESS_CACHE_MODE:
1177 return ctx->session_cache_mode;
1178
1179 case SSL_CTRL_SESS_NUMBER:
1180 return lh_SSL_SESSION_num_items(ctx->sessions);
1181
1182 case SSL_CTRL_SESS_CONNECT:
1183 return ctx->stats.sess_connect;
1184
1185 case SSL_CTRL_SESS_CONNECT_GOOD:
1186 return ctx->stats.sess_connect_good;
1187
1188 case SSL_CTRL_SESS_CONNECT_RENEGOTIATE:
1189 return ctx->stats.sess_connect_renegotiate;
1190
1191 case SSL_CTRL_SESS_ACCEPT:
1192 return ctx->stats.sess_accept;
1193
1194 case SSL_CTRL_SESS_ACCEPT_GOOD:
1195 return ctx->stats.sess_accept_good;
1196
1197 case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE:
1198 return ctx->stats.sess_accept_renegotiate;
1199
1200 case SSL_CTRL_SESS_HIT:
1201 return ctx->stats.sess_hit;
1202
1203 case SSL_CTRL_SESS_CB_HIT:
1204 return ctx->stats.sess_cb_hit;
1205
1206 case SSL_CTRL_SESS_MISSES:
1207 return ctx->stats.sess_miss;
1208
1209 case SSL_CTRL_SESS_TIMEOUTS:
1210 return ctx->stats.sess_timeout;
1211
1212 case SSL_CTRL_SESS_CACHE_FULL:
1213 return ctx->stats.sess_cache_full;
1214
1215 case SSL_CTRL_OPTIONS:
1216 return ctx->options |= larg;
1217
1218 case SSL_CTRL_CLEAR_OPTIONS:
1219 return ctx->options &= ~larg;
1220
1221 case SSL_CTRL_MODE:
1222 return ctx->mode |= larg;
1223
1224 case SSL_CTRL_CLEAR_MODE:
1225 return ctx->mode &= ~larg;
1226
1227 case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
1228 if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) {
1229 return 0;
1230 }
1231 ctx->max_send_fragment = larg;
1232 return 1;
1233
1234 case SSL_CTRL_CERT_FLAGS:
1235 return ctx->cert->cert_flags |= larg;
1236
1237 case SSL_CTRL_CLEAR_CERT_FLAGS:
1238 return ctx->cert->cert_flags &= ~larg;
1239
1240 default:
1241 return ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg);
1242 }
1243}
1244
1245long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) {
1246 switch (cmd) {
1247 case SSL_CTRL_SET_MSG_CALLBACK:
1248 ctx->msg_callback =
1249 (void (*)(int write_p, int version, int content_type, const void *buf,
1250 size_t len, SSL *ssl, void *arg))(fp);
1251 return 1;
1252
1253 default:
1254 return ctx->method->ssl_ctx_callback_ctrl(ctx, cmd, fp);
1255 }
1256}
1257
1258int ssl_cipher_id_cmp(const void *in_a, const void *in_b) {
1259 long l;
1260 const SSL_CIPHER *a = in_a;
1261 const SSL_CIPHER *b = in_b;
1262 const long a_id = a->id;
1263 const long b_id = b->id;
1264
1265 l = a_id - b_id;
1266 if (l == 0L) {
1267 return 0;
1268 } else {
1269 return (l > 0) ? 1 : -1;
1270 }
1271}
1272
1273int ssl_cipher_ptr_id_cmp(const SSL_CIPHER **ap, const SSL_CIPHER **bp) {
1274 long l;
1275 const long a_id = (*ap)->id;
1276 const long b_id = (*bp)->id;
1277
1278 l = a_id - b_id;
1279 if (l == 0) {
1280 return 0;
1281 } else {
1282 return (l > 0) ? 1 : -1;
1283 }
1284}
1285
1286/* return a STACK of the ciphers available for the SSL and in order of
Adam Langley95c29f32014-06-20 12:00:00 -07001287 * preference */
Adam Langleyfcf25832014-12-18 17:42:32 -08001288STACK_OF(SSL_CIPHER) * SSL_get_ciphers(const SSL *s) {
1289 if (s == NULL) {
1290 return NULL;
1291 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001292
Adam Langleyfcf25832014-12-18 17:42:32 -08001293 if (s->cipher_list != NULL) {
1294 return s->cipher_list->ciphers;
1295 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001296
Adam Langleyfcf25832014-12-18 17:42:32 -08001297 if (s->version >= TLS1_1_VERSION && s->ctx != NULL &&
1298 s->ctx->cipher_list_tls11 != NULL) {
1299 return s->ctx->cipher_list_tls11->ciphers;
1300 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001301
Adam Langleyfcf25832014-12-18 17:42:32 -08001302 if (s->ctx != NULL && s->ctx->cipher_list != NULL) {
1303 return s->ctx->cipher_list->ciphers;
1304 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001305
Adam Langleyfcf25832014-12-18 17:42:32 -08001306 return NULL;
1307}
Adam Langley95c29f32014-06-20 12:00:00 -07001308
Adam Langleyfcf25832014-12-18 17:42:32 -08001309/* return a STACK of the ciphers available for the SSL and in order of
Adam Langley95c29f32014-06-20 12:00:00 -07001310 * algorithm id */
Adam Langleyfcf25832014-12-18 17:42:32 -08001311STACK_OF(SSL_CIPHER) * ssl_get_ciphers_by_id(SSL *s) {
1312 if (s == NULL) {
1313 return NULL;
1314 }
Adam Langley95c29f32014-06-20 12:00:00 -07001315
Adam Langleyfcf25832014-12-18 17:42:32 -08001316 if (s->cipher_list_by_id != NULL) {
1317 return s->cipher_list_by_id;
1318 }
Adam Langley95c29f32014-06-20 12:00:00 -07001319
Adam Langleyfcf25832014-12-18 17:42:32 -08001320 if (s->ctx != NULL && s->ctx->cipher_list_by_id != NULL) {
1321 return s->ctx->cipher_list_by_id;
1322 }
Adam Langley95c29f32014-06-20 12:00:00 -07001323
Adam Langleyfcf25832014-12-18 17:42:32 -08001324 return NULL;
1325}
Adam Langley95c29f32014-06-20 12:00:00 -07001326
Adam Langleyfcf25832014-12-18 17:42:32 -08001327/* The old interface to get the same thing as SSL_get_ciphers() */
1328const char *SSL_get_cipher_list(const SSL *s, int n) {
1329 const SSL_CIPHER *c;
1330 STACK_OF(SSL_CIPHER) * sk;
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001331
Adam Langleyfcf25832014-12-18 17:42:32 -08001332 if (s == NULL) {
1333 return NULL;
1334 }
Adam Langley95c29f32014-06-20 12:00:00 -07001335
Adam Langleyfcf25832014-12-18 17:42:32 -08001336 sk = SSL_get_ciphers(s);
1337 if (sk == NULL || n < 0 || (size_t)n >= sk_SSL_CIPHER_num(sk)) {
1338 return NULL;
1339 }
Adam Langley95c29f32014-06-20 12:00:00 -07001340
Adam Langleyfcf25832014-12-18 17:42:32 -08001341 c = sk_SSL_CIPHER_value(sk, n);
1342 if (c == NULL) {
1343 return NULL;
1344 }
Adam Langley95c29f32014-06-20 12:00:00 -07001345
Adam Langleyfcf25832014-12-18 17:42:32 -08001346 return c->name;
1347}
David Benjamin5491e3f2014-09-29 19:33:09 -04001348
Adam Langleyfcf25832014-12-18 17:42:32 -08001349/* specify the ciphers to be used by default by the SSL_CTX */
1350int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) {
1351 STACK_OF(SSL_CIPHER) *sk;
Adam Langley95c29f32014-06-20 12:00:00 -07001352
Adam Langleyfcf25832014-12-18 17:42:32 -08001353 sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list,
1354 &ctx->cipher_list_by_id, str, ctx->cert);
1355 /* ssl_create_cipher_list may return an empty stack if it was unable to find
1356 * a cipher matching the given rule string (for example if the rule string
1357 * specifies a cipher which has been disabled). This is not an error as far
1358 * as ssl_create_cipher_list is concerned, and hence ctx->cipher_list and
1359 * ctx->cipher_list_by_id has been updated. */
1360 if (sk == NULL) {
1361 return 0;
1362 } else if (sk_SSL_CIPHER_num(sk) == 0) {
1363 OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_cipher_list, SSL_R_NO_CIPHER_MATCH);
1364 return 0;
1365 }
Adam Langley95c29f32014-06-20 12:00:00 -07001366
Adam Langleyfcf25832014-12-18 17:42:32 -08001367 return 1;
1368}
David Benjamin39482a12014-07-20 13:30:15 -04001369
Adam Langleyfcf25832014-12-18 17:42:32 -08001370int SSL_CTX_set_cipher_list_tls11(SSL_CTX *ctx, const char *str) {
1371 STACK_OF(SSL_CIPHER) *sk;
Adam Langley95c29f32014-06-20 12:00:00 -07001372
Adam Langleyfcf25832014-12-18 17:42:32 -08001373 sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list_tls11, NULL, str,
1374 ctx->cert);
1375 if (sk == NULL) {
1376 return 0;
1377 } else if (sk_SSL_CIPHER_num(sk) == 0) {
1378 OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_cipher_list_tls11,
1379 SSL_R_NO_CIPHER_MATCH);
1380 return 0;
1381 }
David Benjamin9f2c0d72014-10-21 22:00:19 -04001382
Adam Langleyfcf25832014-12-18 17:42:32 -08001383 return 1;
1384}
Adam Langley95c29f32014-06-20 12:00:00 -07001385
Adam Langleyfcf25832014-12-18 17:42:32 -08001386/* specify the ciphers to be used by the SSL */
1387int SSL_set_cipher_list(SSL *s, const char *str) {
1388 STACK_OF(SSL_CIPHER) *sk;
Adam Langley95c29f32014-06-20 12:00:00 -07001389
Adam Langleyfcf25832014-12-18 17:42:32 -08001390 sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list,
1391 &s->cipher_list_by_id, str, s->cert);
David Benjamin39482a12014-07-20 13:30:15 -04001392
Adam Langleyfcf25832014-12-18 17:42:32 -08001393 /* see comment in SSL_CTX_set_cipher_list */
1394 if (sk == NULL) {
1395 return 0;
1396 } else if (sk_SSL_CIPHER_num(sk) == 0) {
1397 OPENSSL_PUT_ERROR(SSL, SSL_set_cipher_list, SSL_R_NO_CIPHER_MATCH);
1398 return 0;
1399 }
David Benjamin39482a12014-07-20 13:30:15 -04001400
Adam Langleyfcf25832014-12-18 17:42:32 -08001401 return 1;
1402}
Adam Langley95c29f32014-06-20 12:00:00 -07001403
Adam Langleyfcf25832014-12-18 17:42:32 -08001404int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p) {
1405 size_t i;
1406 const SSL_CIPHER *c;
1407 CERT *ct = s->cert;
1408 uint8_t *q;
1409 /* Set disabled masks for this session */
1410 ssl_set_client_disabled(s);
Adam Langley29707792014-06-20 12:00:00 -07001411
Adam Langleyfcf25832014-12-18 17:42:32 -08001412 if (sk == NULL) {
1413 return 0;
1414 }
1415 q = p;
Adam Langley95c29f32014-06-20 12:00:00 -07001416
Adam Langleyfcf25832014-12-18 17:42:32 -08001417 for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
1418 c = sk_SSL_CIPHER_value(sk, i);
1419 /* Skip disabled ciphers */
1420 if (c->algorithm_ssl & ct->mask_ssl ||
1421 c->algorithm_mkey & ct->mask_k ||
1422 c->algorithm_auth & ct->mask_a) {
1423 continue;
1424 }
1425 s2n(ssl3_get_cipher_value(c), p);
1426 }
1427
1428 /* If all ciphers were disabled, return the error to the caller. */
1429 if (p == q) {
1430 return 0;
1431 }
1432
1433 /* Add SCSVs. */
1434 if (!s->renegotiate) {
1435 s2n(SSL3_CK_SCSV & 0xffff, p);
1436 }
1437
1438 if (s->fallback_scsv) {
1439 s2n(SSL3_CK_FALLBACK_SCSV & 0xffff, p);
1440 }
1441
1442 return p - q;
1443}
1444
1445STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
1446 CBS cipher_suites = *cbs;
1447 const SSL_CIPHER *c;
1448 STACK_OF(SSL_CIPHER) * sk;
1449
1450 if (s->s3) {
1451 s->s3->send_connection_binding = 0;
1452 }
1453
1454 if (CBS_len(&cipher_suites) % 2 != 0) {
1455 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
1456 SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
1457 return NULL;
1458 }
1459
1460 sk = sk_SSL_CIPHER_new_null();
1461 if (sk == NULL) {
1462 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
1463 goto err;
1464 }
1465
1466 if (!CBS_stow(&cipher_suites, &s->cert->ciphers_raw,
1467 &s->cert->ciphers_rawlen)) {
1468 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
1469 goto err;
1470 }
1471
1472 while (CBS_len(&cipher_suites) > 0) {
1473 uint16_t cipher_suite;
1474
1475 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
1476 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_INTERNAL_ERROR);
1477 goto err;
1478 }
1479
1480 /* Check for SCSV. */
1481 if (s->s3 && cipher_suite == (SSL3_CK_SCSV & 0xffff)) {
1482 /* SCSV is fatal if renegotiating. */
1483 if (s->renegotiate) {
1484 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
1485 SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
1486 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
1487 goto err;
1488 }
1489 s->s3->send_connection_binding = 1;
1490 continue;
1491 }
1492
1493 /* Check for FALLBACK_SCSV. */
1494 if (s->s3 && cipher_suite == (SSL3_CK_FALLBACK_SCSV & 0xffff)) {
1495 uint16_t max_version = ssl3_get_max_server_version(s);
1496 if (SSL_IS_DTLS(s) ? (uint16_t)s->version > max_version
1497 : (uint16_t)s->version < max_version) {
1498 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
1499 SSL_R_INAPPROPRIATE_FALLBACK);
1500 ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_INAPPROPRIATE_FALLBACK);
1501 goto err;
1502 }
1503 continue;
1504 }
1505
1506 c = ssl3_get_cipher_by_value(cipher_suite);
1507 if (c != NULL && !sk_SSL_CIPHER_push(sk, c)) {
1508 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
1509 goto err;
1510 }
1511 }
1512
1513 return sk;
David Benjamin9f2c0d72014-10-21 22:00:19 -04001514
Adam Langley95c29f32014-06-20 12:00:00 -07001515err:
Adam Langleyfcf25832014-12-18 17:42:32 -08001516 if (sk != NULL) {
1517 sk_SSL_CIPHER_free(sk);
1518 }
1519 return NULL;
1520}
Adam Langley95c29f32014-06-20 12:00:00 -07001521
1522
Adam Langleyfcf25832014-12-18 17:42:32 -08001523/* return a servername extension value if provided in Client Hello, or NULL. So
1524 * far, only host_name types are defined (RFC 3546). */
1525const char *SSL_get_servername(const SSL *s, const int type) {
1526 if (type != TLSEXT_NAMETYPE_host_name) {
1527 return NULL;
1528 }
Adam Langley95c29f32014-06-20 12:00:00 -07001529
Adam Langleyfcf25832014-12-18 17:42:32 -08001530 return s->session && !s->tlsext_hostname ? s->session->tlsext_hostname
1531 : s->tlsext_hostname;
1532}
Adam Langley95c29f32014-06-20 12:00:00 -07001533
Adam Langleyfcf25832014-12-18 17:42:32 -08001534int SSL_get_servername_type(const SSL *s) {
1535 if (s->session &&
1536 (!s->tlsext_hostname ? s->session->tlsext_hostname : s->tlsext_hostname)) {
1537 return TLSEXT_NAMETYPE_host_name;
1538 }
Adam Langley95c29f32014-06-20 12:00:00 -07001539
Adam Langleyfcf25832014-12-18 17:42:32 -08001540 return -1;
1541}
Adam Langley95c29f32014-06-20 12:00:00 -07001542
Adam Langleyfcf25832014-12-18 17:42:32 -08001543void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx) {
1544 ctx->signed_cert_timestamps_enabled = 1;
1545}
HÃ¥vard Molland9169c962014-08-14 14:42:37 +02001546
Adam Langleyfcf25832014-12-18 17:42:32 -08001547int SSL_enable_signed_cert_timestamps(SSL *ssl) {
1548 ssl->signed_cert_timestamps_enabled = 1;
1549 return 1;
1550}
HÃ¥vard Molland9169c962014-08-14 14:42:37 +02001551
Adam Langleyfcf25832014-12-18 17:42:32 -08001552void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx) {
1553 ctx->ocsp_stapling_enabled = 1;
1554}
David Benjamin6c7aed02014-08-27 16:42:38 -04001555
Adam Langleyfcf25832014-12-18 17:42:32 -08001556int SSL_enable_ocsp_stapling(SSL *ssl) {
1557 ssl->ocsp_stapling_enabled = 1;
1558 return 1;
1559}
David Benjamin6c7aed02014-08-27 16:42:38 -04001560
Adam Langleyfcf25832014-12-18 17:42:32 -08001561void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out,
1562 size_t *out_len) {
1563 SSL_SESSION *session = ssl->session;
Adam Langley3cb50e02014-08-26 14:00:31 -07001564
Adam Langleyfcf25832014-12-18 17:42:32 -08001565 *out_len = 0;
1566 *out = NULL;
1567 if (ssl->server || !session || !session->tlsext_signed_cert_timestamp_list) {
1568 return;
1569 }
HÃ¥vard Molland9169c962014-08-14 14:42:37 +02001570
Adam Langleyfcf25832014-12-18 17:42:32 -08001571 *out = session->tlsext_signed_cert_timestamp_list;
1572 *out_len = session->tlsext_signed_cert_timestamp_list_length;
1573}
David Benjamin6c7aed02014-08-27 16:42:38 -04001574
Adam Langleyfcf25832014-12-18 17:42:32 -08001575void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
1576 size_t *out_len) {
1577 SSL_SESSION *session = ssl->session;
1578
1579 *out_len = 0;
1580 *out = NULL;
1581 if (ssl->server || !session || !session->ocsp_response) {
1582 return;
1583 }
1584 *out = session->ocsp_response;
1585 *out_len = session->ocsp_response_length;
1586}
David Benjamin6c7aed02014-08-27 16:42:38 -04001587
Adam Langley95c29f32014-06-20 12:00:00 -07001588/* SSL_select_next_proto implements the standard protocol selection. It is
1589 * expected that this function is called from the callback set by
1590 * SSL_CTX_set_next_proto_select_cb.
1591 *
1592 * The protocol data is assumed to be a vector of 8-bit, length prefixed byte
1593 * strings. The length byte itself is not included in the length. A byte
1594 * string of length 0 is invalid. No byte string may be truncated.
1595 *
1596 * The current, but experimental algorithm for selecting the protocol is:
1597 *
1598 * 1) If the server doesn't support NPN then this is indicated to the
1599 * callback. In this case, the client application has to abort the connection
1600 * or have a default application level protocol.
1601 *
1602 * 2) If the server supports NPN, but advertises an empty list then the
1603 * client selects the first protcol in its list, but indicates via the
1604 * API that this fallback case was enacted.
1605 *
1606 * 3) Otherwise, the client finds the first protocol in the server's list
1607 * that it supports and selects this protocol. This is because it's
1608 * assumed that the server has better information about which protocol
1609 * a client should use.
1610 *
1611 * 4) If the client doesn't support any of the server's advertised
1612 * protocols, then this is treated the same as case 2.
1613 *
1614 * It returns either
1615 * OPENSSL_NPN_NEGOTIATED if a common protocol was found, or
1616 * OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
1617 */
Adam Langleyfcf25832014-12-18 17:42:32 -08001618int SSL_select_next_proto(uint8_t **out, uint8_t *outlen, const uint8_t *server,
1619 unsigned int server_len, const uint8_t *client,
1620 unsigned int client_len) {
1621 unsigned int i, j;
1622 const uint8_t *result;
1623 int status = OPENSSL_NPN_UNSUPPORTED;
Adam Langley95c29f32014-06-20 12:00:00 -07001624
Adam Langleyfcf25832014-12-18 17:42:32 -08001625 /* For each protocol in server preference order, see if we support it. */
1626 for (i = 0; i < server_len;) {
1627 for (j = 0; j < client_len;) {
1628 if (server[i] == client[j] &&
1629 memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) {
1630 /* We found a match */
1631 result = &server[i];
1632 status = OPENSSL_NPN_NEGOTIATED;
1633 goto found;
1634 }
1635 j += client[j];
1636 j++;
1637 }
1638 i += server[i];
1639 i++;
1640 }
Adam Langley95c29f32014-06-20 12:00:00 -07001641
Adam Langleyfcf25832014-12-18 17:42:32 -08001642 /* There's no overlap between our protocols and the server's list. */
1643 result = client;
1644 status = OPENSSL_NPN_NO_OVERLAP;
Adam Langley95c29f32014-06-20 12:00:00 -07001645
Adam Langleyfcf25832014-12-18 17:42:32 -08001646found:
1647 *out = (uint8_t *)result + 1;
1648 *outlen = result[0];
1649 return status;
1650}
Adam Langley95c29f32014-06-20 12:00:00 -07001651
Adam Langley95c29f32014-06-20 12:00:00 -07001652/* SSL_get0_next_proto_negotiated sets *data and *len to point to the client's
1653 * requested protocol for this connection and returns 0. If the client didn't
1654 * request any protocol, then *data is set to NULL.
1655 *
1656 * Note that the client can request any protocol it chooses. The value returned
1657 * from this function need not be a member of the list of supported protocols
Adam Langleyfcf25832014-12-18 17:42:32 -08001658 * provided by the callback. */
1659void SSL_get0_next_proto_negotiated(const SSL *s, const uint8_t **data,
1660 unsigned *len) {
1661 *data = s->next_proto_negotiated;
1662 if (!*data) {
1663 *len = 0;
1664 } else {
1665 *len = s->next_proto_negotiated_len;
1666 }
Adam Langley95c29f32014-06-20 12:00:00 -07001667}
1668
1669/* SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when a
1670 * TLS server needs a list of supported protocols for Next Protocol
1671 * Negotiation. The returned list must be in wire format. The list is returned
1672 * by setting |out| to point to it and |outlen| to its length. This memory will
1673 * not be modified, but one should assume that the SSL* keeps a reference to
1674 * it.
1675 *
Adam Langleyfcf25832014-12-18 17:42:32 -08001676 * The callback should return SSL_TLSEXT_ERR_OK if it wishes to advertise.
1677 * Otherwise, no such extension will be included in the ServerHello. */
1678void SSL_CTX_set_next_protos_advertised_cb(
1679 SSL_CTX *ctx,
1680 int (*cb)(SSL *ssl, const uint8_t **out, unsigned int *outlen, void *arg),
1681 void *arg) {
1682 ctx->next_protos_advertised_cb = cb;
1683 ctx->next_protos_advertised_cb_arg = arg;
1684}
Adam Langley95c29f32014-06-20 12:00:00 -07001685
1686/* SSL_CTX_set_next_proto_select_cb sets a callback that is called when a
1687 * client needs to select a protocol from the server's provided list. |out|
1688 * must be set to point to the selected protocol (which may be within |in|).
1689 * The length of the protocol name must be written into |outlen|. The server's
1690 * advertised protocols are provided in |in| and |inlen|. The callback can
1691 * assume that |in| is syntactically valid.
1692 *
1693 * The client must select a protocol. It is fatal to the connection if this
1694 * callback returns a value other than SSL_TLSEXT_ERR_OK.
1695 */
Adam Langleyfcf25832014-12-18 17:42:32 -08001696void SSL_CTX_set_next_proto_select_cb(
1697 SSL_CTX *ctx, int (*cb)(SSL *s, uint8_t **out, uint8_t *outlen,
1698 const uint8_t *in, unsigned int inlen, void *arg),
1699 void *arg) {
1700 ctx->next_proto_select_cb = cb;
1701 ctx->next_proto_select_cb_arg = arg;
1702}
Adam Langley95c29f32014-06-20 12:00:00 -07001703
Adam Langley95c29f32014-06-20 12:00:00 -07001704/* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
1705 * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
1706 * length-prefixed strings).
1707 *
1708 * Returns 0 on success. */
Adam Langleyfcf25832014-12-18 17:42:32 -08001709int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos,
1710 unsigned protos_len) {
1711 if (ctx->alpn_client_proto_list) {
1712 OPENSSL_free(ctx->alpn_client_proto_list);
1713 }
Adam Langley95c29f32014-06-20 12:00:00 -07001714
Adam Langleyfcf25832014-12-18 17:42:32 -08001715 ctx->alpn_client_proto_list = BUF_memdup(protos, protos_len);
1716 if (!ctx->alpn_client_proto_list) {
1717 return 1;
1718 }
1719 ctx->alpn_client_proto_list_len = protos_len;
Adam Langley95c29f32014-06-20 12:00:00 -07001720
Adam Langleyfcf25832014-12-18 17:42:32 -08001721 return 0;
1722}
Adam Langley95c29f32014-06-20 12:00:00 -07001723
1724/* SSL_set_alpn_protos sets the ALPN protocol list on |ssl| to |protos|.
1725 * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
1726 * length-prefixed strings).
1727 *
1728 * Returns 0 on success. */
Adam Langleyfcf25832014-12-18 17:42:32 -08001729int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) {
1730 if (ssl->alpn_client_proto_list) {
1731 OPENSSL_free(ssl->alpn_client_proto_list);
1732 }
Adam Langley95c29f32014-06-20 12:00:00 -07001733
Adam Langleyfcf25832014-12-18 17:42:32 -08001734 ssl->alpn_client_proto_list = BUF_memdup(protos, protos_len);
1735 if (!ssl->alpn_client_proto_list) {
1736 return 1;
1737 }
1738 ssl->alpn_client_proto_list_len = protos_len;
Adam Langley95c29f32014-06-20 12:00:00 -07001739
Adam Langleyfcf25832014-12-18 17:42:32 -08001740 return 0;
1741}
Adam Langley95c29f32014-06-20 12:00:00 -07001742
1743/* SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called
1744 * during ClientHello processing in order to select an ALPN protocol from the
1745 * client's list of offered protocols. */
Adam Langleyfcf25832014-12-18 17:42:32 -08001746void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
1747 int (*cb)(SSL *ssl, const uint8_t **out,
1748 uint8_t *outlen, const uint8_t *in,
1749 unsigned int inlen, void *arg),
1750 void *arg) {
1751 ctx->alpn_select_cb = cb;
1752 ctx->alpn_select_cb_arg = arg;
1753}
Adam Langley95c29f32014-06-20 12:00:00 -07001754
1755/* SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|.
1756 * On return it sets |*data| to point to |*len| bytes of protocol name (not
1757 * including the leading length-prefix byte). If the server didn't respond with
1758 * a negotiated protocol then |*len| will be zero. */
Adam Langleyfcf25832014-12-18 17:42:32 -08001759void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **data,
1760 unsigned *len) {
1761 *data = NULL;
1762 if (ssl->s3) {
1763 *data = ssl->s3->alpn_selected;
1764 }
1765 if (*data == NULL) {
1766 *len = 0;
1767 } else {
1768 *len = ssl->s3->alpn_selected_len;
1769 }
1770}
Adam Langley95c29f32014-06-20 12:00:00 -07001771
Adam Langleyfcf25832014-12-18 17:42:32 -08001772int SSL_export_keying_material(SSL *s, uint8_t *out, size_t olen,
1773 const char *label, size_t llen, const uint8_t *p,
1774 size_t plen, int use_context) {
1775 if (s->version < TLS1_VERSION) {
1776 return -1;
1777 }
Adam Langley95c29f32014-06-20 12:00:00 -07001778
Adam Langleyfcf25832014-12-18 17:42:32 -08001779 return s->enc_method->export_keying_material(s, out, olen, label, llen, p,
1780 plen, use_context);
1781}
Adam Langley95c29f32014-06-20 12:00:00 -07001782
Adam Langleyfcf25832014-12-18 17:42:32 -08001783static uint32_t ssl_session_hash(const SSL_SESSION *a) {
1784 uint32_t hash =
1785 ((uint32_t)a->session_id[0]) ||
1786 ((uint32_t)a->session_id[1] << 8) ||
1787 ((uint32_t)a->session_id[2] << 16) ||
1788 ((uint32_t)a->session_id[3] << 24);
Adam Langley95c29f32014-06-20 12:00:00 -07001789
Adam Langleyfcf25832014-12-18 17:42:32 -08001790 return hash;
1791}
Adam Langley95c29f32014-06-20 12:00:00 -07001792
1793/* NB: If this function (or indeed the hash function which uses a sort of
1794 * coarser function than this one) is changed, ensure
1795 * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
1796 * able to construct an SSL_SESSION that will collide with any existing session
1797 * with a matching session ID. */
Adam Langleyfcf25832014-12-18 17:42:32 -08001798static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) {
1799 if (a->ssl_version != b->ssl_version) {
1800 return 1;
1801 }
Adam Langley95c29f32014-06-20 12:00:00 -07001802
Adam Langleyfcf25832014-12-18 17:42:32 -08001803 if (a->session_id_length != b->session_id_length) {
1804 return 1;
1805 }
Adam Langley95c29f32014-06-20 12:00:00 -07001806
Adam Langleyfcf25832014-12-18 17:42:32 -08001807 return memcmp(a->session_id, b->session_id, a->session_id_length);
1808}
Adam Langley95c29f32014-06-20 12:00:00 -07001809
Adam Langleyfcf25832014-12-18 17:42:32 -08001810SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) {
1811 SSL_CTX *ret = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001812
Adam Langleyfcf25832014-12-18 17:42:32 -08001813 if (meth == NULL) {
1814 OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_NULL_SSL_METHOD_PASSED);
1815 return NULL;
1816 }
Adam Langley95c29f32014-06-20 12:00:00 -07001817
Adam Langleyfcf25832014-12-18 17:42:32 -08001818 if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) {
1819 OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
1820 goto err;
1821 }
Adam Langley95c29f32014-06-20 12:00:00 -07001822
Adam Langleyfcf25832014-12-18 17:42:32 -08001823 ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
1824 if (ret == NULL) {
1825 goto err;
1826 }
Adam Langley95c29f32014-06-20 12:00:00 -07001827
Adam Langleyfcf25832014-12-18 17:42:32 -08001828 memset(ret, 0, sizeof(SSL_CTX));
Adam Langley95c29f32014-06-20 12:00:00 -07001829
Adam Langleyfcf25832014-12-18 17:42:32 -08001830 ret->method = meth->method;
Adam Langley95c29f32014-06-20 12:00:00 -07001831
Adam Langleyfcf25832014-12-18 17:42:32 -08001832 ret->cert_store = NULL;
1833 ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
1834 ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
1835 ret->session_cache_head = NULL;
1836 ret->session_cache_tail = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001837
Adam Langleyfcf25832014-12-18 17:42:32 -08001838 /* We take the system default */
1839 ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
Adam Langley95c29f32014-06-20 12:00:00 -07001840
Adam Langleyfcf25832014-12-18 17:42:32 -08001841 ret->new_session_cb = 0;
1842 ret->remove_session_cb = 0;
1843 ret->get_session_cb = 0;
1844 ret->generate_session_id = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001845
Adam Langleyfcf25832014-12-18 17:42:32 -08001846 memset((char *)&ret->stats, 0, sizeof(ret->stats));
Adam Langley95c29f32014-06-20 12:00:00 -07001847
Adam Langleyfcf25832014-12-18 17:42:32 -08001848 ret->references = 1;
1849 ret->quiet_shutdown = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001850
Adam Langleyfcf25832014-12-18 17:42:32 -08001851 ret->info_callback = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001852
Adam Langleyfcf25832014-12-18 17:42:32 -08001853 ret->app_verify_callback = 0;
1854 ret->app_verify_arg = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001855
Adam Langleyfcf25832014-12-18 17:42:32 -08001856 ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
1857 ret->read_ahead = 0;
1858 ret->msg_callback = 0;
1859 ret->msg_callback_arg = NULL;
1860 ret->verify_mode = SSL_VERIFY_NONE;
1861 ret->sid_ctx_length = 0;
1862 ret->default_verify_callback = NULL;
1863 ret->cert = ssl_cert_new();
1864 if (ret->cert == NULL) {
1865 goto err;
1866 }
Adam Langley95c29f32014-06-20 12:00:00 -07001867
Adam Langleyfcf25832014-12-18 17:42:32 -08001868 ret->default_passwd_callback = 0;
1869 ret->default_passwd_callback_userdata = NULL;
1870 ret->client_cert_cb = 0;
1871 ret->app_gen_cookie_cb = 0;
1872 ret->app_verify_cookie_cb = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001873
Adam Langleyfcf25832014-12-18 17:42:32 -08001874 ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
1875 if (ret->sessions == NULL) {
1876 goto err;
1877 }
1878 ret->cert_store = X509_STORE_new();
1879 if (ret->cert_store == NULL) {
1880 goto err;
1881 }
Adam Langley95c29f32014-06-20 12:00:00 -07001882
Adam Langleyfcf25832014-12-18 17:42:32 -08001883 ssl_create_cipher_list(ret->method, &ret->cipher_list,
1884 &ret->cipher_list_by_id, SSL_DEFAULT_CIPHER_LIST,
1885 ret->cert);
1886 if (ret->cipher_list == NULL ||
1887 sk_SSL_CIPHER_num(ret->cipher_list->ciphers) <= 0) {
1888 OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_LIBRARY_HAS_NO_CIPHERS);
1889 goto err2;
1890 }
Adam Langley95c29f32014-06-20 12:00:00 -07001891
Adam Langleyfcf25832014-12-18 17:42:32 -08001892 ret->param = X509_VERIFY_PARAM_new();
1893 if (!ret->param) {
1894 goto err;
1895 }
Adam Langley95c29f32014-06-20 12:00:00 -07001896
Adam Langleyfcf25832014-12-18 17:42:32 -08001897 ret->client_CA = sk_X509_NAME_new_null();
1898 if (ret->client_CA == NULL) {
1899 goto err;
1900 }
Adam Langley95c29f32014-06-20 12:00:00 -07001901
Adam Langleyfcf25832014-12-18 17:42:32 -08001902 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -07001903
Adam Langleyfcf25832014-12-18 17:42:32 -08001904 ret->extra_certs = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001905
Adam Langleyfcf25832014-12-18 17:42:32 -08001906 ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
David Benjamin422d3a42014-08-20 11:09:03 -04001907
Adam Langleyfcf25832014-12-18 17:42:32 -08001908 ret->tlsext_servername_callback = 0;
1909 ret->tlsext_servername_arg = NULL;
1910 /* Setup RFC4507 ticket keys */
1911 if (!RAND_bytes(ret->tlsext_tick_key_name, 16) ||
1912 !RAND_bytes(ret->tlsext_tick_hmac_key, 16) ||
1913 !RAND_bytes(ret->tlsext_tick_aes_key, 16)) {
1914 ret->options |= SSL_OP_NO_TICKET;
1915 }
Adam Langley95c29f32014-06-20 12:00:00 -07001916
Adam Langleyfcf25832014-12-18 17:42:32 -08001917 ret->tlsext_status_cb = 0;
1918 ret->tlsext_status_arg = NULL;
David Benjamin82c9e902014-12-12 15:55:27 -05001919
Adam Langleyfcf25832014-12-18 17:42:32 -08001920 ret->next_protos_advertised_cb = 0;
1921 ret->next_proto_select_cb = 0;
1922 ret->psk_identity_hint = NULL;
1923 ret->psk_client_callback = NULL;
1924 ret->psk_server_callback = NULL;
1925
1926 /* Default is to connect to non-RI servers. When RI is more widely deployed
1927 * might change this. */
1928 ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
1929
1930 /* Lock the SSL_CTX to the specified version, for compatibility with legacy
1931 * uses of SSL_METHOD. */
1932 if (meth->version != 0) {
1933 SSL_CTX_set_max_version(ret, meth->version);
1934 SSL_CTX_set_min_version(ret, meth->version);
1935 }
1936
1937 return ret;
1938
Adam Langley95c29f32014-06-20 12:00:00 -07001939err:
Adam Langleyfcf25832014-12-18 17:42:32 -08001940 OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -07001941err2:
Adam Langleyfcf25832014-12-18 17:42:32 -08001942 if (ret != NULL) {
1943 SSL_CTX_free(ret);
1944 }
1945 return NULL;
1946}
Adam Langley95c29f32014-06-20 12:00:00 -07001947
Adam Langleyfcf25832014-12-18 17:42:32 -08001948void SSL_CTX_free(SSL_CTX *a) {
1949 int i;
Adam Langley95c29f32014-06-20 12:00:00 -07001950
Adam Langleyfcf25832014-12-18 17:42:32 -08001951 if (a == NULL) {
1952 return;
1953 }
Adam Langley95c29f32014-06-20 12:00:00 -07001954
Adam Langleyfcf25832014-12-18 17:42:32 -08001955 i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_SSL_CTX);
1956 if (i > 0) {
1957 return;
1958 }
Adam Langley95c29f32014-06-20 12:00:00 -07001959
Adam Langleyfcf25832014-12-18 17:42:32 -08001960 if (a->param) {
1961 X509_VERIFY_PARAM_free(a->param);
1962 }
Adam Langley95c29f32014-06-20 12:00:00 -07001963
Adam Langleyfcf25832014-12-18 17:42:32 -08001964 /* Free internal session cache. However: the remove_cb() may reference the
1965 * ex_data of SSL_CTX, thus the ex_data store can only be removed after the
1966 * sessions were flushed. As the ex_data handling routines might also touch
1967 * the session cache, the most secure solution seems to be: empty (flush) the
1968 * cache, then free ex_data, then finally free the cache. (See ticket
1969 * [openssl.org #212].) */
1970 if (a->sessions != NULL) {
1971 SSL_CTX_flush_sessions(a, 0);
1972 }
Adam Langley95c29f32014-06-20 12:00:00 -07001973
Adam Langleyfcf25832014-12-18 17:42:32 -08001974 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -07001975
Adam Langleyfcf25832014-12-18 17:42:32 -08001976 if (a->sessions != NULL) {
1977 lh_SSL_SESSION_free(a->sessions);
1978 }
1979 if (a->cert_store != NULL) {
1980 X509_STORE_free(a->cert_store);
1981 }
1982 if (a->cipher_list != NULL) {
1983 ssl_cipher_preference_list_free(a->cipher_list);
1984 }
1985 if (a->cipher_list_by_id != NULL) {
1986 sk_SSL_CIPHER_free(a->cipher_list_by_id);
1987 }
1988 if (a->cipher_list_tls11 != NULL) {
1989 ssl_cipher_preference_list_free(a->cipher_list_tls11);
1990 }
1991 if (a->cert != NULL) {
1992 ssl_cert_free(a->cert);
1993 }
1994 if (a->client_CA != NULL) {
1995 sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free);
1996 }
1997 if (a->extra_certs != NULL) {
1998 sk_X509_pop_free(a->extra_certs, X509_free);
1999 }
2000 if (a->srtp_profiles) {
2001 sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
2002 }
2003 if (a->psk_identity_hint) {
2004 OPENSSL_free(a->psk_identity_hint);
2005 }
2006 if (a->tlsext_ecpointformatlist) {
2007 OPENSSL_free(a->tlsext_ecpointformatlist);
2008 }
2009 if (a->tlsext_ellipticcurvelist) {
2010 OPENSSL_free(a->tlsext_ellipticcurvelist);
2011 }
2012 if (a->alpn_client_proto_list != NULL) {
2013 OPENSSL_free(a->alpn_client_proto_list);
2014 }
2015 if (a->tlsext_channel_id_private) {
2016 EVP_PKEY_free(a->tlsext_channel_id_private);
2017 }
2018 if (a->keylog_bio) {
2019 BIO_free(a->keylog_bio);
2020 }
Adam Langley95c29f32014-06-20 12:00:00 -07002021
Adam Langleyfcf25832014-12-18 17:42:32 -08002022 OPENSSL_free(a);
2023}
Adam Langley95c29f32014-06-20 12:00:00 -07002024
Adam Langleyfcf25832014-12-18 17:42:32 -08002025void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) {
2026 ctx->default_passwd_callback = cb;
2027}
Adam Langley95c29f32014-06-20 12:00:00 -07002028
Adam Langleyfcf25832014-12-18 17:42:32 -08002029void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) {
2030 ctx->default_passwd_callback_userdata = u;
2031}
Adam Langley95c29f32014-06-20 12:00:00 -07002032
Adam Langleyfcf25832014-12-18 17:42:32 -08002033void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
2034 int (*cb)(X509_STORE_CTX *, void *),
2035 void *arg) {
2036 ctx->app_verify_callback = cb;
2037 ctx->app_verify_arg = arg;
2038}
Adam Langley95c29f32014-06-20 12:00:00 -07002039
Adam Langleyfcf25832014-12-18 17:42:32 -08002040void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
2041 int (*cb)(int, X509_STORE_CTX *)) {
2042 ctx->verify_mode = mode;
2043 ctx->default_verify_callback = cb;
2044}
Adam Langley95c29f32014-06-20 12:00:00 -07002045
Adam Langleyfcf25832014-12-18 17:42:32 -08002046void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) {
2047 X509_VERIFY_PARAM_set_depth(ctx->param, depth);
2048}
Adam Langley1258b6a2014-06-20 12:00:00 -07002049
Adam Langleyfcf25832014-12-18 17:42:32 -08002050void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb)(SSL *ssl, void *arg),
2051 void *arg) {
2052 ssl_cert_set_cert_cb(c->cert, cb, arg);
2053}
David Benjamin859ec3c2014-09-02 16:29:36 -04002054
Adam Langleyfcf25832014-12-18 17:42:32 -08002055void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg), void *arg) {
2056 ssl_cert_set_cert_cb(s->cert, cb, arg);
2057}
Adam Langley95c29f32014-06-20 12:00:00 -07002058
Adam Langleyfcf25832014-12-18 17:42:32 -08002059static int ssl_has_key(SSL *s, size_t idx) {
2060 CERT_PKEY *cpk = &s->cert->pkeys[idx];
2061 return cpk->x509 && cpk->privatekey;
2062}
David Benjamin033e5f42014-11-13 18:47:41 -05002063
David Benjaminf31e6812014-11-13 18:05:55 -05002064void ssl_get_compatible_server_ciphers(SSL *s, unsigned long *out_mask_k,
Adam Langleyfcf25832014-12-18 17:42:32 -08002065 unsigned long *out_mask_a) {
2066 CERT *c = s->cert;
2067 int rsa_enc, rsa_sign, dh_tmp;
2068 unsigned long mask_k, mask_a;
2069 int have_ecc_cert, ecdsa_ok;
2070 int have_ecdh_tmp;
2071 X509 *x;
Adam Langley95c29f32014-06-20 12:00:00 -07002072
Adam Langleyfcf25832014-12-18 17:42:32 -08002073 if (c == NULL) {
2074 /* TODO(davidben): Is this codepath possible? */
2075 *out_mask_k = 0;
2076 *out_mask_a = 0;
2077 return;
2078 }
Adam Langley95c29f32014-06-20 12:00:00 -07002079
Adam Langleyfcf25832014-12-18 17:42:32 -08002080 dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
Adam Langley95c29f32014-06-20 12:00:00 -07002081
Adam Langleyfcf25832014-12-18 17:42:32 -08002082 have_ecdh_tmp = (c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto);
2083 rsa_enc = ssl_has_key(s, SSL_PKEY_RSA_ENC);
2084 rsa_sign = ssl_has_key(s, SSL_PKEY_RSA_SIGN);
2085 have_ecc_cert = ssl_has_key(s, SSL_PKEY_ECC);
2086 mask_k = 0;
2087 mask_a = 0;
David Benjaminf31e6812014-11-13 18:05:55 -05002088
Adam Langleyfcf25832014-12-18 17:42:32 -08002089 if (rsa_enc) {
2090 mask_k |= SSL_kRSA;
2091 }
2092 if (dh_tmp) {
2093 mask_k |= SSL_kEDH;
2094 }
2095 if (rsa_enc || rsa_sign) {
2096 mask_a |= SSL_aRSA;
2097 }
Adam Langley95c29f32014-06-20 12:00:00 -07002098
Adam Langleyfcf25832014-12-18 17:42:32 -08002099 mask_a |= SSL_aNULL;
Adam Langley95c29f32014-06-20 12:00:00 -07002100
Adam Langleyfcf25832014-12-18 17:42:32 -08002101 /* An ECC certificate may be usable for ECDSA cipher suites depending on the
2102 * key usage extension and on the client's curve preferences. */
2103 if (have_ecc_cert) {
2104 x = c->pkeys[SSL_PKEY_ECC].x509;
2105 /* This call populates extension flags (ex_flags). */
2106 X509_check_purpose(x, -1, 0);
2107 ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE)
2108 ? (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)
2109 : 1;
2110 if (!tls1_check_ec_cert(s, x)) {
2111 ecdsa_ok = 0;
2112 }
2113 if (ecdsa_ok) {
2114 mask_a |= SSL_aECDSA;
2115 }
2116 }
Adam Langley95c29f32014-06-20 12:00:00 -07002117
Adam Langleyfcf25832014-12-18 17:42:32 -08002118 /* If we are considering an ECC cipher suite that uses an ephemeral EC
2119 * key, check it. */
2120 if (have_ecdh_tmp && tls1_check_ec_tmp_key(s)) {
2121 mask_k |= SSL_kEECDH;
2122 }
Adam Langley95c29f32014-06-20 12:00:00 -07002123
Adam Langleyfcf25832014-12-18 17:42:32 -08002124 /* PSK requires a server callback. */
2125 if (s->psk_server_callback != NULL) {
2126 mask_k |= SSL_kPSK;
2127 mask_a |= SSL_aPSK;
2128 }
Adam Langley95c29f32014-06-20 12:00:00 -07002129
Adam Langleyfcf25832014-12-18 17:42:32 -08002130 *out_mask_k = mask_k;
2131 *out_mask_a = mask_a;
2132}
Adam Langley95c29f32014-06-20 12:00:00 -07002133
2134/* This handy macro borrowed from crypto/x509v3/v3_purp.c */
2135#define ku_reject(x, usage) \
Adam Langleyfcf25832014-12-18 17:42:32 -08002136 (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
Adam Langley95c29f32014-06-20 12:00:00 -07002137
Adam Langleyfcf25832014-12-18 17:42:32 -08002138int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) {
2139 unsigned long alg_a;
2140 int signature_nid = 0, md_nid = 0, pk_nid = 0;
2141 const SSL_CIPHER *cs = s->s3->tmp.new_cipher;
Adam Langley95c29f32014-06-20 12:00:00 -07002142
Adam Langleyfcf25832014-12-18 17:42:32 -08002143 alg_a = cs->algorithm_auth;
Adam Langley95c29f32014-06-20 12:00:00 -07002144
Adam Langleyfcf25832014-12-18 17:42:32 -08002145 /* This call populates the ex_flags field correctly */
2146 X509_check_purpose(x, -1, 0);
2147 if (x->sig_alg && x->sig_alg->algorithm) {
2148 signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
2149 OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
2150 }
2151 if (alg_a & SSL_aECDSA) {
2152 /* key usage, if present, must allow signing */
2153 if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) {
2154 OPENSSL_PUT_ERROR(SSL, ssl_check_srvr_ecc_cert_and_alg,
2155 SSL_R_ECC_CERT_NOT_FOR_SIGNING);
2156 return 0;
2157 }
2158 }
Adam Langley95c29f32014-06-20 12:00:00 -07002159
Adam Langleyfcf25832014-12-18 17:42:32 -08002160 return 1; /* all checks are ok */
2161}
Adam Langley95c29f32014-06-20 12:00:00 -07002162
Adam Langleyfcf25832014-12-18 17:42:32 -08002163static int ssl_get_server_cert_index(const SSL *s) {
2164 int idx;
2165 idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
2166 if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509) {
2167 idx = SSL_PKEY_RSA_SIGN;
2168 }
2169 if (idx == -1) {
2170 OPENSSL_PUT_ERROR(SSL, ssl_get_server_cert_index, ERR_R_INTERNAL_ERROR);
2171 }
2172 return idx;
2173}
Adam Langley95c29f32014-06-20 12:00:00 -07002174
Adam Langleyfcf25832014-12-18 17:42:32 -08002175CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) {
2176 int i = ssl_get_server_cert_index(s);
Adam Langley95c29f32014-06-20 12:00:00 -07002177
Adam Langleyfcf25832014-12-18 17:42:32 -08002178 /* This may or may not be an error. */
2179 if (i < 0) {
2180 return NULL;
2181 }
Adam Langley95c29f32014-06-20 12:00:00 -07002182
Adam Langleyfcf25832014-12-18 17:42:32 -08002183 /* May be NULL. */
2184 return &s->cert->pkeys[i];
2185}
Adam Langley95c29f32014-06-20 12:00:00 -07002186
Adam Langleyfcf25832014-12-18 17:42:32 -08002187EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher) {
2188 unsigned long alg_a;
2189 CERT *c;
2190 int idx = -1;
Adam Langley95c29f32014-06-20 12:00:00 -07002191
Adam Langleyfcf25832014-12-18 17:42:32 -08002192 alg_a = cipher->algorithm_auth;
2193 c = s->cert;
Adam Langley95c29f32014-06-20 12:00:00 -07002194
Adam Langleyfcf25832014-12-18 17:42:32 -08002195 if (alg_a & SSL_aRSA) {
2196 if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) {
2197 idx = SSL_PKEY_RSA_SIGN;
2198 } else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) {
2199 idx = SSL_PKEY_RSA_ENC;
2200 }
2201 } else if ((alg_a & SSL_aECDSA) &&
2202 (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) {
2203 idx = SSL_PKEY_ECC;
2204 }
Adam Langley95c29f32014-06-20 12:00:00 -07002205
Adam Langleyfcf25832014-12-18 17:42:32 -08002206 if (idx == -1) {
2207 OPENSSL_PUT_ERROR(SSL, ssl_get_sign_pkey, ERR_R_INTERNAL_ERROR);
2208 return NULL;
2209 }
Adam Langley95c29f32014-06-20 12:00:00 -07002210
Adam Langleyfcf25832014-12-18 17:42:32 -08002211 return c->pkeys[idx].privatekey;
2212}
Adam Langley95c29f32014-06-20 12:00:00 -07002213
Adam Langleyfcf25832014-12-18 17:42:32 -08002214void ssl_update_cache(SSL *s, int mode) {
2215 int i;
Adam Langley95c29f32014-06-20 12:00:00 -07002216
Adam Langleyfcf25832014-12-18 17:42:32 -08002217 /* If the session_id_length is 0, we are not supposed to cache it, and it
2218 * would be rather hard to do anyway :-) */
2219 if (s->session->session_id_length == 0) {
2220 return;
2221 }
Adam Langley95c29f32014-06-20 12:00:00 -07002222
Adam Langleyfcf25832014-12-18 17:42:32 -08002223 i = s->initial_ctx->session_cache_mode;
2224 if ((i & mode) && !s->hit &&
2225 ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) ||
2226 SSL_CTX_add_session(s->initial_ctx, s->session)) &&
2227 s->initial_ctx->new_session_cb != NULL) {
2228 CRYPTO_add(&s->session->references, 1, CRYPTO_LOCK_SSL_SESSION);
2229 if (!s->initial_ctx->new_session_cb(s, s->session)) {
2230 SSL_SESSION_free(s->session);
2231 }
2232 }
Adam Langley95c29f32014-06-20 12:00:00 -07002233
Adam Langleyfcf25832014-12-18 17:42:32 -08002234 /* auto flush every 255 connections */
2235 if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && ((i & mode) == mode)) {
2236 if ((((mode & SSL_SESS_CACHE_CLIENT)
2237 ? s->initial_ctx->stats.sess_connect_good
2238 : s->initial_ctx->stats.sess_accept_good) &
2239 0xff) == 0xff) {
2240 SSL_CTX_flush_sessions(s->initial_ctx, (unsigned long)time(NULL));
2241 }
2242 }
2243}
Adam Langley95c29f32014-06-20 12:00:00 -07002244
Adam Langleyfcf25832014-12-18 17:42:32 -08002245int SSL_get_error(const SSL *s, int i) {
2246 int reason;
2247 unsigned long l;
2248 BIO *bio;
Adam Langley95c29f32014-06-20 12:00:00 -07002249
Adam Langleyfcf25832014-12-18 17:42:32 -08002250 if (i > 0) {
2251 return SSL_ERROR_NONE;
2252 }
Adam Langley95c29f32014-06-20 12:00:00 -07002253
Adam Langleyfcf25832014-12-18 17:42:32 -08002254 /* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
2255 * where we do encode the error */
2256 l = ERR_peek_error();
2257 if (l != 0) {
2258 if (ERR_GET_LIB(l) == ERR_LIB_SYS) {
2259 return SSL_ERROR_SYSCALL;
2260 }
2261 return SSL_ERROR_SSL;
2262 }
Adam Langley95c29f32014-06-20 12:00:00 -07002263
Adam Langleyfcf25832014-12-18 17:42:32 -08002264 if (i == 0 && (s->shutdown & SSL_RECEIVED_SHUTDOWN) &&
2265 (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) {
2266 return SSL_ERROR_ZERO_RETURN;
2267 }
Adam Langleyb2ce0582014-06-20 12:00:00 -07002268
Adam Langleyfcf25832014-12-18 17:42:32 -08002269 assert(i < 0);
Adam Langleydc9b1412014-06-20 12:00:00 -07002270
Adam Langleyfcf25832014-12-18 17:42:32 -08002271 if (SSL_want_session(s)) {
2272 return SSL_ERROR_PENDING_SESSION;
2273 }
Adam Langley95c29f32014-06-20 12:00:00 -07002274
Adam Langleyfcf25832014-12-18 17:42:32 -08002275 if (SSL_want_certificate(s)) {
2276 return SSL_ERROR_PENDING_CERTIFICATE;
2277 }
Adam Langley95c29f32014-06-20 12:00:00 -07002278
Adam Langleyfcf25832014-12-18 17:42:32 -08002279 if (SSL_want_read(s)) {
2280 bio = SSL_get_rbio(s);
2281 if (BIO_should_read(bio)) {
2282 return SSL_ERROR_WANT_READ;
2283 }
Adam Langley95c29f32014-06-20 12:00:00 -07002284
Adam Langleyfcf25832014-12-18 17:42:32 -08002285 if (BIO_should_write(bio)) {
2286 /* This one doesn't make too much sense ... We never try to write to the
2287 * rbio, and an application program where rbio and wbio are separate
2288 * couldn't even know what it should wait for. However if we ever set
2289 * s->rwstate incorrectly (so that we have SSL_want_read(s) instead of
2290 * SSL_want_write(s)) and rbio and wbio *are* the same, this test works
2291 * around that bug; so it might be safer to keep it. */
2292 return SSL_ERROR_WANT_WRITE;
2293 }
Adam Langley95c29f32014-06-20 12:00:00 -07002294
Adam Langleyfcf25832014-12-18 17:42:32 -08002295 if (BIO_should_io_special(bio)) {
2296 reason = BIO_get_retry_reason(bio);
2297 if (reason == BIO_RR_CONNECT) {
2298 return SSL_ERROR_WANT_CONNECT;
2299 }
Adam Langley95c29f32014-06-20 12:00:00 -07002300
Adam Langleyfcf25832014-12-18 17:42:32 -08002301 if (reason == BIO_RR_ACCEPT) {
2302 return SSL_ERROR_WANT_ACCEPT;
2303 }
Adam Langley95c29f32014-06-20 12:00:00 -07002304
Adam Langleyfcf25832014-12-18 17:42:32 -08002305 return SSL_ERROR_SYSCALL; /* unknown */
2306 }
2307 }
Adam Langley95c29f32014-06-20 12:00:00 -07002308
Adam Langleyfcf25832014-12-18 17:42:32 -08002309 if (SSL_want_write(s)) {
2310 bio = SSL_get_wbio(s);
2311 if (BIO_should_write(bio)) {
2312 return SSL_ERROR_WANT_WRITE;
2313 }
Adam Langley95c29f32014-06-20 12:00:00 -07002314
Adam Langleyfcf25832014-12-18 17:42:32 -08002315 if (BIO_should_read(bio)) {
2316 /* See above (SSL_want_read(s) with BIO_should_write(bio)) */
2317 return SSL_ERROR_WANT_READ;
2318 }
Adam Langley95c29f32014-06-20 12:00:00 -07002319
Adam Langleyfcf25832014-12-18 17:42:32 -08002320 if (BIO_should_io_special(bio)) {
2321 reason = BIO_get_retry_reason(bio);
2322 if (reason == BIO_RR_CONNECT) {
2323 return SSL_ERROR_WANT_CONNECT;
2324 }
Adam Langley95c29f32014-06-20 12:00:00 -07002325
Adam Langleyfcf25832014-12-18 17:42:32 -08002326 if (reason == BIO_RR_ACCEPT) {
2327 return SSL_ERROR_WANT_ACCEPT;
2328 }
Adam Langley95c29f32014-06-20 12:00:00 -07002329
Adam Langleyfcf25832014-12-18 17:42:32 -08002330 return SSL_ERROR_SYSCALL;
2331 }
2332 }
Adam Langley95c29f32014-06-20 12:00:00 -07002333
Adam Langleyfcf25832014-12-18 17:42:32 -08002334 if (SSL_want_x509_lookup(s)) {
2335 return SSL_ERROR_WANT_X509_LOOKUP;
2336 }
Adam Langley95c29f32014-06-20 12:00:00 -07002337
Adam Langleyfcf25832014-12-18 17:42:32 -08002338 if (SSL_want_channel_id_lookup(s)) {
2339 return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP;
2340 }
Adam Langley0f4746e2014-08-13 12:26:32 -07002341
Adam Langleyfcf25832014-12-18 17:42:32 -08002342 return SSL_ERROR_SYSCALL;
2343}
Adam Langley0f4746e2014-08-13 12:26:32 -07002344
Adam Langleyfcf25832014-12-18 17:42:32 -08002345int SSL_do_handshake(SSL *s) {
2346 int ret = 1;
Adam Langley95c29f32014-06-20 12:00:00 -07002347
Adam Langleyfcf25832014-12-18 17:42:32 -08002348 if (s->handshake_func == NULL) {
2349 OPENSSL_PUT_ERROR(SSL, SSL_do_handshake, SSL_R_CONNECTION_TYPE_NOT_SET);
2350 return -1;
2351 }
Adam Langley95c29f32014-06-20 12:00:00 -07002352
Adam Langleyfcf25832014-12-18 17:42:32 -08002353 s->method->ssl_renegotiate_check(s);
Adam Langley95c29f32014-06-20 12:00:00 -07002354
Adam Langleyfcf25832014-12-18 17:42:32 -08002355 if (SSL_in_init(s)) {
2356 ret = s->handshake_func(s);
2357 }
2358 return ret;
2359}
Adam Langley95c29f32014-06-20 12:00:00 -07002360
Adam Langleyfcf25832014-12-18 17:42:32 -08002361void SSL_set_accept_state(SSL *s) {
2362 s->server = 1;
2363 s->shutdown = 0;
2364 s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE;
2365 s->handshake_func = s->method->ssl_accept;
2366 /* clear the current cipher */
2367 ssl_clear_cipher_ctx(s);
2368 ssl_clear_hash_ctx(&s->read_hash);
2369 ssl_clear_hash_ctx(&s->write_hash);
2370}
Adam Langley95c29f32014-06-20 12:00:00 -07002371
Adam Langleyfcf25832014-12-18 17:42:32 -08002372void SSL_set_connect_state(SSL *s) {
2373 s->server = 0;
2374 s->shutdown = 0;
2375 s->state = SSL_ST_CONNECT | SSL_ST_BEFORE;
2376 s->handshake_func = s->method->ssl_connect;
2377 /* clear the current cipher */
2378 ssl_clear_cipher_ctx(s);
2379 ssl_clear_hash_ctx(&s->read_hash);
2380 ssl_clear_hash_ctx(&s->write_hash);
2381}
Adam Langley95c29f32014-06-20 12:00:00 -07002382
Adam Langleyfcf25832014-12-18 17:42:32 -08002383int ssl_undefined_function(SSL *s) {
2384 OPENSSL_PUT_ERROR(SSL, ssl_undefined_function,
2385 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
2386 return 0;
2387}
Adam Langley95c29f32014-06-20 12:00:00 -07002388
Adam Langleyfcf25832014-12-18 17:42:32 -08002389int ssl_undefined_void_function(void) {
2390 OPENSSL_PUT_ERROR(SSL, ssl_undefined_void_function,
2391 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
2392 return 0;
2393}
Adam Langley95c29f32014-06-20 12:00:00 -07002394
Adam Langleyfcf25832014-12-18 17:42:32 -08002395int ssl_undefined_const_function(const SSL *s) {
2396 OPENSSL_PUT_ERROR(SSL, ssl_undefined_const_function,
2397 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
2398 return 0;
2399}
Adam Langley95c29f32014-06-20 12:00:00 -07002400
Adam Langleyfcf25832014-12-18 17:42:32 -08002401static const char *ssl_get_version(int version) {
2402 switch (version) {
2403 case TLS1_2_VERSION:
2404 return "TLSv1.2";
Adam Langley95c29f32014-06-20 12:00:00 -07002405
Adam Langleyfcf25832014-12-18 17:42:32 -08002406 case TLS1_1_VERSION:
2407 return "TLSv1.1";
Adam Langley95c29f32014-06-20 12:00:00 -07002408
Adam Langleyfcf25832014-12-18 17:42:32 -08002409 case TLS1_VERSION:
2410 return "TLSv1";
Adam Langley95c29f32014-06-20 12:00:00 -07002411
Adam Langleyfcf25832014-12-18 17:42:32 -08002412 case SSL3_VERSION:
2413 return "SSLv3";
Adam Langley95c29f32014-06-20 12:00:00 -07002414
Adam Langleyfcf25832014-12-18 17:42:32 -08002415 default:
2416 return "unknown";
2417 }
2418}
Adam Langley95c29f32014-06-20 12:00:00 -07002419
Adam Langleyfcf25832014-12-18 17:42:32 -08002420const char *SSL_get_version(const SSL *s) {
2421 return ssl_get_version(s->version);
2422}
Adam Langley95c29f32014-06-20 12:00:00 -07002423
Adam Langleyfcf25832014-12-18 17:42:32 -08002424const char *SSL_SESSION_get_version(const SSL_SESSION *sess) {
2425 return ssl_get_version(sess->ssl_version);
2426}
Adam Langley95c29f32014-06-20 12:00:00 -07002427
Adam Langleyfcf25832014-12-18 17:42:32 -08002428void ssl_clear_cipher_ctx(SSL *s) {
2429 if (s->enc_read_ctx != NULL) {
2430 EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
2431 OPENSSL_free(s->enc_read_ctx);
2432 s->enc_read_ctx = NULL;
2433 }
Adam Langley95c29f32014-06-20 12:00:00 -07002434
Adam Langleyfcf25832014-12-18 17:42:32 -08002435 if (s->enc_write_ctx != NULL) {
2436 EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
2437 OPENSSL_free(s->enc_write_ctx);
2438 s->enc_write_ctx = NULL;
2439 }
Adam Langleya5dc5452014-06-20 12:00:00 -07002440
Adam Langleyfcf25832014-12-18 17:42:32 -08002441 if (s->aead_read_ctx != NULL) {
2442 EVP_AEAD_CTX_cleanup(&s->aead_read_ctx->ctx);
2443 OPENSSL_free(s->aead_read_ctx);
2444 s->aead_read_ctx = NULL;
2445 }
Adam Langleya5dc5452014-06-20 12:00:00 -07002446
Adam Langleyfcf25832014-12-18 17:42:32 -08002447 if (s->aead_write_ctx != NULL) {
2448 EVP_AEAD_CTX_cleanup(&s->aead_write_ctx->ctx);
2449 OPENSSL_free(s->aead_write_ctx);
2450 s->aead_write_ctx = NULL;
2451 }
2452}
Adam Langley95c29f32014-06-20 12:00:00 -07002453
Adam Langleyfcf25832014-12-18 17:42:32 -08002454X509 *SSL_get_certificate(const SSL *s) {
2455 if (s->cert != NULL) {
2456 return s->cert->key->x509;
2457 }
2458
2459 return NULL;
2460}
2461
2462EVP_PKEY *SSL_get_privatekey(const SSL *s) {
2463 if (s->cert != NULL) {
2464 return s->cert->key->privatekey;
2465 }
2466
2467 return NULL;
2468}
2469
2470X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
2471 if (ctx->cert != NULL) {
2472 return ctx->cert->key->x509;
2473 }
2474
2475 return NULL;
2476}
2477
2478EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) {
2479 if (ctx->cert != NULL) {
2480 return ctx->cert->key->privatekey;
2481 }
2482
2483 return NULL;
2484}
2485
2486const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) {
2487 if (s->session != NULL && s->session->cipher != NULL) {
2488 return s->session->cipher;
2489 }
2490
2491 return NULL;
2492}
2493
2494const void *SSL_get_current_compression(SSL *s) { return NULL; }
2495
2496const void *SSL_get_current_expansion(SSL *s) { return NULL; }
2497
2498int ssl_init_wbio_buffer(SSL *s, int push) {
2499 BIO *bbio;
2500
2501 if (s->bbio == NULL) {
2502 bbio = BIO_new(BIO_f_buffer());
2503 if (bbio == NULL) {
2504 return 0;
2505 }
2506 s->bbio = bbio;
2507 } else {
2508 bbio = s->bbio;
2509 if (s->bbio == s->wbio) {
2510 s->wbio = BIO_pop(s->wbio);
2511 }
2512 }
2513
2514 BIO_reset(bbio);
2515 if (!BIO_set_read_buffer_size(bbio, 1)) {
2516 OPENSSL_PUT_ERROR(SSL, ssl_init_wbio_buffer, ERR_R_BUF_LIB);
2517 return 0;
2518 }
2519
2520 if (push) {
2521 if (s->wbio != bbio) {
2522 s->wbio = BIO_push(bbio, s->wbio);
2523 }
2524 } else {
2525 if (s->wbio == bbio) {
2526 s->wbio = BIO_pop(bbio);
2527 }
2528 }
2529
2530 return 1;
2531}
2532
2533void ssl_free_wbio_buffer(SSL *s) {
2534 if (s->bbio == NULL) {
2535 return;
2536 }
2537
2538 if (s->bbio == s->wbio) {
2539 /* remove buffering */
2540 s->wbio = BIO_pop(s->wbio);
2541 }
2542
2543 BIO_free(s->bbio);
2544 s->bbio = NULL;
2545}
2546
2547void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) {
2548 ctx->quiet_shutdown = mode;
2549}
2550
2551int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) {
2552 return ctx->quiet_shutdown;
2553}
2554
2555void SSL_set_quiet_shutdown(SSL *s, int mode) { s->quiet_shutdown = mode; }
2556
2557int SSL_get_quiet_shutdown(const SSL *s) { return s->quiet_shutdown; }
2558
2559void SSL_set_shutdown(SSL *s, int mode) { s->shutdown = mode; }
2560
2561int SSL_get_shutdown(const SSL *s) { return s->shutdown; }
2562
2563int SSL_version(const SSL *s) { return s->version; }
2564
2565SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return ssl->ctx; }
2566
2567SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) {
2568 if (ssl->ctx == ctx) {
2569 return ssl->ctx;
2570 }
2571
2572 if (ctx == NULL) {
2573 ctx = ssl->initial_ctx;
2574 }
2575
2576 if (ssl->cert != NULL) {
2577 ssl_cert_free(ssl->cert);
2578 }
2579
2580 ssl->cert = ssl_cert_dup(ctx->cert);
2581 CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
2582 if (ssl->ctx != NULL) {
2583 SSL_CTX_free(ssl->ctx); /* decrement reference count */
2584 }
2585 ssl->ctx = ctx;
2586
2587 ssl->sid_ctx_length = ctx->sid_ctx_length;
2588 assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx));
2589 memcpy(ssl->sid_ctx, ctx->sid_ctx, sizeof(ssl->sid_ctx));
2590
2591 return ssl->ctx;
2592}
2593
2594int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) {
2595 return X509_STORE_set_default_paths(ctx->cert_store);
2596}
Adam Langley95c29f32014-06-20 12:00:00 -07002597
2598int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
Adam Langleyfcf25832014-12-18 17:42:32 -08002599 const char *CApath) {
2600 return X509_STORE_load_locations(ctx->cert_store, CAfile, CApath);
2601}
Adam Langley95c29f32014-06-20 12:00:00 -07002602
2603void SSL_set_info_callback(SSL *ssl,
Adam Langleyfcf25832014-12-18 17:42:32 -08002604 void (*cb)(const SSL *ssl, int type, int val)) {
2605 ssl->info_callback = cb;
2606}
Adam Langley95c29f32014-06-20 12:00:00 -07002607
Adam Langleyfcf25832014-12-18 17:42:32 -08002608void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/, int /*type*/,
2609 int /*val*/) {
2610 return ssl->info_callback;
2611}
Adam Langley95c29f32014-06-20 12:00:00 -07002612
Adam Langleyfcf25832014-12-18 17:42:32 -08002613int SSL_state(const SSL *ssl) { return ssl->state; }
Adam Langley95c29f32014-06-20 12:00:00 -07002614
Adam Langleyfcf25832014-12-18 17:42:32 -08002615void SSL_set_state(SSL *ssl, int state) { ssl->state = state; }
Adam Langley95c29f32014-06-20 12:00:00 -07002616
Adam Langleyfcf25832014-12-18 17:42:32 -08002617void SSL_set_verify_result(SSL *ssl, long arg) { ssl->verify_result = arg; }
Adam Langley95c29f32014-06-20 12:00:00 -07002618
Adam Langleyfcf25832014-12-18 17:42:32 -08002619long SSL_get_verify_result(const SSL *ssl) { return ssl->verify_result; }
Adam Langley95c29f32014-06-20 12:00:00 -07002620
Adam Langleyfcf25832014-12-18 17:42:32 -08002621int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
2622 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
2623 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp, new_func,
2624 dup_func, free_func);
2625}
Adam Langley95c29f32014-06-20 12:00:00 -07002626
Adam Langleyfcf25832014-12-18 17:42:32 -08002627int SSL_set_ex_data(SSL *s, int idx, void *arg) {
2628 return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
2629}
Adam Langley95c29f32014-06-20 12:00:00 -07002630
Adam Langleyfcf25832014-12-18 17:42:32 -08002631void *SSL_get_ex_data(const SSL *s, int idx) {
2632 return CRYPTO_get_ex_data(&s->ex_data, idx);
2633}
Adam Langley95c29f32014-06-20 12:00:00 -07002634
Adam Langleyfcf25832014-12-18 17:42:32 -08002635int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
2636 CRYPTO_EX_dup *dup_func,
2637 CRYPTO_EX_free *free_func) {
2638 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp, new_func,
2639 dup_func, free_func);
2640}
Adam Langley95c29f32014-06-20 12:00:00 -07002641
Adam Langleyfcf25832014-12-18 17:42:32 -08002642int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg) {
2643 return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
2644}
Adam Langley95c29f32014-06-20 12:00:00 -07002645
Adam Langleyfcf25832014-12-18 17:42:32 -08002646void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx) {
2647 return CRYPTO_get_ex_data(&s->ex_data, idx);
2648}
Adam Langley95c29f32014-06-20 12:00:00 -07002649
Adam Langleyfcf25832014-12-18 17:42:32 -08002650int ssl_ok(SSL *s) { return 1; }
Adam Langley95c29f32014-06-20 12:00:00 -07002651
Adam Langleyfcf25832014-12-18 17:42:32 -08002652X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
2653 return ctx->cert_store;
2654}
Adam Langley95c29f32014-06-20 12:00:00 -07002655
Adam Langleyfcf25832014-12-18 17:42:32 -08002656void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) {
2657 if (ctx->cert_store != NULL) {
2658 X509_STORE_free(ctx->cert_store);
2659 }
2660 ctx->cert_store = store;
2661}
Adam Langley95c29f32014-06-20 12:00:00 -07002662
Adam Langleyfcf25832014-12-18 17:42:32 -08002663int SSL_want(const SSL *s) { return s->rwstate; }
Adam Langley95c29f32014-06-20 12:00:00 -07002664
Adam Langleyfcf25832014-12-18 17:42:32 -08002665void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
2666 RSA *(*cb)(SSL *ssl, int is_export,
2667 int keylength)) {
2668 SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb);
2669}
Adam Langley95c29f32014-06-20 12:00:00 -07002670
Adam Langleyfcf25832014-12-18 17:42:32 -08002671void SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb)(SSL *ssl, int is_export,
2672 int keylength)) {
2673 SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb);
2674}
2675
2676void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
2677 DH *(*dh)(SSL *ssl, int is_export,
2678 int keylength)) {
2679 SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh);
2680}
2681
2682void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh)(SSL *ssl, int is_export,
2683 int keylength)) {
2684 SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh);
2685}
2686
2687void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
2688 EC_KEY *(*ecdh)(SSL *ssl, int is_export,
2689 int keylength)) {
2690 SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH_CB, (void (*)(void))ecdh);
2691}
2692
2693void SSL_set_tmp_ecdh_callback(SSL *ssl,
2694 EC_KEY *(*ecdh)(SSL *ssl, int is_export,
2695 int keylength)) {
2696 SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_ECDH_CB, (void (*)(void))ecdh);
2697}
2698
2699int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) {
2700 if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
2701 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_psk_identity_hint,
2702 SSL_R_DATA_LENGTH_TOO_LONG);
2703 return 0;
2704 }
2705
2706 if (ctx->psk_identity_hint != NULL) {
2707 OPENSSL_free(ctx->psk_identity_hint);
2708 }
2709
2710 if (identity_hint != NULL) {
2711 ctx->psk_identity_hint = BUF_strdup(identity_hint);
2712 if (ctx->psk_identity_hint == NULL) {
2713 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07002714 }
Adam Langleyfcf25832014-12-18 17:42:32 -08002715 } else {
2716 ctx->psk_identity_hint = NULL;
2717 }
Adam Langley95c29f32014-06-20 12:00:00 -07002718
Adam Langleyfcf25832014-12-18 17:42:32 -08002719 return 1;
2720}
2721
2722int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) {
2723 if (s == NULL) {
2724 return 0;
2725 }
2726
2727 if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
2728 OPENSSL_PUT_ERROR(SSL, SSL_use_psk_identity_hint,
2729 SSL_R_DATA_LENGTH_TOO_LONG);
2730 return 0;
2731 }
2732
2733 /* Clear currently configured hint, if any. */
2734 if (s->psk_identity_hint != NULL) {
2735 OPENSSL_free(s->psk_identity_hint);
2736 s->psk_identity_hint = NULL;
2737 }
2738
2739 if (identity_hint != NULL) {
2740 s->psk_identity_hint = BUF_strdup(identity_hint);
2741 if (s->psk_identity_hint == NULL) {
2742 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07002743 }
Adam Langleyfcf25832014-12-18 17:42:32 -08002744 }
Adam Langley95c29f32014-06-20 12:00:00 -07002745
Adam Langleyfcf25832014-12-18 17:42:32 -08002746 return 1;
2747}
Adam Langley95c29f32014-06-20 12:00:00 -07002748
Adam Langleyfcf25832014-12-18 17:42:32 -08002749const char *SSL_get_psk_identity_hint(const SSL *s) {
2750 if (s == NULL) {
2751 return NULL;
2752 }
2753 return s->psk_identity_hint;
2754}
Adam Langley95c29f32014-06-20 12:00:00 -07002755
Adam Langleyfcf25832014-12-18 17:42:32 -08002756const char *SSL_get_psk_identity(const SSL *s) {
2757 if (s == NULL || s->session == NULL) {
2758 return NULL;
2759 }
Adam Langley95c29f32014-06-20 12:00:00 -07002760
Adam Langleyfcf25832014-12-18 17:42:32 -08002761 return s->session->psk_identity;
2762}
Adam Langley95c29f32014-06-20 12:00:00 -07002763
Adam Langleyfcf25832014-12-18 17:42:32 -08002764void SSL_set_psk_client_callback(
2765 SSL *s, unsigned int (*cb)(SSL *ssl, const char *hint, char *identity,
2766 unsigned int max_identity_len, uint8_t *psk,
2767 unsigned int max_psk_len)) {
2768 s->psk_client_callback = cb;
2769}
Adam Langley95c29f32014-06-20 12:00:00 -07002770
Adam Langleyfcf25832014-12-18 17:42:32 -08002771void SSL_CTX_set_psk_client_callback(
2772 SSL_CTX *ctx, unsigned int (*cb)(SSL *ssl, const char *hint, char *identity,
2773 unsigned int max_identity_len,
2774 uint8_t *psk, unsigned int max_psk_len)) {
2775 ctx->psk_client_callback = cb;
2776}
Adam Langley95c29f32014-06-20 12:00:00 -07002777
Adam Langleyfcf25832014-12-18 17:42:32 -08002778void SSL_set_psk_server_callback(
2779 SSL *s, unsigned int (*cb)(SSL *ssl, const char *identity, uint8_t *psk,
2780 unsigned int max_psk_len)) {
2781 s->psk_server_callback = cb;
2782}
Adam Langley95c29f32014-06-20 12:00:00 -07002783
Adam Langleyfcf25832014-12-18 17:42:32 -08002784void SSL_CTX_set_psk_server_callback(
2785 SSL_CTX *ctx, unsigned int (*cb)(SSL *ssl, const char *identity,
2786 uint8_t *psk, unsigned int max_psk_len)) {
2787 ctx->psk_server_callback = cb;
2788}
Adam Langley95c29f32014-06-20 12:00:00 -07002789
Adam Langleyfcf25832014-12-18 17:42:32 -08002790void SSL_CTX_set_min_version(SSL_CTX *ctx, uint16_t version) {
2791 ctx->min_version = version;
2792}
Adam Langley95c29f32014-06-20 12:00:00 -07002793
Adam Langleyfcf25832014-12-18 17:42:32 -08002794void SSL_CTX_set_max_version(SSL_CTX *ctx, uint16_t version) {
2795 ctx->max_version = version;
2796}
Adam Langley0289c732014-06-20 12:00:00 -07002797
Adam Langleyfcf25832014-12-18 17:42:32 -08002798void SSL_set_min_version(SSL *ssl, uint16_t version) {
2799 ssl->min_version = version;
2800}
Adam Langley0289c732014-06-20 12:00:00 -07002801
Adam Langleyfcf25832014-12-18 17:42:32 -08002802void SSL_set_max_version(SSL *ssl, uint16_t version) {
2803 ssl->max_version = version;
2804}
Adam Langley95c29f32014-06-20 12:00:00 -07002805
Adam Langleyfcf25832014-12-18 17:42:32 -08002806void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
2807 void (*cb)(int write_p, int version,
2808 int content_type, const void *buf,
2809 size_t len, SSL *ssl, void *arg)) {
2810 SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
2811}
2812void SSL_set_msg_callback(SSL *ssl,
2813 void (*cb)(int write_p, int version, int content_type,
2814 const void *buf, size_t len, SSL *ssl,
2815 void *arg)) {
2816 SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
2817}
Adam Langley95c29f32014-06-20 12:00:00 -07002818
Adam Langleyfcf25832014-12-18 17:42:32 -08002819void SSL_CTX_set_keylog_bio(SSL_CTX *ctx, BIO *keylog_bio) {
2820 if (ctx->keylog_bio != NULL) {
2821 BIO_free(ctx->keylog_bio);
2822 }
2823 ctx->keylog_bio = keylog_bio;
2824}
Adam Langley95c29f32014-06-20 12:00:00 -07002825
Adam Langleyfcf25832014-12-18 17:42:32 -08002826static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) {
2827 static const char hextable[] = "0123456789abcdef";
2828 uint8_t *out;
2829 size_t i;
Adam Langley95c29f32014-06-20 12:00:00 -07002830
Adam Langleyfcf25832014-12-18 17:42:32 -08002831 if (!CBB_add_space(cbb, &out, in_len * 2)) {
2832 return 0;
2833 }
Adam Langley95c29f32014-06-20 12:00:00 -07002834
Adam Langleyfcf25832014-12-18 17:42:32 -08002835 for (i = 0; i < in_len; i++) {
2836 *(out++) = (uint8_t)hextable[in[i] >> 4];
2837 *(out++) = (uint8_t)hextable[in[i] & 0xf];
2838 }
Adam Langley95c29f32014-06-20 12:00:00 -07002839
Adam Langleyfcf25832014-12-18 17:42:32 -08002840 return 1;
2841}
David Benjamin859ec3c2014-09-02 16:29:36 -04002842
2843int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx,
Adam Langleyfcf25832014-12-18 17:42:32 -08002844 const uint8_t *encrypted_premaster,
2845 size_t encrypted_premaster_len,
2846 const uint8_t *premaster,
2847 size_t premaster_len) {
2848 BIO *bio = ctx->keylog_bio;
2849 CBB cbb;
2850 uint8_t *out;
2851 size_t out_len;
2852 int ret;
David Benjamin859ec3c2014-09-02 16:29:36 -04002853
Adam Langleyfcf25832014-12-18 17:42:32 -08002854 if (bio == NULL) {
2855 return 1;
2856 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002857
Adam Langleyfcf25832014-12-18 17:42:32 -08002858 if (encrypted_premaster_len < 8) {
2859 OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_rsa_client_key_exchange,
2860 ERR_R_INTERNAL_ERROR);
2861 return 0;
2862 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002863
Adam Langleyfcf25832014-12-18 17:42:32 -08002864 if (!CBB_init(&cbb, 4 + 16 + 1 + premaster_len * 2 + 1)) {
2865 return 0;
2866 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002867
Adam Langleyfcf25832014-12-18 17:42:32 -08002868 if (!CBB_add_bytes(&cbb, (const uint8_t *)"RSA ", 4) ||
2869 /* Only the first 8 bytes of the encrypted premaster secret are
2870 * logged. */
2871 !cbb_add_hex(&cbb, encrypted_premaster, 8) ||
2872 !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
2873 !cbb_add_hex(&cbb, premaster, premaster_len) ||
2874 !CBB_add_bytes(&cbb, (const uint8_t *)"\n", 1) ||
2875 !CBB_finish(&cbb, &out, &out_len)) {
2876 CBB_cleanup(&cbb);
2877 return 0;
2878 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002879
Adam Langleyfcf25832014-12-18 17:42:32 -08002880 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
2881 ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio);
2882 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
David Benjamin859ec3c2014-09-02 16:29:36 -04002883
Adam Langleyfcf25832014-12-18 17:42:32 -08002884 OPENSSL_free(out);
2885 return ret;
Adam Langley95f22882014-06-20 12:00:00 -07002886}
2887
Adam Langleyfcf25832014-12-18 17:42:32 -08002888int ssl_ctx_log_master_secret(SSL_CTX *ctx, const uint8_t *client_random,
2889 size_t client_random_len, const uint8_t *master,
2890 size_t master_len) {
2891 BIO *bio = ctx->keylog_bio;
2892 CBB cbb;
2893 uint8_t *out;
2894 size_t out_len;
2895 int ret;
Adam Langleyadb739e2014-06-20 12:00:00 -07002896
Adam Langleyfcf25832014-12-18 17:42:32 -08002897 if (bio == NULL) {
2898 return 1;
2899 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002900
Adam Langleyfcf25832014-12-18 17:42:32 -08002901 if (client_random_len != 32) {
2902 OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_master_secret, ERR_R_INTERNAL_ERROR);
2903 return 0;
2904 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002905
Adam Langleyfcf25832014-12-18 17:42:32 -08002906 if (!CBB_init(&cbb, 14 + 64 + 1 + master_len * 2 + 1)) {
2907 return 0;
2908 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002909
Adam Langleyfcf25832014-12-18 17:42:32 -08002910 if (!CBB_add_bytes(&cbb, (const uint8_t *)"CLIENT_RANDOM ", 14) ||
2911 !cbb_add_hex(&cbb, client_random, 32) ||
2912 !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
2913 !cbb_add_hex(&cbb, master, master_len) ||
2914 !CBB_add_bytes(&cbb, (const uint8_t *)"\n", 1) ||
2915 !CBB_finish(&cbb, &out, &out_len)) {
2916 CBB_cleanup(&cbb);
2917 return 0;
2918 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002919
Adam Langleyfcf25832014-12-18 17:42:32 -08002920 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
2921 ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio);
2922 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
David Benjamine99e9122014-12-11 01:46:01 -05002923
Adam Langleyfcf25832014-12-18 17:42:32 -08002924 OPENSSL_free(out);
2925 return ret;
Adam Langley95c29f32014-06-20 12:00:00 -07002926}
2927
Adam Langleyfcf25832014-12-18 17:42:32 -08002928int SSL_cutthrough_complete(const SSL *s) {
2929 return (
2930 !s->server && /* cutthrough only applies to clients */
2931 !s->hit && /* full-handshake */
2932 s->version >= SSL3_VERSION &&
2933 s->s3->in_read_app_data == 0 && /* cutthrough only applies to write() */
2934 (SSL_get_mode((SSL *)s) &
2935 SSL_MODE_HANDSHAKE_CUTTHROUGH) && /* cutthrough enabled */
2936 ssl3_can_cutthrough(s) && /* cutthrough allowed */
2937 s->s3->previous_server_finished_len ==
2938 0 && /* not a renegotiation handshake */
2939 (s->state == SSL3_ST_CR_SESSION_TICKET_A || /* ready to write app-data*/
2940 s->state == SSL3_ST_CR_CHANGE || s->state == SSL3_ST_CR_FINISHED_A));
2941}
Adam Langley95c29f32014-06-20 12:00:00 -07002942
Adam Langleyfcf25832014-12-18 17:42:32 -08002943void SSL_get_structure_sizes(size_t *ssl_size, size_t *ssl_ctx_size,
2944 size_t *ssl_session_size) {
2945 *ssl_size = sizeof(SSL);
2946 *ssl_ctx_size = sizeof(SSL_CTX);
2947 *ssl_session_size = sizeof(SSL_SESSION);
2948}
Feng Lu41aa3252014-11-21 22:47:56 -08002949
Adam Langleyfcf25832014-12-18 17:42:32 -08002950int ssl3_can_cutthrough(const SSL *s) {
2951 const SSL_CIPHER *c;
2952
2953 /* require a strong enough cipher */
2954 if (SSL_get_cipher_bits(s, NULL) < 128) {
2955 return 0;
2956 }
2957
2958 /* require ALPN or NPN extension */
2959 if (!s->s3->alpn_selected && !s->s3->next_proto_neg_seen) {
2960 return 0;
2961 }
2962
2963 /* require a forward-secret cipher */
2964 c = SSL_get_current_cipher(s);
2965 if (!c ||
2966 (c->algorithm_mkey != SSL_kEDH && c->algorithm_mkey != SSL_kEECDH)) {
2967 return 0;
2968 }
2969
2970 return 1;
2971}
2972
2973const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) {
2974 switch (version) {
2975 case SSL3_VERSION:
2976 return &SSLv3_enc_data;
2977
2978 case TLS1_VERSION:
2979 return &TLSv1_enc_data;
2980
2981 case TLS1_1_VERSION:
2982 return &TLSv1_1_enc_data;
2983
2984 case TLS1_2_VERSION:
2985 return &TLSv1_2_enc_data;
2986
2987 case DTLS1_VERSION:
2988 return &DTLSv1_enc_data;
2989
2990 case DTLS1_2_VERSION:
2991 return &DTLSv1_2_enc_data;
2992
2993 default:
2994 return NULL;
2995 }
2996}
2997
2998uint16_t ssl3_get_max_server_version(const SSL *s) {
2999 uint16_t max_version;
3000
3001 if (SSL_IS_DTLS(s)) {
3002 max_version = (s->max_version != 0) ? s->max_version : DTLS1_2_VERSION;
3003 if (!(s->options & SSL_OP_NO_DTLSv1_2) && DTLS1_2_VERSION >= max_version) {
3004 return DTLS1_2_VERSION;
3005 }
3006 if (!(s->options & SSL_OP_NO_DTLSv1) && DTLS1_VERSION >= max_version) {
3007 return DTLS1_VERSION;
3008 }
3009 return 0;
3010 }
3011
3012 max_version = (s->max_version != 0) ? s->max_version : TLS1_2_VERSION;
3013 if (!(s->options & SSL_OP_NO_TLSv1_2) && TLS1_2_VERSION <= max_version) {
3014 return TLS1_2_VERSION;
3015 }
3016 if (!(s->options & SSL_OP_NO_TLSv1_1) && TLS1_1_VERSION <= max_version) {
3017 return TLS1_1_VERSION;
3018 }
3019 if (!(s->options & SSL_OP_NO_TLSv1) && TLS1_VERSION <= max_version) {
3020 return TLS1_VERSION;
3021 }
3022 if (!(s->options & SSL_OP_NO_SSLv3) && SSL3_VERSION <= max_version) {
3023 return SSL3_VERSION;
3024 }
3025 return 0;
3026}
3027
3028uint16_t ssl3_get_mutual_version(SSL *s, uint16_t client_version) {
3029 uint16_t version = 0;
3030
3031 if (SSL_IS_DTLS(s)) {
3032 /* Clamp client_version to max_version. */
3033 if (s->max_version != 0 && client_version < s->max_version) {
3034 client_version = s->max_version;
3035 }
3036
3037 if (client_version <= DTLS1_2_VERSION && !(s->options & SSL_OP_NO_DTLSv1_2)) {
3038 version = DTLS1_2_VERSION;
3039 } else if (client_version <= DTLS1_VERSION &&
3040 !(s->options & SSL_OP_NO_DTLSv1)) {
3041 version = DTLS1_VERSION;
3042 }
3043
3044 /* Check against min_version. */
3045 if (version != 0 && s->min_version != 0 && version > s->min_version) {
3046 return 0;
3047 }
3048 return version;
3049 } else {
3050 /* Clamp client_version to max_version. */
3051 if (s->max_version != 0 && client_version > s->max_version) {
3052 client_version = s->max_version;
3053 }
3054
3055 if (client_version >= TLS1_2_VERSION && !(s->options & SSL_OP_NO_TLSv1_2)) {
3056 version = TLS1_2_VERSION;
3057 } else if (client_version >= TLS1_1_VERSION &&
3058 !(s->options & SSL_OP_NO_TLSv1_1)) {
3059 version = TLS1_1_VERSION;
3060 } else if (client_version >= TLS1_VERSION && !(s->options & SSL_OP_NO_TLSv1)) {
3061 version = TLS1_VERSION;
3062 } else if (client_version >= SSL3_VERSION && !(s->options & SSL_OP_NO_SSLv3)) {
3063 version = SSL3_VERSION;
3064 }
3065
3066 /* Check against min_version. */
3067 if (version != 0 && s->min_version != 0 && version < s->min_version) {
3068 return 0;
3069 }
3070 return version;
3071 }
3072}
3073
3074uint16_t ssl3_get_max_client_version(SSL *s) {
3075 unsigned long options = s->options;
3076 uint16_t version = 0;
3077
3078 /* OpenSSL's API for controlling versions entails blacklisting individual
3079 * protocols. This has two problems. First, on the client, the protocol can
3080 * only express a contiguous range of versions. Second, a library consumer
3081 * trying to set a maximum version cannot disable protocol versions that get
3082 * added in a future version of the library.
3083 *
3084 * To account for both of these, OpenSSL interprets the client-side bitmask
3085 * as a min/max range by picking the lowest contiguous non-empty range of
3086 * enabled protocols. Note that this means it is impossible to set a maximum
3087 * version of TLS 1.2 in a future-proof way.
3088 *
3089 * By this scheme, the maximum version is the lowest version V such that V is
3090 * enabled and V+1 is disabled or unimplemented. */
3091 if (SSL_IS_DTLS(s)) {
3092 if (!(options & SSL_OP_NO_DTLSv1_2)) {
3093 version = DTLS1_2_VERSION;
3094 }
3095 if (!(options & SSL_OP_NO_DTLSv1) && (options & SSL_OP_NO_DTLSv1_2)) {
3096 version = DTLS1_VERSION;
3097 }
3098 if (s->max_version != 0 && version < s->max_version) {
3099 version = s->max_version;
3100 }
3101 } else {
3102 if (!(options & SSL_OP_NO_TLSv1_2)) {
3103 version = TLS1_2_VERSION;
3104 }
3105 if (!(options & SSL_OP_NO_TLSv1_1) && (options & SSL_OP_NO_TLSv1_2)) {
3106 version = TLS1_1_VERSION;
3107 }
3108 if (!(options & SSL_OP_NO_TLSv1) && (options & SSL_OP_NO_TLSv1_1)) {
3109 version = TLS1_VERSION;
3110 }
3111 if (!(options & SSL_OP_NO_SSLv3) && (options & SSL_OP_NO_TLSv1)) {
3112 version = SSL3_VERSION;
3113 }
3114 if (s->max_version != 0 && version > s->max_version) {
3115 version = s->max_version;
3116 }
3117 }
3118
3119 return version;
3120}
3121
3122int ssl3_is_version_enabled(SSL *s, uint16_t version) {
3123 if (SSL_IS_DTLS(s)) {
3124 if (s->max_version != 0 && version < s->max_version) {
3125 return 0;
3126 }
3127 if (s->min_version != 0 && version > s->min_version) {
3128 return 0;
3129 }
3130
3131 switch (version) {
3132 case DTLS1_VERSION:
3133 return !(s->options & SSL_OP_NO_DTLSv1);
3134
3135 case DTLS1_2_VERSION:
3136 return !(s->options & SSL_OP_NO_DTLSv1_2);
3137
3138 default:
3139 return 0;
3140 }
3141 } else {
3142 if (s->max_version != 0 && version > s->max_version) {
3143 return 0;
3144 }
3145 if (s->min_version != 0 && version < s->min_version) {
3146 return 0;
3147 }
3148
3149 switch (version) {
3150 case SSL3_VERSION:
3151 return !(s->options & SSL_OP_NO_SSLv3);
3152
3153 case TLS1_VERSION:
3154 return !(s->options & SSL_OP_NO_TLSv1);
3155
3156 case TLS1_1_VERSION:
3157 return !(s->options & SSL_OP_NO_TLSv1_1);
3158
3159 case TLS1_2_VERSION:
3160 return !(s->options & SSL_OP_NO_TLSv1_2);
3161
3162 default:
3163 return 0;
3164 }
3165 }
3166}
3167
3168/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer vairable,
3169 * freeing EVP_MD_CTX previously stored in that variable, if any. If EVP_MD
3170 * pointer is passed, initializes ctx with this md Returns newly allocated
3171 * ctx. */
3172EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md) {
3173 ssl_clear_hash_ctx(hash);
3174 *hash = EVP_MD_CTX_create();
3175 if (md != NULL && *hash != NULL && !EVP_DigestInit_ex(*hash, md, NULL)) {
3176 EVP_MD_CTX_destroy(*hash);
3177 *hash = NULL;
3178 }
3179 return *hash;
3180}
3181
3182void ssl_clear_hash_ctx(EVP_MD_CTX **hash) {
3183 if (*hash) {
3184 EVP_MD_CTX_destroy(*hash);
3185 }
3186 *hash = NULL;
3187}
3188
3189int SSL_cache_hit(SSL *s) { return s->hit; }
3190
3191int SSL_is_server(SSL *s) { return s->server; }
3192
3193void SSL_enable_fastradio_padding(SSL *s, char on_off) {
3194 s->fastradio_padding = on_off;
3195}