blob: 5ed35312e94cced40974a08e6d849cc58fcbc592 [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
Adam Langleyfcf25832014-12-18 17:42:32 -0800193 s->rwstate = SSL_NOTHING;
194 s->rstate = SSL_ST_READ_HEADER;
Adam Langley95c29f32014-06-20 12:00:00 -0700195
Adam Langleyfcf25832014-12-18 17:42:32 -0800196 if (s->init_buf != NULL) {
197 BUF_MEM_free(s->init_buf);
198 s->init_buf = NULL;
199 }
Adam Langley95c29f32014-06-20 12:00:00 -0700200
Adam Langleyfcf25832014-12-18 17:42:32 -0800201 ssl_clear_cipher_ctx(s);
202 ssl_clear_hash_ctx(&s->read_hash);
203 ssl_clear_hash_ctx(&s->write_hash);
Adam Langley95c29f32014-06-20 12:00:00 -0700204
Adam Langleyfcf25832014-12-18 17:42:32 -0800205 s->method->ssl_clear(s);
206 s->client_version = s->version;
Adam Langley95c29f32014-06-20 12:00:00 -0700207
Adam Langleyfcf25832014-12-18 17:42:32 -0800208 return 1;
209}
Adam Langley95c29f32014-06-20 12:00:00 -0700210
Adam Langleyfcf25832014-12-18 17:42:32 -0800211SSL *SSL_new(SSL_CTX *ctx) {
212 SSL *s;
Adam Langley95c29f32014-06-20 12:00:00 -0700213
Adam Langleyfcf25832014-12-18 17:42:32 -0800214 if (ctx == NULL) {
215 OPENSSL_PUT_ERROR(SSL, SSL_new, SSL_R_NULL_SSL_CTX);
216 return NULL;
217 }
218 if (ctx->method == NULL) {
219 OPENSSL_PUT_ERROR(SSL, SSL_new, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
220 return NULL;
221 }
Adam Langley95c29f32014-06-20 12:00:00 -0700222
Adam Langleyfcf25832014-12-18 17:42:32 -0800223 s = (SSL *)OPENSSL_malloc(sizeof(SSL));
224 if (s == NULL) {
225 goto err;
226 }
227 memset(s, 0, sizeof(SSL));
Adam Langley95c29f32014-06-20 12:00:00 -0700228
Adam Langleyfcf25832014-12-18 17:42:32 -0800229 s->min_version = ctx->min_version;
230 s->max_version = ctx->max_version;
David Benjamin1eb367c2014-12-12 18:17:51 -0500231
Adam Langleyfcf25832014-12-18 17:42:32 -0800232 s->options = ctx->options;
233 s->mode = ctx->mode;
234 s->max_cert_list = ctx->max_cert_list;
Adam Langley95c29f32014-06-20 12:00:00 -0700235
Adam Langleyfcf25832014-12-18 17:42:32 -0800236 if (ctx->cert != NULL) {
237 /* Earlier library versions used to copy the pointer to the CERT, not its
238 * contents; only when setting new parameters for the per-SSL copy,
239 * ssl_cert_new would be called (and the direct reference to the
240 * per-SSL_CTX settings would be lost, but those still were indirectly
241 * accessed for various purposes, and for that reason they used to be known
242 * as s->ctx->default_cert). Now we don't look at the SSL_CTX's CERT after
243 * having duplicated it once. */
Adam Langley95c29f32014-06-20 12:00:00 -0700244
Adam Langleyfcf25832014-12-18 17:42:32 -0800245 s->cert = ssl_cert_dup(ctx->cert);
246 if (s->cert == NULL) {
247 goto err;
248 }
249 } else {
250 s->cert = NULL; /* Cannot really happen (see SSL_CTX_new) */
251 }
Adam Langley95c29f32014-06-20 12:00:00 -0700252
Adam Langleyfcf25832014-12-18 17:42:32 -0800253 s->read_ahead = ctx->read_ahead;
254 s->msg_callback = ctx->msg_callback;
255 s->msg_callback_arg = ctx->msg_callback_arg;
256 s->verify_mode = ctx->verify_mode;
257 s->sid_ctx_length = ctx->sid_ctx_length;
258 assert(s->sid_ctx_length <= sizeof s->sid_ctx);
259 memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx));
260 s->verify_callback = ctx->default_verify_callback;
261 s->generate_session_id = ctx->generate_session_id;
Adam Langley95c29f32014-06-20 12:00:00 -0700262
Adam Langleyfcf25832014-12-18 17:42:32 -0800263 s->param = X509_VERIFY_PARAM_new();
264 if (!s->param) {
265 goto err;
266 }
267 X509_VERIFY_PARAM_inherit(s->param, ctx->param);
268 s->quiet_shutdown = ctx->quiet_shutdown;
269 s->max_send_fragment = ctx->max_send_fragment;
Adam Langley95c29f32014-06-20 12:00:00 -0700270
Adam Langleyfcf25832014-12-18 17:42:32 -0800271 CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
272 s->ctx = ctx;
273 s->tlsext_debug_cb = 0;
274 s->tlsext_debug_arg = NULL;
275 s->tlsext_ticket_expected = 0;
276 CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
277 s->initial_ctx = ctx;
278 if (ctx->tlsext_ecpointformatlist) {
279 s->tlsext_ecpointformatlist = BUF_memdup(
280 ctx->tlsext_ecpointformatlist, ctx->tlsext_ecpointformatlist_length);
281 if (!s->tlsext_ecpointformatlist) {
282 goto err;
283 }
284 s->tlsext_ecpointformatlist_length = ctx->tlsext_ecpointformatlist_length;
285 }
Adam Langley95c29f32014-06-20 12:00:00 -0700286
Adam Langleyfcf25832014-12-18 17:42:32 -0800287 if (ctx->tlsext_ellipticcurvelist) {
288 s->tlsext_ellipticcurvelist =
289 BUF_memdup(ctx->tlsext_ellipticcurvelist,
290 ctx->tlsext_ellipticcurvelist_length * 2);
291 if (!s->tlsext_ellipticcurvelist) {
292 goto err;
293 }
294 s->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length;
295 }
296 s->next_proto_negotiated = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700297
Adam Langleyfcf25832014-12-18 17:42:32 -0800298 if (s->ctx->alpn_client_proto_list) {
299 s->alpn_client_proto_list = BUF_memdup(s->ctx->alpn_client_proto_list,
300 s->ctx->alpn_client_proto_list_len);
301 if (s->alpn_client_proto_list == NULL) {
302 goto err;
303 }
304 s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
305 }
Adam Langley95c29f32014-06-20 12:00:00 -0700306
Adam Langleyfcf25832014-12-18 17:42:32 -0800307 s->verify_result = X509_V_OK;
308 s->method = ctx->method;
Adam Langley95c29f32014-06-20 12:00:00 -0700309
Adam Langleyfcf25832014-12-18 17:42:32 -0800310 if (!s->method->ssl_new(s)) {
311 goto err;
312 }
313 s->enc_method = ssl3_get_enc_method(s->version);
314 assert(s->enc_method != NULL);
Adam Langley95c29f32014-06-20 12:00:00 -0700315
Adam Langleyfcf25832014-12-18 17:42:32 -0800316 s->references = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700317
Adam Langleyfcf25832014-12-18 17:42:32 -0800318 SSL_clear(s);
Adam Langley95c29f32014-06-20 12:00:00 -0700319
Adam Langleyfcf25832014-12-18 17:42:32 -0800320 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700321
Adam Langleyfcf25832014-12-18 17:42:32 -0800322 s->psk_identity_hint = NULL;
323 if (ctx->psk_identity_hint) {
324 s->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint);
325 if (s->psk_identity_hint == NULL) {
326 goto err;
327 }
328 }
329 s->psk_client_callback = ctx->psk_client_callback;
330 s->psk_server_callback = ctx->psk_server_callback;
Adam Langley95c29f32014-06-20 12:00:00 -0700331
Adam Langleyfcf25832014-12-18 17:42:32 -0800332 s->signed_cert_timestamps_enabled = s->ctx->signed_cert_timestamps_enabled;
333 s->ocsp_stapling_enabled = s->ctx->ocsp_stapling_enabled;
HÃ¥vard Molland9169c962014-08-14 14:42:37 +0200334
Adam Langleyfcf25832014-12-18 17:42:32 -0800335 return s;
336
Adam Langley95c29f32014-06-20 12:00:00 -0700337err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800338 if (s != NULL) {
339 if (s->cert != NULL) {
340 ssl_cert_free(s->cert);
Adam Langley95c29f32014-06-20 12:00:00 -0700341 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800342 if (s->ctx != NULL) {
343 SSL_CTX_free(s->ctx);
Adam Langley95c29f32014-06-20 12:00:00 -0700344 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800345 OPENSSL_free(s);
346 }
347 OPENSSL_PUT_ERROR(SSL, SSL_new, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -0700348
Adam Langleyfcf25832014-12-18 17:42:32 -0800349 return NULL;
350}
Adam Langley95c29f32014-06-20 12:00:00 -0700351
Adam Langleyfcf25832014-12-18 17:42:32 -0800352int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx,
353 unsigned int sid_ctx_len) {
354 if (sid_ctx_len > sizeof ctx->sid_ctx) {
355 OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_session_id_context,
356 SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
357 return 0;
358 }
359 ctx->sid_ctx_length = sid_ctx_len;
360 memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len);
Adam Langley95c29f32014-06-20 12:00:00 -0700361
Adam Langleyfcf25832014-12-18 17:42:32 -0800362 return 1;
363}
Adam Langley95c29f32014-06-20 12:00:00 -0700364
Adam Langleyfcf25832014-12-18 17:42:32 -0800365int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
366 unsigned int sid_ctx_len) {
367 if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
368 OPENSSL_PUT_ERROR(SSL, SSL_set_session_id_context,
369 SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
370 return 0;
371 }
372 ssl->sid_ctx_length = sid_ctx_len;
373 memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len);
Adam Langley95c29f32014-06-20 12:00:00 -0700374
Adam Langleyfcf25832014-12-18 17:42:32 -0800375 return 1;
376}
Adam Langley95c29f32014-06-20 12:00:00 -0700377
Adam Langleyfcf25832014-12-18 17:42:32 -0800378int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) {
379 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
380 ctx->generate_session_id = cb;
381 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
382 return 1;
383}
Adam Langley95c29f32014-06-20 12:00:00 -0700384
Adam Langleyfcf25832014-12-18 17:42:32 -0800385int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) {
386 CRYPTO_w_lock(CRYPTO_LOCK_SSL);
387 ssl->generate_session_id = cb;
388 CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
389 return 1;
390}
Adam Langley95c29f32014-06-20 12:00:00 -0700391
Adam Langleyfcf25832014-12-18 17:42:32 -0800392int SSL_has_matching_session_id(const SSL *ssl, const uint8_t *id,
393 unsigned int id_len) {
394 /* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how we
395 * can "construct" a session to give us the desired check - ie. to find if
396 * there's a session in the hash table that would conflict with any new
397 * session built out of this id/id_len and the ssl_version in use by this
398 * SSL. */
399 SSL_SESSION r, *p;
Adam Langley95c29f32014-06-20 12:00:00 -0700400
Adam Langleyfcf25832014-12-18 17:42:32 -0800401 if (id_len > sizeof r.session_id) {
402 return 0;
403 }
Adam Langley95c29f32014-06-20 12:00:00 -0700404
Adam Langleyfcf25832014-12-18 17:42:32 -0800405 r.ssl_version = ssl->version;
406 r.session_id_length = id_len;
407 memcpy(r.session_id, id, id_len);
Adam Langley95c29f32014-06-20 12:00:00 -0700408
Adam Langleyfcf25832014-12-18 17:42:32 -0800409 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
410 p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r);
411 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
412 return p != NULL;
413}
Adam Langley95c29f32014-06-20 12:00:00 -0700414
Adam Langleyfcf25832014-12-18 17:42:32 -0800415int SSL_CTX_set_purpose(SSL_CTX *s, int purpose) {
416 return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
417}
418
419int SSL_set_purpose(SSL *s, int purpose) {
420 return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
421}
422
423int SSL_CTX_set_trust(SSL_CTX *s, int trust) {
424 return X509_VERIFY_PARAM_set_trust(s->param, trust);
425}
426
427int SSL_set_trust(SSL *s, int trust) {
428 return X509_VERIFY_PARAM_set_trust(s->param, trust);
429}
430
431int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) {
432 return X509_VERIFY_PARAM_set1(ctx->param, vpm);
433}
434
435int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) {
436 return X509_VERIFY_PARAM_set1(ssl->param, vpm);
437}
Adam Langley95c29f32014-06-20 12:00:00 -0700438
Adam Langley858a88d2014-06-20 12:00:00 -0700439void ssl_cipher_preference_list_free(
Adam Langleyfcf25832014-12-18 17:42:32 -0800440 struct ssl_cipher_preference_list_st *cipher_list) {
441 sk_SSL_CIPHER_free(cipher_list->ciphers);
442 OPENSSL_free(cipher_list->in_group_flags);
443 OPENSSL_free(cipher_list);
444}
Adam Langley858a88d2014-06-20 12:00:00 -0700445
Adam Langleyfcf25832014-12-18 17:42:32 -0800446struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_dup(
447 struct ssl_cipher_preference_list_st *cipher_list) {
448 struct ssl_cipher_preference_list_st *ret = NULL;
449 size_t n = sk_SSL_CIPHER_num(cipher_list->ciphers);
Adam Langley858a88d2014-06-20 12:00:00 -0700450
Adam Langleyfcf25832014-12-18 17:42:32 -0800451 ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
452 if (!ret) {
453 goto err;
454 }
455
456 ret->ciphers = NULL;
457 ret->in_group_flags = NULL;
458 ret->ciphers = sk_SSL_CIPHER_dup(cipher_list->ciphers);
459 if (!ret->ciphers) {
460 goto err;
461 }
462 ret->in_group_flags = BUF_memdup(cipher_list->in_group_flags, n);
463 if (!ret->in_group_flags) {
464 goto err;
465 }
466
467 return ret;
Adam Langley858a88d2014-06-20 12:00:00 -0700468
469err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800470 if (ret && ret->ciphers) {
471 sk_SSL_CIPHER_free(ret->ciphers);
472 }
473 if (ret) {
474 OPENSSL_free(ret);
475 }
476 return NULL;
477}
Adam Langley858a88d2014-06-20 12:00:00 -0700478
Adam Langleyfcf25832014-12-18 17:42:32 -0800479struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_from_ciphers(
480 STACK_OF(SSL_CIPHER) * ciphers) {
481 struct ssl_cipher_preference_list_st *ret = NULL;
482 size_t n = sk_SSL_CIPHER_num(ciphers);
Adam Langley858a88d2014-06-20 12:00:00 -0700483
Adam Langleyfcf25832014-12-18 17:42:32 -0800484 ret = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
485 if (!ret) {
486 goto err;
487 }
488 ret->ciphers = NULL;
489 ret->in_group_flags = NULL;
490 ret->ciphers = sk_SSL_CIPHER_dup(ciphers);
491 if (!ret->ciphers) {
492 goto err;
493 }
494 ret->in_group_flags = OPENSSL_malloc(n);
495 if (!ret->in_group_flags) {
496 goto err;
497 }
498 memset(ret->in_group_flags, 0, n);
499 return ret;
Adam Langley858a88d2014-06-20 12:00:00 -0700500
501err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800502 if (ret && ret->ciphers) {
503 sk_SSL_CIPHER_free(ret->ciphers);
504 }
505 if (ret) {
506 OPENSSL_free(ret);
507 }
508 return NULL;
509}
Adam Langley858a88d2014-06-20 12:00:00 -0700510
Adam Langleyfcf25832014-12-18 17:42:32 -0800511X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { return ctx->param; }
Adam Langley95c29f32014-06-20 12:00:00 -0700512
Adam Langleyfcf25832014-12-18 17:42:32 -0800513X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { return ssl->param; }
Adam Langley95c29f32014-06-20 12:00:00 -0700514
Adam Langleyfcf25832014-12-18 17:42:32 -0800515void SSL_certs_clear(SSL *s) { ssl_cert_clear_certs(s->cert); }
Adam Langley95c29f32014-06-20 12:00:00 -0700516
Adam Langleyfcf25832014-12-18 17:42:32 -0800517void SSL_free(SSL *s) {
518 int i;
Adam Langley95c29f32014-06-20 12:00:00 -0700519
Adam Langleyfcf25832014-12-18 17:42:32 -0800520 if (s == NULL) {
521 return;
522 }
Adam Langley95c29f32014-06-20 12:00:00 -0700523
Adam Langleyfcf25832014-12-18 17:42:32 -0800524 i = CRYPTO_add(&s->references, -1, CRYPTO_LOCK_SSL);
525 if (i > 0) {
526 return;
527 }
Adam Langley95c29f32014-06-20 12:00:00 -0700528
Adam Langleyfcf25832014-12-18 17:42:32 -0800529 if (s->param) {
530 X509_VERIFY_PARAM_free(s->param);
531 }
Adam Langley95c29f32014-06-20 12:00:00 -0700532
Adam Langleyfcf25832014-12-18 17:42:32 -0800533 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -0700534
Adam Langleyfcf25832014-12-18 17:42:32 -0800535 if (s->bbio != NULL) {
536 /* If the buffering BIO is in place, pop it off */
537 if (s->bbio == s->wbio) {
538 s->wbio = BIO_pop(s->wbio);
539 }
540 BIO_free(s->bbio);
541 s->bbio = NULL;
542 }
Adam Langley95c29f32014-06-20 12:00:00 -0700543
Adam Langleyfcf25832014-12-18 17:42:32 -0800544 if (s->rbio != NULL) {
545 BIO_free_all(s->rbio);
546 }
Adam Langley95c29f32014-06-20 12:00:00 -0700547
Adam Langleyfcf25832014-12-18 17:42:32 -0800548 if (s->wbio != NULL && s->wbio != s->rbio) {
549 BIO_free_all(s->wbio);
550 }
Adam Langley95c29f32014-06-20 12:00:00 -0700551
Adam Langleyfcf25832014-12-18 17:42:32 -0800552 if (s->init_buf != NULL) {
553 BUF_MEM_free(s->init_buf);
554 }
Adam Langley95c29f32014-06-20 12:00:00 -0700555
Adam Langleyfcf25832014-12-18 17:42:32 -0800556 /* add extra stuff */
557 if (s->cipher_list != NULL) {
558 ssl_cipher_preference_list_free(s->cipher_list);
559 }
560 if (s->cipher_list_by_id != NULL) {
561 sk_SSL_CIPHER_free(s->cipher_list_by_id);
562 }
Adam Langley95c29f32014-06-20 12:00:00 -0700563
Adam Langleyfcf25832014-12-18 17:42:32 -0800564 if (s->session != NULL) {
565 ssl_clear_bad_session(s);
566 SSL_SESSION_free(s->session);
567 }
Adam Langley95c29f32014-06-20 12:00:00 -0700568
Adam Langleyfcf25832014-12-18 17:42:32 -0800569 ssl_clear_cipher_ctx(s);
570 ssl_clear_hash_ctx(&s->read_hash);
571 ssl_clear_hash_ctx(&s->write_hash);
Adam Langley95c29f32014-06-20 12:00:00 -0700572
Adam Langleyfcf25832014-12-18 17:42:32 -0800573 if (s->cert != NULL) {
574 ssl_cert_free(s->cert);
575 }
Adam Langley0289c732014-06-20 12:00:00 -0700576
Adam Langleyfcf25832014-12-18 17:42:32 -0800577 if (s->tlsext_hostname) {
578 OPENSSL_free(s->tlsext_hostname);
579 }
580 if (s->initial_ctx) {
581 SSL_CTX_free(s->initial_ctx);
582 }
583 if (s->tlsext_ecpointformatlist) {
584 OPENSSL_free(s->tlsext_ecpointformatlist);
585 }
586 if (s->tlsext_ellipticcurvelist) {
587 OPENSSL_free(s->tlsext_ellipticcurvelist);
588 }
589 if (s->alpn_client_proto_list) {
590 OPENSSL_free(s->alpn_client_proto_list);
591 }
592 if (s->tlsext_channel_id_private) {
593 EVP_PKEY_free(s->tlsext_channel_id_private);
594 }
595 if (s->psk_identity_hint) {
596 OPENSSL_free(s->psk_identity_hint);
597 }
598 if (s->client_CA != NULL) {
599 sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
600 }
601 if (s->next_proto_negotiated) {
602 OPENSSL_free(s->next_proto_negotiated);
603 }
604 if (s->srtp_profiles) {
605 sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
606 }
Adam Langley95c29f32014-06-20 12:00:00 -0700607
Adam Langleyfcf25832014-12-18 17:42:32 -0800608 if (s->method != NULL) {
609 s->method->ssl_free(s);
610 }
611 if (s->ctx) {
612 SSL_CTX_free(s->ctx);
613 }
Adam Langley95c29f32014-06-20 12:00:00 -0700614
Adam Langleyfcf25832014-12-18 17:42:32 -0800615 OPENSSL_free(s);
616}
Adam Langley95c29f32014-06-20 12:00:00 -0700617
Adam Langleyfcf25832014-12-18 17:42:32 -0800618void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) {
619 /* If the output buffering BIO is still in place, remove it. */
620 if (s->bbio != NULL) {
621 if (s->wbio == s->bbio) {
622 s->wbio = s->wbio->next_bio;
623 s->bbio->next_bio = NULL;
624 }
625 }
Adam Langley95c29f32014-06-20 12:00:00 -0700626
Adam Langleyfcf25832014-12-18 17:42:32 -0800627 if (s->rbio != NULL && s->rbio != rbio) {
628 BIO_free_all(s->rbio);
629 }
630 if (s->wbio != NULL && s->wbio != wbio && s->rbio != s->wbio) {
631 BIO_free_all(s->wbio);
632 }
633 s->rbio = rbio;
634 s->wbio = wbio;
635}
Adam Langley95c29f32014-06-20 12:00:00 -0700636
Adam Langleyfcf25832014-12-18 17:42:32 -0800637BIO *SSL_get_rbio(const SSL *s) { return s->rbio; }
Adam Langley95c29f32014-06-20 12:00:00 -0700638
Adam Langleyfcf25832014-12-18 17:42:32 -0800639BIO *SSL_get_wbio(const SSL *s) { return s->wbio; }
Adam Langley95c29f32014-06-20 12:00:00 -0700640
Adam Langleyfcf25832014-12-18 17:42:32 -0800641int SSL_get_fd(const SSL *s) { return SSL_get_rfd(s); }
Adam Langley95c29f32014-06-20 12:00:00 -0700642
Adam Langleyfcf25832014-12-18 17:42:32 -0800643int SSL_get_rfd(const SSL *s) {
644 int ret = -1;
645 BIO *b, *r;
Adam Langley95c29f32014-06-20 12:00:00 -0700646
Adam Langleyfcf25832014-12-18 17:42:32 -0800647 b = SSL_get_rbio(s);
648 r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
649 if (r != NULL) {
650 BIO_get_fd(r, &ret);
651 }
652 return ret;
653}
Adam Langley95c29f32014-06-20 12:00:00 -0700654
Adam Langleyfcf25832014-12-18 17:42:32 -0800655int SSL_get_wfd(const SSL *s) {
656 int ret = -1;
657 BIO *b, *r;
Adam Langley95c29f32014-06-20 12:00:00 -0700658
Adam Langleyfcf25832014-12-18 17:42:32 -0800659 b = SSL_get_wbio(s);
660 r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
661 if (r != NULL) {
662 BIO_get_fd(r, &ret);
663 }
Adam Langley95c29f32014-06-20 12:00:00 -0700664
Adam Langleyfcf25832014-12-18 17:42:32 -0800665 return ret;
666}
Adam Langley95c29f32014-06-20 12:00:00 -0700667
Adam Langleyfcf25832014-12-18 17:42:32 -0800668int SSL_set_fd(SSL *s, int fd) {
669 int ret = 0;
670 BIO *bio = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700671
Adam Langleyfcf25832014-12-18 17:42:32 -0800672 bio = BIO_new(BIO_s_fd());
Adam Langley95c29f32014-06-20 12:00:00 -0700673
Adam Langleyfcf25832014-12-18 17:42:32 -0800674 if (bio == NULL) {
675 OPENSSL_PUT_ERROR(SSL, SSL_set_fd, ERR_R_BUF_LIB);
676 goto err;
677 }
678 BIO_set_fd(bio, fd, BIO_NOCLOSE);
679 SSL_set_bio(s, bio, bio);
680 ret = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700681
Adam Langley95c29f32014-06-20 12:00:00 -0700682err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800683 return ret;
684}
Adam Langley95c29f32014-06-20 12:00:00 -0700685
Adam Langleyfcf25832014-12-18 17:42:32 -0800686int SSL_set_wfd(SSL *s, int fd) {
687 int ret = 0;
688 BIO *bio = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700689
Adam Langleyfcf25832014-12-18 17:42:32 -0800690 if (s->rbio == NULL || BIO_method_type(s->rbio) != BIO_TYPE_FD ||
691 (int)BIO_get_fd(s->rbio, NULL) != fd) {
692 bio = BIO_new(BIO_s_fd());
Adam Langley95c29f32014-06-20 12:00:00 -0700693
Adam Langleyfcf25832014-12-18 17:42:32 -0800694 if (bio == NULL) {
695 OPENSSL_PUT_ERROR(SSL, SSL_set_wfd, ERR_R_BUF_LIB);
696 goto err;
697 }
698 BIO_set_fd(bio, fd, BIO_NOCLOSE);
699 SSL_set_bio(s, SSL_get_rbio(s), bio);
700 } else {
701 SSL_set_bio(s, SSL_get_rbio(s), SSL_get_rbio(s));
702 }
703
704 ret = 1;
705
Adam Langley95c29f32014-06-20 12:00:00 -0700706err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800707 return ret;
708}
Adam Langley95c29f32014-06-20 12:00:00 -0700709
Adam Langleyfcf25832014-12-18 17:42:32 -0800710int SSL_set_rfd(SSL *s, int fd) {
711 int ret = 0;
712 BIO *bio = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700713
Adam Langleyfcf25832014-12-18 17:42:32 -0800714 if (s->wbio == NULL || BIO_method_type(s->wbio) != BIO_TYPE_FD ||
715 (int)BIO_get_fd(s->wbio, NULL) != fd) {
716 bio = BIO_new(BIO_s_fd());
Adam Langley95c29f32014-06-20 12:00:00 -0700717
Adam Langleyfcf25832014-12-18 17:42:32 -0800718 if (bio == NULL) {
719 OPENSSL_PUT_ERROR(SSL, SSL_set_rfd, ERR_R_BUF_LIB);
720 goto err;
721 }
722 BIO_set_fd(bio, fd, BIO_NOCLOSE);
723 SSL_set_bio(s, bio, SSL_get_wbio(s));
724 } else {
725 SSL_set_bio(s, SSL_get_wbio(s), SSL_get_wbio(s));
726 }
727 ret = 1;
728
Adam Langley95c29f32014-06-20 12:00:00 -0700729err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800730 return ret;
731}
Adam Langley95c29f32014-06-20 12:00:00 -0700732
733/* return length of latest Finished message we sent, copy to 'buf' */
Adam Langleyfcf25832014-12-18 17:42:32 -0800734size_t SSL_get_finished(const SSL *s, void *buf, size_t count) {
735 size_t ret = 0;
736
737 if (s->s3 != NULL) {
738 ret = s->s3->tmp.finish_md_len;
739 if (count > ret) {
740 count = ret;
741 }
742 memcpy(buf, s->s3->tmp.finish_md, count);
743 }
744
745 return ret;
746}
Adam Langley95c29f32014-06-20 12:00:00 -0700747
748/* return length of latest Finished message we expected, copy to 'buf' */
Adam Langleyfcf25832014-12-18 17:42:32 -0800749size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count) {
750 size_t ret = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700751
Adam Langleyfcf25832014-12-18 17:42:32 -0800752 if (s->s3 != NULL) {
753 ret = s->s3->tmp.peer_finish_md_len;
754 if (count > ret) {
755 count = ret;
756 }
757 memcpy(buf, s->s3->tmp.peer_finish_md, count);
758 }
Adam Langley95c29f32014-06-20 12:00:00 -0700759
Adam Langleyfcf25832014-12-18 17:42:32 -0800760 return ret;
761}
Adam Langley95c29f32014-06-20 12:00:00 -0700762
Adam Langleyfcf25832014-12-18 17:42:32 -0800763int SSL_get_verify_mode(const SSL *s) { return s->verify_mode; }
Adam Langley95c29f32014-06-20 12:00:00 -0700764
Adam Langleyfcf25832014-12-18 17:42:32 -0800765int SSL_get_verify_depth(const SSL *s) {
766 return X509_VERIFY_PARAM_get_depth(s->param);
767}
Adam Langley95c29f32014-06-20 12:00:00 -0700768
Adam Langleyfcf25832014-12-18 17:42:32 -0800769int (*SSL_get_verify_callback(const SSL *s))(int, X509_STORE_CTX *) {
770 return s->verify_callback;
771}
Adam Langley95c29f32014-06-20 12:00:00 -0700772
Adam Langleyfcf25832014-12-18 17:42:32 -0800773int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { return ctx->verify_mode; }
Adam Langley95c29f32014-06-20 12:00:00 -0700774
Adam Langleyfcf25832014-12-18 17:42:32 -0800775int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) {
776 return X509_VERIFY_PARAM_get_depth(ctx->param);
777}
Adam Langley95c29f32014-06-20 12:00:00 -0700778
Adam Langleyfcf25832014-12-18 17:42:32 -0800779int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int, X509_STORE_CTX *) {
780 return ctx->default_verify_callback;
781}
Adam Langley95c29f32014-06-20 12:00:00 -0700782
Adam Langleyfcf25832014-12-18 17:42:32 -0800783void SSL_set_verify(SSL *s, int mode,
784 int (*callback)(int ok, X509_STORE_CTX *ctx)) {
785 s->verify_mode = mode;
786 if (callback != NULL) {
787 s->verify_callback = callback;
788 }
789}
Adam Langley95c29f32014-06-20 12:00:00 -0700790
Adam Langleyfcf25832014-12-18 17:42:32 -0800791void SSL_set_verify_depth(SSL *s, int depth) {
792 X509_VERIFY_PARAM_set_depth(s->param, depth);
793}
Adam Langley95c29f32014-06-20 12:00:00 -0700794
Adam Langleyfcf25832014-12-18 17:42:32 -0800795void SSL_set_read_ahead(SSL *s, int yes) { s->read_ahead = yes; }
Adam Langley95c29f32014-06-20 12:00:00 -0700796
Adam Langleyfcf25832014-12-18 17:42:32 -0800797int SSL_get_read_ahead(const SSL *s) { return s->read_ahead; }
Adam Langley95c29f32014-06-20 12:00:00 -0700798
Adam Langleyfcf25832014-12-18 17:42:32 -0800799int SSL_pending(const SSL *s) {
800 /* SSL_pending cannot work properly if read-ahead is enabled
801 * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)), and it is
802 * impossible to fix since SSL_pending cannot report errors that may be
803 * observed while scanning the new data. (Note that SSL_pending() is often
804 * used as a boolean value, so we'd better not return -1.). */
805 return s->method->ssl_pending(s);
806}
Adam Langley95c29f32014-06-20 12:00:00 -0700807
Adam Langleyfcf25832014-12-18 17:42:32 -0800808X509 *SSL_get_peer_certificate(const SSL *s) {
809 X509 *r;
Adam Langley95c29f32014-06-20 12:00:00 -0700810
Adam Langleyfcf25832014-12-18 17:42:32 -0800811 if (s == NULL || s->session == NULL) {
812 r = NULL;
813 } else {
814 r = s->session->peer;
815 }
Adam Langley95c29f32014-06-20 12:00:00 -0700816
Adam Langleyfcf25832014-12-18 17:42:32 -0800817 if (r == NULL) {
818 return NULL;
819 }
Adam Langley95c29f32014-06-20 12:00:00 -0700820
Adam Langleyfcf25832014-12-18 17:42:32 -0800821 return X509_up_ref(r);
822}
823
824STACK_OF(X509) * SSL_get_peer_cert_chain(const SSL *s) {
825 STACK_OF(X509) * r;
826
827 if (s == NULL || s->session == NULL || s->session->sess_cert == NULL) {
828 r = NULL;
829 } else {
830 r = s->session->sess_cert->cert_chain;
831 }
832
833 /* If we are a client, cert_chain includes the peer's own certificate; if we
834 * are a server, it does not. */
835 return r;
836}
Adam Langley95c29f32014-06-20 12:00:00 -0700837
Adam Langley95c29f32014-06-20 12:00:00 -0700838/* Fix this so it checks all the valid key/cert options */
Adam Langleyfcf25832014-12-18 17:42:32 -0800839int SSL_CTX_check_private_key(const SSL_CTX *ctx) {
840 if (ctx == NULL || ctx->cert == NULL || ctx->cert->key->x509 == NULL) {
841 OPENSSL_PUT_ERROR(SSL, SSL_CTX_check_private_key,
842 SSL_R_NO_CERTIFICATE_ASSIGNED);
843 return 0;
844 }
845
846 if (ctx->cert->key->privatekey == NULL) {
847 OPENSSL_PUT_ERROR(SSL, SSL_CTX_check_private_key,
848 SSL_R_NO_PRIVATE_KEY_ASSIGNED);
849 return 0;
850 }
851
852 return X509_check_private_key(ctx->cert->key->x509,
853 ctx->cert->key->privatekey);
854}
Adam Langley95c29f32014-06-20 12:00:00 -0700855
856/* Fix this function so that it takes an optional type parameter */
Adam Langleyfcf25832014-12-18 17:42:32 -0800857int SSL_check_private_key(const SSL *ssl) {
858 if (ssl == NULL) {
859 OPENSSL_PUT_ERROR(SSL, SSL_check_private_key, ERR_R_PASSED_NULL_PARAMETER);
860 return 0;
861 }
Adam Langley95c29f32014-06-20 12:00:00 -0700862
Adam Langleyfcf25832014-12-18 17:42:32 -0800863 if (ssl->cert == NULL) {
864 OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
865 SSL_R_NO_CERTIFICATE_ASSIGNED);
866 return 0;
867 }
Adam Langley95c29f32014-06-20 12:00:00 -0700868
Adam Langleyfcf25832014-12-18 17:42:32 -0800869 if (ssl->cert->key->x509 == NULL) {
870 OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
871 SSL_R_NO_CERTIFICATE_ASSIGNED);
872 return 0;
873 }
David Benjamin0b145c22014-11-26 20:10:09 -0500874
Adam Langleyfcf25832014-12-18 17:42:32 -0800875 if (ssl->cert->key->privatekey == NULL) {
876 OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
877 SSL_R_NO_PRIVATE_KEY_ASSIGNED);
878 return 0;
879 }
Adam Langley95c29f32014-06-20 12:00:00 -0700880
Adam Langleyfcf25832014-12-18 17:42:32 -0800881 return X509_check_private_key(ssl->cert->key->x509,
882 ssl->cert->key->privatekey);
883}
Adam Langley95c29f32014-06-20 12:00:00 -0700884
Adam Langleyfcf25832014-12-18 17:42:32 -0800885int SSL_accept(SSL *s) {
886 if (s->handshake_func == 0) {
887 /* Not properly initialized yet */
888 SSL_set_accept_state(s);
889 }
David Benjamin0b145c22014-11-26 20:10:09 -0500890
Adam Langleyfcf25832014-12-18 17:42:32 -0800891 if (s->handshake_func != s->method->ssl_accept) {
892 OPENSSL_PUT_ERROR(SSL, SSL_connect, ERR_R_INTERNAL_ERROR);
893 return -1;
894 }
Adam Langley95c29f32014-06-20 12:00:00 -0700895
Adam Langleyfcf25832014-12-18 17:42:32 -0800896 return s->handshake_func(s);
897}
Adam Langley95c29f32014-06-20 12:00:00 -0700898
Adam Langleyfcf25832014-12-18 17:42:32 -0800899int SSL_connect(SSL *s) {
900 if (s->handshake_func == 0) {
901 /* Not properly initialized yet */
902 SSL_set_connect_state(s);
903 }
Adam Langley95c29f32014-06-20 12:00:00 -0700904
Adam Langleyfcf25832014-12-18 17:42:32 -0800905 if (s->handshake_func != s->method->ssl_connect) {
906 OPENSSL_PUT_ERROR(SSL, SSL_connect, ERR_R_INTERNAL_ERROR);
907 return -1;
908 }
Adam Langley95c29f32014-06-20 12:00:00 -0700909
Adam Langleyfcf25832014-12-18 17:42:32 -0800910 return s->handshake_func(s);
911}
Adam Langley95c29f32014-06-20 12:00:00 -0700912
Adam Langleyfcf25832014-12-18 17:42:32 -0800913long SSL_get_default_timeout(const SSL *s) {
914 return SSL_DEFAULT_SESSION_TIMEOUT;
915}
Adam Langley95c29f32014-06-20 12:00:00 -0700916
Adam Langleyfcf25832014-12-18 17:42:32 -0800917int SSL_read(SSL *s, void *buf, int num) {
918 if (s->handshake_func == 0) {
919 OPENSSL_PUT_ERROR(SSL, SSL_read, SSL_R_UNINITIALIZED);
920 return -1;
921 }
Adam Langley95c29f32014-06-20 12:00:00 -0700922
Adam Langleyfcf25832014-12-18 17:42:32 -0800923 if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
924 s->rwstate = SSL_NOTHING;
925 return 0;
926 }
Adam Langley95c29f32014-06-20 12:00:00 -0700927
Adam Langleyfcf25832014-12-18 17:42:32 -0800928 return s->method->ssl_read(s, buf, num);
929}
Adam Langley95c29f32014-06-20 12:00:00 -0700930
Adam Langleyfcf25832014-12-18 17:42:32 -0800931int SSL_peek(SSL *s, void *buf, int num) {
932 if (s->handshake_func == 0) {
933 OPENSSL_PUT_ERROR(SSL, SSL_peek, SSL_R_UNINITIALIZED);
934 return -1;
935 }
Adam Langley95c29f32014-06-20 12:00:00 -0700936
Adam Langleyfcf25832014-12-18 17:42:32 -0800937 if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
938 return 0;
939 }
Adam Langley95c29f32014-06-20 12:00:00 -0700940
Adam Langleyfcf25832014-12-18 17:42:32 -0800941 return s->method->ssl_peek(s, buf, num);
942}
Adam Langley95c29f32014-06-20 12:00:00 -0700943
Adam Langleyfcf25832014-12-18 17:42:32 -0800944int SSL_write(SSL *s, const void *buf, int num) {
945 if (s->handshake_func == 0) {
946 OPENSSL_PUT_ERROR(SSL, SSL_write, SSL_R_UNINITIALIZED);
947 return -1;
948 }
Adam Langley95c29f32014-06-20 12:00:00 -0700949
Adam Langleyfcf25832014-12-18 17:42:32 -0800950 if (s->shutdown & SSL_SENT_SHUTDOWN) {
951 s->rwstate = SSL_NOTHING;
952 OPENSSL_PUT_ERROR(SSL, SSL_write, SSL_R_PROTOCOL_IS_SHUTDOWN);
953 return -1;
954 }
Adam Langley95c29f32014-06-20 12:00:00 -0700955
Adam Langleyfcf25832014-12-18 17:42:32 -0800956 return s->method->ssl_write(s, buf, num);
957}
Adam Langley95c29f32014-06-20 12:00:00 -0700958
Adam Langleyfcf25832014-12-18 17:42:32 -0800959int SSL_shutdown(SSL *s) {
960 /* Note that this function behaves differently from what one might expect.
961 * Return values are 0 for no success (yet), 1 for success; but calling it
962 * once is usually not enough, even if blocking I/O is used (see
963 * ssl3_shutdown). */
Adam Langley95c29f32014-06-20 12:00:00 -0700964
Adam Langleyfcf25832014-12-18 17:42:32 -0800965 if (s->handshake_func == 0) {
966 OPENSSL_PUT_ERROR(SSL, SSL_shutdown, SSL_R_UNINITIALIZED);
967 return -1;
968 }
Adam Langley95c29f32014-06-20 12:00:00 -0700969
Adam Langleyfcf25832014-12-18 17:42:32 -0800970 if (!SSL_in_init(s)) {
971 return s->method->ssl_shutdown(s);
972 }
Adam Langley95c29f32014-06-20 12:00:00 -0700973
Adam Langleyfcf25832014-12-18 17:42:32 -0800974 return 1;
975}
Adam Langley95c29f32014-06-20 12:00:00 -0700976
Adam Langleyfcf25832014-12-18 17:42:32 -0800977int SSL_renegotiate(SSL *s) {
978 if (s->renegotiate == 0) {
979 s->renegotiate = 1;
980 }
Adam Langley95c29f32014-06-20 12:00:00 -0700981
Adam Langleyfcf25832014-12-18 17:42:32 -0800982 s->new_session = 1;
983 return s->method->ssl_renegotiate(s);
984}
Adam Langley95c29f32014-06-20 12:00:00 -0700985
Adam Langleyfcf25832014-12-18 17:42:32 -0800986int SSL_renegotiate_abbreviated(SSL *s) {
987 if (s->renegotiate == 0) {
988 s->renegotiate = 1;
989 }
Adam Langley95c29f32014-06-20 12:00:00 -0700990
Adam Langleyfcf25832014-12-18 17:42:32 -0800991 s->new_session = 0;
992 return s->method->ssl_renegotiate(s);
993}
Adam Langley95c29f32014-06-20 12:00:00 -0700994
Adam Langleyfcf25832014-12-18 17:42:32 -0800995int SSL_renegotiate_pending(SSL *s) {
996 /* becomes true when negotiation is requested; false again once a handshake
997 * has finished */
998 return s->renegotiate != 0;
999}
Adam Langley95c29f32014-06-20 12:00:00 -07001000
Adam Langleyfcf25832014-12-18 17:42:32 -08001001long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) {
1002 long l;
Adam Langley95c29f32014-06-20 12:00:00 -07001003
Adam Langleyfcf25832014-12-18 17:42:32 -08001004 switch (cmd) {
1005 case SSL_CTRL_GET_READ_AHEAD:
1006 return s->read_ahead;
Adam Langley95c29f32014-06-20 12:00:00 -07001007
Adam Langleyfcf25832014-12-18 17:42:32 -08001008 case SSL_CTRL_SET_READ_AHEAD:
1009 l = s->read_ahead;
1010 s->read_ahead = larg;
1011 return l;
Adam Langley95c29f32014-06-20 12:00:00 -07001012
Adam Langleyfcf25832014-12-18 17:42:32 -08001013 case SSL_CTRL_SET_MSG_CALLBACK_ARG:
1014 s->msg_callback_arg = parg;
1015 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -07001016
Adam Langleyfcf25832014-12-18 17:42:32 -08001017 case SSL_CTRL_OPTIONS:
1018 return s->options |= larg;
Adam Langley95c29f32014-06-20 12:00:00 -07001019
Adam Langleyfcf25832014-12-18 17:42:32 -08001020 case SSL_CTRL_CLEAR_OPTIONS:
1021 return s->options &= ~larg;
Adam Langley95c29f32014-06-20 12:00:00 -07001022
Adam Langleyfcf25832014-12-18 17:42:32 -08001023 case SSL_CTRL_MODE:
1024 return s->mode |= larg;
Adam Langley95c29f32014-06-20 12:00:00 -07001025
Adam Langleyfcf25832014-12-18 17:42:32 -08001026 case SSL_CTRL_CLEAR_MODE:
1027 return s->mode &= ~larg;
Adam Langley95c29f32014-06-20 12:00:00 -07001028
Adam Langleyfcf25832014-12-18 17:42:32 -08001029 case SSL_CTRL_GET_MAX_CERT_LIST:
1030 return s->max_cert_list;
Adam Langley95c29f32014-06-20 12:00:00 -07001031
Adam Langleyfcf25832014-12-18 17:42:32 -08001032 case SSL_CTRL_SET_MAX_CERT_LIST:
1033 l = s->max_cert_list;
1034 s->max_cert_list = larg;
1035 return l;
Adam Langley95c29f32014-06-20 12:00:00 -07001036
Adam Langleyfcf25832014-12-18 17:42:32 -08001037 case SSL_CTRL_SET_MTU:
1038 if (larg < (long)dtls1_min_mtu()) {
1039 return 0;
1040 }
1041 if (SSL_IS_DTLS(s)) {
1042 s->d1->mtu = larg;
1043 return larg;
1044 }
1045 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001046
Adam Langleyfcf25832014-12-18 17:42:32 -08001047 case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
1048 if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) {
1049 return 0;
1050 }
1051 s->max_send_fragment = larg;
1052 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -07001053
Adam Langleyfcf25832014-12-18 17:42:32 -08001054 case SSL_CTRL_GET_RI_SUPPORT:
1055 if (s->s3) {
1056 return s->s3->send_connection_binding;
1057 }
1058 return 0;
1059
1060 case SSL_CTRL_CERT_FLAGS:
1061 return s->cert->cert_flags |= larg;
1062
1063 case SSL_CTRL_CLEAR_CERT_FLAGS:
1064 return s->cert->cert_flags &= ~larg;
1065
1066 case SSL_CTRL_GET_RAW_CIPHERLIST:
1067 if (parg) {
1068 if (s->cert->ciphers_raw == NULL) {
1069 return 0;
1070 }
1071 *(uint8_t **)parg = s->cert->ciphers_raw;
1072 return (int)s->cert->ciphers_rawlen;
1073 }
1074
1075 /* Passing a NULL |parg| returns the size of a single
1076 * cipher suite value. */
1077 return 2;
1078
1079 default:
1080 return s->method->ssl_ctrl(s, cmd, larg, parg);
1081 }
1082}
1083
1084long SSL_callback_ctrl(SSL *s, int cmd, void (*fp)(void)) {
1085 switch (cmd) {
1086 case SSL_CTRL_SET_MSG_CALLBACK:
1087 s->msg_callback =
1088 (void (*)(int write_p, int version, int content_type, const void *buf,
1089 size_t len, SSL *ssl, void *arg))(fp);
1090 return 1;
1091
1092 default:
1093 return s->method->ssl_callback_ctrl(s, cmd, fp);
1094 }
1095}
1096
1097LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) { return ctx->sessions; }
1098
1099long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) {
1100 long l;
1101
1102 switch (cmd) {
1103 case SSL_CTRL_GET_READ_AHEAD:
1104 return ctx->read_ahead;
1105
1106 case SSL_CTRL_SET_READ_AHEAD:
1107 l = ctx->read_ahead;
1108 ctx->read_ahead = larg;
1109 return l;
1110
1111 case SSL_CTRL_SET_MSG_CALLBACK_ARG:
1112 ctx->msg_callback_arg = parg;
1113 return 1;
1114
1115 case SSL_CTRL_GET_MAX_CERT_LIST:
1116 return ctx->max_cert_list;
1117
1118 case SSL_CTRL_SET_MAX_CERT_LIST:
1119 l = ctx->max_cert_list;
1120 ctx->max_cert_list = larg;
1121 return l;
1122
1123 case SSL_CTRL_SET_SESS_CACHE_SIZE:
1124 l = ctx->session_cache_size;
1125 ctx->session_cache_size = larg;
1126 return l;
1127
1128 case SSL_CTRL_GET_SESS_CACHE_SIZE:
1129 return ctx->session_cache_size;
1130
1131 case SSL_CTRL_SET_SESS_CACHE_MODE:
1132 l = ctx->session_cache_mode;
1133 ctx->session_cache_mode = larg;
1134 return l;
1135
1136 case SSL_CTRL_GET_SESS_CACHE_MODE:
1137 return ctx->session_cache_mode;
1138
1139 case SSL_CTRL_SESS_NUMBER:
1140 return lh_SSL_SESSION_num_items(ctx->sessions);
1141
1142 case SSL_CTRL_SESS_CONNECT:
1143 return ctx->stats.sess_connect;
1144
1145 case SSL_CTRL_SESS_CONNECT_GOOD:
1146 return ctx->stats.sess_connect_good;
1147
1148 case SSL_CTRL_SESS_CONNECT_RENEGOTIATE:
1149 return ctx->stats.sess_connect_renegotiate;
1150
1151 case SSL_CTRL_SESS_ACCEPT:
1152 return ctx->stats.sess_accept;
1153
1154 case SSL_CTRL_SESS_ACCEPT_GOOD:
1155 return ctx->stats.sess_accept_good;
1156
1157 case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE:
1158 return ctx->stats.sess_accept_renegotiate;
1159
1160 case SSL_CTRL_SESS_HIT:
1161 return ctx->stats.sess_hit;
1162
1163 case SSL_CTRL_SESS_CB_HIT:
1164 return ctx->stats.sess_cb_hit;
1165
1166 case SSL_CTRL_SESS_MISSES:
1167 return ctx->stats.sess_miss;
1168
1169 case SSL_CTRL_SESS_TIMEOUTS:
1170 return ctx->stats.sess_timeout;
1171
1172 case SSL_CTRL_SESS_CACHE_FULL:
1173 return ctx->stats.sess_cache_full;
1174
1175 case SSL_CTRL_OPTIONS:
1176 return ctx->options |= larg;
1177
1178 case SSL_CTRL_CLEAR_OPTIONS:
1179 return ctx->options &= ~larg;
1180
1181 case SSL_CTRL_MODE:
1182 return ctx->mode |= larg;
1183
1184 case SSL_CTRL_CLEAR_MODE:
1185 return ctx->mode &= ~larg;
1186
1187 case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
1188 if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) {
1189 return 0;
1190 }
1191 ctx->max_send_fragment = larg;
1192 return 1;
1193
1194 case SSL_CTRL_CERT_FLAGS:
1195 return ctx->cert->cert_flags |= larg;
1196
1197 case SSL_CTRL_CLEAR_CERT_FLAGS:
1198 return ctx->cert->cert_flags &= ~larg;
1199
1200 default:
1201 return ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg);
1202 }
1203}
1204
1205long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp)(void)) {
1206 switch (cmd) {
1207 case SSL_CTRL_SET_MSG_CALLBACK:
1208 ctx->msg_callback =
1209 (void (*)(int write_p, int version, int content_type, const void *buf,
1210 size_t len, SSL *ssl, void *arg))(fp);
1211 return 1;
1212
1213 default:
1214 return ctx->method->ssl_ctx_callback_ctrl(ctx, cmd, fp);
1215 }
1216}
1217
1218int ssl_cipher_id_cmp(const void *in_a, const void *in_b) {
1219 long l;
1220 const SSL_CIPHER *a = in_a;
1221 const SSL_CIPHER *b = in_b;
1222 const long a_id = a->id;
1223 const long b_id = b->id;
1224
1225 l = a_id - b_id;
1226 if (l == 0L) {
1227 return 0;
1228 } else {
1229 return (l > 0) ? 1 : -1;
1230 }
1231}
1232
1233int ssl_cipher_ptr_id_cmp(const SSL_CIPHER **ap, const SSL_CIPHER **bp) {
1234 long l;
1235 const long a_id = (*ap)->id;
1236 const long b_id = (*bp)->id;
1237
1238 l = a_id - b_id;
1239 if (l == 0) {
1240 return 0;
1241 } else {
1242 return (l > 0) ? 1 : -1;
1243 }
1244}
1245
1246/* return a STACK of the ciphers available for the SSL and in order of
Adam Langley95c29f32014-06-20 12:00:00 -07001247 * preference */
Adam Langleyfcf25832014-12-18 17:42:32 -08001248STACK_OF(SSL_CIPHER) * SSL_get_ciphers(const SSL *s) {
1249 if (s == NULL) {
1250 return NULL;
1251 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001252
Adam Langleyfcf25832014-12-18 17:42:32 -08001253 if (s->cipher_list != NULL) {
1254 return s->cipher_list->ciphers;
1255 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001256
Adam Langleyfcf25832014-12-18 17:42:32 -08001257 if (s->version >= TLS1_1_VERSION && s->ctx != NULL &&
1258 s->ctx->cipher_list_tls11 != NULL) {
1259 return s->ctx->cipher_list_tls11->ciphers;
1260 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001261
Adam Langleyfcf25832014-12-18 17:42:32 -08001262 if (s->ctx != NULL && s->ctx->cipher_list != NULL) {
1263 return s->ctx->cipher_list->ciphers;
1264 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001265
Adam Langleyfcf25832014-12-18 17:42:32 -08001266 return NULL;
1267}
Adam Langley95c29f32014-06-20 12:00:00 -07001268
Adam Langleyfcf25832014-12-18 17:42:32 -08001269/* return a STACK of the ciphers available for the SSL and in order of
Adam Langley95c29f32014-06-20 12:00:00 -07001270 * algorithm id */
Adam Langleyfcf25832014-12-18 17:42:32 -08001271STACK_OF(SSL_CIPHER) * ssl_get_ciphers_by_id(SSL *s) {
1272 if (s == NULL) {
1273 return NULL;
1274 }
Adam Langley95c29f32014-06-20 12:00:00 -07001275
Adam Langleyfcf25832014-12-18 17:42:32 -08001276 if (s->cipher_list_by_id != NULL) {
1277 return s->cipher_list_by_id;
1278 }
Adam Langley95c29f32014-06-20 12:00:00 -07001279
Adam Langleyfcf25832014-12-18 17:42:32 -08001280 if (s->ctx != NULL && s->ctx->cipher_list_by_id != NULL) {
1281 return s->ctx->cipher_list_by_id;
1282 }
Adam Langley95c29f32014-06-20 12:00:00 -07001283
Adam Langleyfcf25832014-12-18 17:42:32 -08001284 return NULL;
1285}
Adam Langley95c29f32014-06-20 12:00:00 -07001286
Adam Langleyfcf25832014-12-18 17:42:32 -08001287/* The old interface to get the same thing as SSL_get_ciphers() */
1288const char *SSL_get_cipher_list(const SSL *s, int n) {
1289 const SSL_CIPHER *c;
1290 STACK_OF(SSL_CIPHER) * sk;
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001291
Adam Langleyfcf25832014-12-18 17:42:32 -08001292 if (s == NULL) {
1293 return NULL;
1294 }
Adam Langley95c29f32014-06-20 12:00:00 -07001295
Adam Langleyfcf25832014-12-18 17:42:32 -08001296 sk = SSL_get_ciphers(s);
1297 if (sk == NULL || n < 0 || (size_t)n >= sk_SSL_CIPHER_num(sk)) {
1298 return NULL;
1299 }
Adam Langley95c29f32014-06-20 12:00:00 -07001300
Adam Langleyfcf25832014-12-18 17:42:32 -08001301 c = sk_SSL_CIPHER_value(sk, n);
1302 if (c == NULL) {
1303 return NULL;
1304 }
Adam Langley95c29f32014-06-20 12:00:00 -07001305
Adam Langleyfcf25832014-12-18 17:42:32 -08001306 return c->name;
1307}
David Benjamin5491e3f2014-09-29 19:33:09 -04001308
Adam Langleyfcf25832014-12-18 17:42:32 -08001309/* specify the ciphers to be used by default by the SSL_CTX */
1310int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) {
1311 STACK_OF(SSL_CIPHER) *sk;
Adam Langley95c29f32014-06-20 12:00:00 -07001312
Adam Langleyfcf25832014-12-18 17:42:32 -08001313 sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list,
1314 &ctx->cipher_list_by_id, str, ctx->cert);
1315 /* ssl_create_cipher_list may return an empty stack if it was unable to find
1316 * a cipher matching the given rule string (for example if the rule string
1317 * specifies a cipher which has been disabled). This is not an error as far
1318 * as ssl_create_cipher_list is concerned, and hence ctx->cipher_list and
1319 * ctx->cipher_list_by_id has been updated. */
1320 if (sk == NULL) {
1321 return 0;
1322 } else if (sk_SSL_CIPHER_num(sk) == 0) {
1323 OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_cipher_list, SSL_R_NO_CIPHER_MATCH);
1324 return 0;
1325 }
Adam Langley95c29f32014-06-20 12:00:00 -07001326
Adam Langleyfcf25832014-12-18 17:42:32 -08001327 return 1;
1328}
David Benjamin39482a12014-07-20 13:30:15 -04001329
Adam Langleyfcf25832014-12-18 17:42:32 -08001330int SSL_CTX_set_cipher_list_tls11(SSL_CTX *ctx, const char *str) {
1331 STACK_OF(SSL_CIPHER) *sk;
Adam Langley95c29f32014-06-20 12:00:00 -07001332
Adam Langleyfcf25832014-12-18 17:42:32 -08001333 sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list_tls11, NULL, str,
1334 ctx->cert);
1335 if (sk == NULL) {
1336 return 0;
1337 } else if (sk_SSL_CIPHER_num(sk) == 0) {
1338 OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_cipher_list_tls11,
1339 SSL_R_NO_CIPHER_MATCH);
1340 return 0;
1341 }
David Benjamin9f2c0d72014-10-21 22:00:19 -04001342
Adam Langleyfcf25832014-12-18 17:42:32 -08001343 return 1;
1344}
Adam Langley95c29f32014-06-20 12:00:00 -07001345
Adam Langleyfcf25832014-12-18 17:42:32 -08001346/* specify the ciphers to be used by the SSL */
1347int SSL_set_cipher_list(SSL *s, const char *str) {
1348 STACK_OF(SSL_CIPHER) *sk;
Adam Langley95c29f32014-06-20 12:00:00 -07001349
Adam Langleyfcf25832014-12-18 17:42:32 -08001350 sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list,
1351 &s->cipher_list_by_id, str, s->cert);
David Benjamin39482a12014-07-20 13:30:15 -04001352
Adam Langleyfcf25832014-12-18 17:42:32 -08001353 /* see comment in SSL_CTX_set_cipher_list */
1354 if (sk == NULL) {
1355 return 0;
1356 } else if (sk_SSL_CIPHER_num(sk) == 0) {
1357 OPENSSL_PUT_ERROR(SSL, SSL_set_cipher_list, SSL_R_NO_CIPHER_MATCH);
1358 return 0;
1359 }
David Benjamin39482a12014-07-20 13:30:15 -04001360
Adam Langleyfcf25832014-12-18 17:42:32 -08001361 return 1;
1362}
Adam Langley95c29f32014-06-20 12:00:00 -07001363
Adam Langleyfcf25832014-12-18 17:42:32 -08001364int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p) {
1365 size_t i;
1366 const SSL_CIPHER *c;
1367 CERT *ct = s->cert;
1368 uint8_t *q;
1369 /* Set disabled masks for this session */
1370 ssl_set_client_disabled(s);
Adam Langley29707792014-06-20 12:00:00 -07001371
Adam Langleyfcf25832014-12-18 17:42:32 -08001372 if (sk == NULL) {
1373 return 0;
1374 }
1375 q = p;
Adam Langley95c29f32014-06-20 12:00:00 -07001376
Adam Langleyfcf25832014-12-18 17:42:32 -08001377 for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
1378 c = sk_SSL_CIPHER_value(sk, i);
1379 /* Skip disabled ciphers */
1380 if (c->algorithm_ssl & ct->mask_ssl ||
1381 c->algorithm_mkey & ct->mask_k ||
1382 c->algorithm_auth & ct->mask_a) {
1383 continue;
1384 }
1385 s2n(ssl3_get_cipher_value(c), p);
1386 }
1387
1388 /* If all ciphers were disabled, return the error to the caller. */
1389 if (p == q) {
1390 return 0;
1391 }
1392
1393 /* Add SCSVs. */
1394 if (!s->renegotiate) {
1395 s2n(SSL3_CK_SCSV & 0xffff, p);
1396 }
1397
1398 if (s->fallback_scsv) {
1399 s2n(SSL3_CK_FALLBACK_SCSV & 0xffff, p);
1400 }
1401
1402 return p - q;
1403}
1404
1405STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
1406 CBS cipher_suites = *cbs;
1407 const SSL_CIPHER *c;
1408 STACK_OF(SSL_CIPHER) * sk;
1409
1410 if (s->s3) {
1411 s->s3->send_connection_binding = 0;
1412 }
1413
1414 if (CBS_len(&cipher_suites) % 2 != 0) {
1415 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
1416 SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
1417 return NULL;
1418 }
1419
1420 sk = sk_SSL_CIPHER_new_null();
1421 if (sk == NULL) {
1422 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
1423 goto err;
1424 }
1425
1426 if (!CBS_stow(&cipher_suites, &s->cert->ciphers_raw,
1427 &s->cert->ciphers_rawlen)) {
1428 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
1429 goto err;
1430 }
1431
1432 while (CBS_len(&cipher_suites) > 0) {
1433 uint16_t cipher_suite;
1434
1435 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
1436 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_INTERNAL_ERROR);
1437 goto err;
1438 }
1439
1440 /* Check for SCSV. */
1441 if (s->s3 && cipher_suite == (SSL3_CK_SCSV & 0xffff)) {
1442 /* SCSV is fatal if renegotiating. */
1443 if (s->renegotiate) {
1444 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
1445 SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
1446 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
1447 goto err;
1448 }
1449 s->s3->send_connection_binding = 1;
1450 continue;
1451 }
1452
1453 /* Check for FALLBACK_SCSV. */
1454 if (s->s3 && cipher_suite == (SSL3_CK_FALLBACK_SCSV & 0xffff)) {
1455 uint16_t max_version = ssl3_get_max_server_version(s);
1456 if (SSL_IS_DTLS(s) ? (uint16_t)s->version > max_version
1457 : (uint16_t)s->version < max_version) {
1458 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
1459 SSL_R_INAPPROPRIATE_FALLBACK);
1460 ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_INAPPROPRIATE_FALLBACK);
1461 goto err;
1462 }
1463 continue;
1464 }
1465
1466 c = ssl3_get_cipher_by_value(cipher_suite);
1467 if (c != NULL && !sk_SSL_CIPHER_push(sk, c)) {
1468 OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
1469 goto err;
1470 }
1471 }
1472
1473 return sk;
David Benjamin9f2c0d72014-10-21 22:00:19 -04001474
Adam Langley95c29f32014-06-20 12:00:00 -07001475err:
Adam Langleyfcf25832014-12-18 17:42:32 -08001476 if (sk != NULL) {
1477 sk_SSL_CIPHER_free(sk);
1478 }
1479 return NULL;
1480}
Adam Langley95c29f32014-06-20 12:00:00 -07001481
1482
Adam Langleyfcf25832014-12-18 17:42:32 -08001483/* return a servername extension value if provided in Client Hello, or NULL. So
1484 * far, only host_name types are defined (RFC 3546). */
1485const char *SSL_get_servername(const SSL *s, const int type) {
1486 if (type != TLSEXT_NAMETYPE_host_name) {
1487 return NULL;
1488 }
Adam Langley95c29f32014-06-20 12:00:00 -07001489
Adam Langleyfcf25832014-12-18 17:42:32 -08001490 return s->session && !s->tlsext_hostname ? s->session->tlsext_hostname
1491 : s->tlsext_hostname;
1492}
Adam Langley95c29f32014-06-20 12:00:00 -07001493
Adam Langleyfcf25832014-12-18 17:42:32 -08001494int SSL_get_servername_type(const SSL *s) {
1495 if (s->session &&
1496 (!s->tlsext_hostname ? s->session->tlsext_hostname : s->tlsext_hostname)) {
1497 return TLSEXT_NAMETYPE_host_name;
1498 }
Adam Langley95c29f32014-06-20 12:00:00 -07001499
Adam Langleyfcf25832014-12-18 17:42:32 -08001500 return -1;
1501}
Adam Langley95c29f32014-06-20 12:00:00 -07001502
Adam Langleyfcf25832014-12-18 17:42:32 -08001503void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx) {
1504 ctx->signed_cert_timestamps_enabled = 1;
1505}
HÃ¥vard Molland9169c962014-08-14 14:42:37 +02001506
Adam Langleyfcf25832014-12-18 17:42:32 -08001507int SSL_enable_signed_cert_timestamps(SSL *ssl) {
1508 ssl->signed_cert_timestamps_enabled = 1;
1509 return 1;
1510}
HÃ¥vard Molland9169c962014-08-14 14:42:37 +02001511
Adam Langleyfcf25832014-12-18 17:42:32 -08001512void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx) {
1513 ctx->ocsp_stapling_enabled = 1;
1514}
David Benjamin6c7aed02014-08-27 16:42:38 -04001515
Adam Langleyfcf25832014-12-18 17:42:32 -08001516int SSL_enable_ocsp_stapling(SSL *ssl) {
1517 ssl->ocsp_stapling_enabled = 1;
1518 return 1;
1519}
David Benjamin6c7aed02014-08-27 16:42:38 -04001520
Adam Langleyfcf25832014-12-18 17:42:32 -08001521void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out,
1522 size_t *out_len) {
1523 SSL_SESSION *session = ssl->session;
Adam Langley3cb50e02014-08-26 14:00:31 -07001524
Adam Langleyfcf25832014-12-18 17:42:32 -08001525 *out_len = 0;
1526 *out = NULL;
1527 if (ssl->server || !session || !session->tlsext_signed_cert_timestamp_list) {
1528 return;
1529 }
HÃ¥vard Molland9169c962014-08-14 14:42:37 +02001530
Adam Langleyfcf25832014-12-18 17:42:32 -08001531 *out = session->tlsext_signed_cert_timestamp_list;
1532 *out_len = session->tlsext_signed_cert_timestamp_list_length;
1533}
David Benjamin6c7aed02014-08-27 16:42:38 -04001534
Adam Langleyfcf25832014-12-18 17:42:32 -08001535void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
1536 size_t *out_len) {
1537 SSL_SESSION *session = ssl->session;
1538
1539 *out_len = 0;
1540 *out = NULL;
1541 if (ssl->server || !session || !session->ocsp_response) {
1542 return;
1543 }
1544 *out = session->ocsp_response;
1545 *out_len = session->ocsp_response_length;
1546}
David Benjamin6c7aed02014-08-27 16:42:38 -04001547
Adam Langley95c29f32014-06-20 12:00:00 -07001548/* SSL_select_next_proto implements the standard protocol selection. It is
1549 * expected that this function is called from the callback set by
1550 * SSL_CTX_set_next_proto_select_cb.
1551 *
1552 * The protocol data is assumed to be a vector of 8-bit, length prefixed byte
1553 * strings. The length byte itself is not included in the length. A byte
1554 * string of length 0 is invalid. No byte string may be truncated.
1555 *
1556 * The current, but experimental algorithm for selecting the protocol is:
1557 *
1558 * 1) If the server doesn't support NPN then this is indicated to the
1559 * callback. In this case, the client application has to abort the connection
1560 * or have a default application level protocol.
1561 *
1562 * 2) If the server supports NPN, but advertises an empty list then the
1563 * client selects the first protcol in its list, but indicates via the
1564 * API that this fallback case was enacted.
1565 *
1566 * 3) Otherwise, the client finds the first protocol in the server's list
1567 * that it supports and selects this protocol. This is because it's
1568 * assumed that the server has better information about which protocol
1569 * a client should use.
1570 *
1571 * 4) If the client doesn't support any of the server's advertised
1572 * protocols, then this is treated the same as case 2.
1573 *
1574 * It returns either
1575 * OPENSSL_NPN_NEGOTIATED if a common protocol was found, or
1576 * OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
1577 */
Adam Langleyfcf25832014-12-18 17:42:32 -08001578int SSL_select_next_proto(uint8_t **out, uint8_t *outlen, const uint8_t *server,
1579 unsigned int server_len, const uint8_t *client,
1580 unsigned int client_len) {
1581 unsigned int i, j;
1582 const uint8_t *result;
1583 int status = OPENSSL_NPN_UNSUPPORTED;
Adam Langley95c29f32014-06-20 12:00:00 -07001584
Adam Langleyfcf25832014-12-18 17:42:32 -08001585 /* For each protocol in server preference order, see if we support it. */
1586 for (i = 0; i < server_len;) {
1587 for (j = 0; j < client_len;) {
1588 if (server[i] == client[j] &&
1589 memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) {
1590 /* We found a match */
1591 result = &server[i];
1592 status = OPENSSL_NPN_NEGOTIATED;
1593 goto found;
1594 }
1595 j += client[j];
1596 j++;
1597 }
1598 i += server[i];
1599 i++;
1600 }
Adam Langley95c29f32014-06-20 12:00:00 -07001601
Adam Langleyfcf25832014-12-18 17:42:32 -08001602 /* There's no overlap between our protocols and the server's list. */
1603 result = client;
1604 status = OPENSSL_NPN_NO_OVERLAP;
Adam Langley95c29f32014-06-20 12:00:00 -07001605
Adam Langleyfcf25832014-12-18 17:42:32 -08001606found:
1607 *out = (uint8_t *)result + 1;
1608 *outlen = result[0];
1609 return status;
1610}
Adam Langley95c29f32014-06-20 12:00:00 -07001611
Adam Langley95c29f32014-06-20 12:00:00 -07001612/* SSL_get0_next_proto_negotiated sets *data and *len to point to the client's
1613 * requested protocol for this connection and returns 0. If the client didn't
1614 * request any protocol, then *data is set to NULL.
1615 *
1616 * Note that the client can request any protocol it chooses. The value returned
1617 * from this function need not be a member of the list of supported protocols
Adam Langleyfcf25832014-12-18 17:42:32 -08001618 * provided by the callback. */
1619void SSL_get0_next_proto_negotiated(const SSL *s, const uint8_t **data,
1620 unsigned *len) {
1621 *data = s->next_proto_negotiated;
1622 if (!*data) {
1623 *len = 0;
1624 } else {
1625 *len = s->next_proto_negotiated_len;
1626 }
Adam Langley95c29f32014-06-20 12:00:00 -07001627}
1628
1629/* SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when a
1630 * TLS server needs a list of supported protocols for Next Protocol
1631 * Negotiation. The returned list must be in wire format. The list is returned
1632 * by setting |out| to point to it and |outlen| to its length. This memory will
1633 * not be modified, but one should assume that the SSL* keeps a reference to
1634 * it.
1635 *
Adam Langleyfcf25832014-12-18 17:42:32 -08001636 * The callback should return SSL_TLSEXT_ERR_OK if it wishes to advertise.
1637 * Otherwise, no such extension will be included in the ServerHello. */
1638void SSL_CTX_set_next_protos_advertised_cb(
1639 SSL_CTX *ctx,
1640 int (*cb)(SSL *ssl, const uint8_t **out, unsigned int *outlen, void *arg),
1641 void *arg) {
1642 ctx->next_protos_advertised_cb = cb;
1643 ctx->next_protos_advertised_cb_arg = arg;
1644}
Adam Langley95c29f32014-06-20 12:00:00 -07001645
1646/* SSL_CTX_set_next_proto_select_cb sets a callback that is called when a
1647 * client needs to select a protocol from the server's provided list. |out|
1648 * must be set to point to the selected protocol (which may be within |in|).
1649 * The length of the protocol name must be written into |outlen|. The server's
1650 * advertised protocols are provided in |in| and |inlen|. The callback can
1651 * assume that |in| is syntactically valid.
1652 *
1653 * The client must select a protocol. It is fatal to the connection if this
1654 * callback returns a value other than SSL_TLSEXT_ERR_OK.
1655 */
Adam Langleyfcf25832014-12-18 17:42:32 -08001656void SSL_CTX_set_next_proto_select_cb(
1657 SSL_CTX *ctx, int (*cb)(SSL *s, uint8_t **out, uint8_t *outlen,
1658 const uint8_t *in, unsigned int inlen, void *arg),
1659 void *arg) {
1660 ctx->next_proto_select_cb = cb;
1661 ctx->next_proto_select_cb_arg = arg;
1662}
Adam Langley95c29f32014-06-20 12:00:00 -07001663
Adam Langley95c29f32014-06-20 12:00:00 -07001664/* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
1665 * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
1666 * length-prefixed strings).
1667 *
1668 * Returns 0 on success. */
Adam Langleyfcf25832014-12-18 17:42:32 -08001669int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos,
1670 unsigned protos_len) {
1671 if (ctx->alpn_client_proto_list) {
1672 OPENSSL_free(ctx->alpn_client_proto_list);
1673 }
Adam Langley95c29f32014-06-20 12:00:00 -07001674
Adam Langleyfcf25832014-12-18 17:42:32 -08001675 ctx->alpn_client_proto_list = BUF_memdup(protos, protos_len);
1676 if (!ctx->alpn_client_proto_list) {
1677 return 1;
1678 }
1679 ctx->alpn_client_proto_list_len = protos_len;
Adam Langley95c29f32014-06-20 12:00:00 -07001680
Adam Langleyfcf25832014-12-18 17:42:32 -08001681 return 0;
1682}
Adam Langley95c29f32014-06-20 12:00:00 -07001683
1684/* SSL_set_alpn_protos sets the ALPN protocol list on |ssl| to |protos|.
1685 * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
1686 * length-prefixed strings).
1687 *
1688 * Returns 0 on success. */
Adam Langleyfcf25832014-12-18 17:42:32 -08001689int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) {
1690 if (ssl->alpn_client_proto_list) {
1691 OPENSSL_free(ssl->alpn_client_proto_list);
1692 }
Adam Langley95c29f32014-06-20 12:00:00 -07001693
Adam Langleyfcf25832014-12-18 17:42:32 -08001694 ssl->alpn_client_proto_list = BUF_memdup(protos, protos_len);
1695 if (!ssl->alpn_client_proto_list) {
1696 return 1;
1697 }
1698 ssl->alpn_client_proto_list_len = protos_len;
Adam Langley95c29f32014-06-20 12:00:00 -07001699
Adam Langleyfcf25832014-12-18 17:42:32 -08001700 return 0;
1701}
Adam Langley95c29f32014-06-20 12:00:00 -07001702
1703/* SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called
1704 * during ClientHello processing in order to select an ALPN protocol from the
1705 * client's list of offered protocols. */
Adam Langleyfcf25832014-12-18 17:42:32 -08001706void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
1707 int (*cb)(SSL *ssl, const uint8_t **out,
1708 uint8_t *outlen, const uint8_t *in,
1709 unsigned int inlen, void *arg),
1710 void *arg) {
1711 ctx->alpn_select_cb = cb;
1712 ctx->alpn_select_cb_arg = arg;
1713}
Adam Langley95c29f32014-06-20 12:00:00 -07001714
1715/* SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|.
1716 * On return it sets |*data| to point to |*len| bytes of protocol name (not
1717 * including the leading length-prefix byte). If the server didn't respond with
1718 * a negotiated protocol then |*len| will be zero. */
Adam Langleyfcf25832014-12-18 17:42:32 -08001719void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **data,
1720 unsigned *len) {
1721 *data = NULL;
1722 if (ssl->s3) {
1723 *data = ssl->s3->alpn_selected;
1724 }
1725 if (*data == NULL) {
1726 *len = 0;
1727 } else {
1728 *len = ssl->s3->alpn_selected_len;
1729 }
1730}
Adam Langley95c29f32014-06-20 12:00:00 -07001731
Adam Langleyfcf25832014-12-18 17:42:32 -08001732int SSL_export_keying_material(SSL *s, uint8_t *out, size_t olen,
1733 const char *label, size_t llen, const uint8_t *p,
1734 size_t plen, int use_context) {
1735 if (s->version < TLS1_VERSION) {
1736 return -1;
1737 }
Adam Langley95c29f32014-06-20 12:00:00 -07001738
Adam Langleyfcf25832014-12-18 17:42:32 -08001739 return s->enc_method->export_keying_material(s, out, olen, label, llen, p,
1740 plen, use_context);
1741}
Adam Langley95c29f32014-06-20 12:00:00 -07001742
Adam Langleyfcf25832014-12-18 17:42:32 -08001743static uint32_t ssl_session_hash(const SSL_SESSION *a) {
1744 uint32_t hash =
1745 ((uint32_t)a->session_id[0]) ||
1746 ((uint32_t)a->session_id[1] << 8) ||
1747 ((uint32_t)a->session_id[2] << 16) ||
1748 ((uint32_t)a->session_id[3] << 24);
Adam Langley95c29f32014-06-20 12:00:00 -07001749
Adam Langleyfcf25832014-12-18 17:42:32 -08001750 return hash;
1751}
Adam Langley95c29f32014-06-20 12:00:00 -07001752
1753/* NB: If this function (or indeed the hash function which uses a sort of
1754 * coarser function than this one) is changed, ensure
1755 * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
1756 * able to construct an SSL_SESSION that will collide with any existing session
1757 * with a matching session ID. */
Adam Langleyfcf25832014-12-18 17:42:32 -08001758static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) {
1759 if (a->ssl_version != b->ssl_version) {
1760 return 1;
1761 }
Adam Langley95c29f32014-06-20 12:00:00 -07001762
Adam Langleyfcf25832014-12-18 17:42:32 -08001763 if (a->session_id_length != b->session_id_length) {
1764 return 1;
1765 }
Adam Langley95c29f32014-06-20 12:00:00 -07001766
Adam Langleyfcf25832014-12-18 17:42:32 -08001767 return memcmp(a->session_id, b->session_id, a->session_id_length);
1768}
Adam Langley95c29f32014-06-20 12:00:00 -07001769
Adam Langleyfcf25832014-12-18 17:42:32 -08001770SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) {
1771 SSL_CTX *ret = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001772
Adam Langleyfcf25832014-12-18 17:42:32 -08001773 if (meth == NULL) {
1774 OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_NULL_SSL_METHOD_PASSED);
1775 return NULL;
1776 }
Adam Langley95c29f32014-06-20 12:00:00 -07001777
Adam Langleyfcf25832014-12-18 17:42:32 -08001778 if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) {
1779 OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
1780 goto err;
1781 }
Adam Langley95c29f32014-06-20 12:00:00 -07001782
Adam Langleyfcf25832014-12-18 17:42:32 -08001783 ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
1784 if (ret == NULL) {
1785 goto err;
1786 }
Adam Langley95c29f32014-06-20 12:00:00 -07001787
Adam Langleyfcf25832014-12-18 17:42:32 -08001788 memset(ret, 0, sizeof(SSL_CTX));
Adam Langley95c29f32014-06-20 12:00:00 -07001789
Adam Langleyfcf25832014-12-18 17:42:32 -08001790 ret->method = meth->method;
Adam Langley95c29f32014-06-20 12:00:00 -07001791
Adam Langleyfcf25832014-12-18 17:42:32 -08001792 ret->cert_store = NULL;
1793 ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
1794 ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
1795 ret->session_cache_head = NULL;
1796 ret->session_cache_tail = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001797
Adam Langleyfcf25832014-12-18 17:42:32 -08001798 /* We take the system default */
1799 ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
Adam Langley95c29f32014-06-20 12:00:00 -07001800
Adam Langleyfcf25832014-12-18 17:42:32 -08001801 ret->new_session_cb = 0;
1802 ret->remove_session_cb = 0;
1803 ret->get_session_cb = 0;
1804 ret->generate_session_id = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001805
Adam Langleyfcf25832014-12-18 17:42:32 -08001806 memset((char *)&ret->stats, 0, sizeof(ret->stats));
Adam Langley95c29f32014-06-20 12:00:00 -07001807
Adam Langleyfcf25832014-12-18 17:42:32 -08001808 ret->references = 1;
1809 ret->quiet_shutdown = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001810
Adam Langleyfcf25832014-12-18 17:42:32 -08001811 ret->info_callback = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001812
Adam Langleyfcf25832014-12-18 17:42:32 -08001813 ret->app_verify_callback = 0;
1814 ret->app_verify_arg = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001815
Adam Langleyfcf25832014-12-18 17:42:32 -08001816 ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
1817 ret->read_ahead = 0;
1818 ret->msg_callback = 0;
1819 ret->msg_callback_arg = NULL;
1820 ret->verify_mode = SSL_VERIFY_NONE;
1821 ret->sid_ctx_length = 0;
1822 ret->default_verify_callback = NULL;
1823 ret->cert = ssl_cert_new();
1824 if (ret->cert == NULL) {
1825 goto err;
1826 }
Adam Langley95c29f32014-06-20 12:00:00 -07001827
Adam Langleyfcf25832014-12-18 17:42:32 -08001828 ret->default_passwd_callback = 0;
1829 ret->default_passwd_callback_userdata = NULL;
1830 ret->client_cert_cb = 0;
1831 ret->app_gen_cookie_cb = 0;
1832 ret->app_verify_cookie_cb = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001833
Adam Langleyfcf25832014-12-18 17:42:32 -08001834 ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
1835 if (ret->sessions == NULL) {
1836 goto err;
1837 }
1838 ret->cert_store = X509_STORE_new();
1839 if (ret->cert_store == NULL) {
1840 goto err;
1841 }
Adam Langley95c29f32014-06-20 12:00:00 -07001842
Adam Langleyfcf25832014-12-18 17:42:32 -08001843 ssl_create_cipher_list(ret->method, &ret->cipher_list,
1844 &ret->cipher_list_by_id, SSL_DEFAULT_CIPHER_LIST,
1845 ret->cert);
1846 if (ret->cipher_list == NULL ||
1847 sk_SSL_CIPHER_num(ret->cipher_list->ciphers) <= 0) {
1848 OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_LIBRARY_HAS_NO_CIPHERS);
1849 goto err2;
1850 }
Adam Langley95c29f32014-06-20 12:00:00 -07001851
Adam Langleyfcf25832014-12-18 17:42:32 -08001852 ret->param = X509_VERIFY_PARAM_new();
1853 if (!ret->param) {
1854 goto err;
1855 }
Adam Langley95c29f32014-06-20 12:00:00 -07001856
Adam Langleyfcf25832014-12-18 17:42:32 -08001857 ret->client_CA = sk_X509_NAME_new_null();
1858 if (ret->client_CA == NULL) {
1859 goto err;
1860 }
Adam Langley95c29f32014-06-20 12:00:00 -07001861
Adam Langleyfcf25832014-12-18 17:42:32 -08001862 CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -07001863
Adam Langleyfcf25832014-12-18 17:42:32 -08001864 ret->extra_certs = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001865
Adam Langleyfcf25832014-12-18 17:42:32 -08001866 ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
David Benjamin422d3a42014-08-20 11:09:03 -04001867
Adam Langleyfcf25832014-12-18 17:42:32 -08001868 ret->tlsext_servername_callback = 0;
1869 ret->tlsext_servername_arg = NULL;
1870 /* Setup RFC4507 ticket keys */
1871 if (!RAND_bytes(ret->tlsext_tick_key_name, 16) ||
1872 !RAND_bytes(ret->tlsext_tick_hmac_key, 16) ||
1873 !RAND_bytes(ret->tlsext_tick_aes_key, 16)) {
1874 ret->options |= SSL_OP_NO_TICKET;
1875 }
Adam Langley95c29f32014-06-20 12:00:00 -07001876
Adam Langleyfcf25832014-12-18 17:42:32 -08001877 ret->tlsext_status_cb = 0;
1878 ret->tlsext_status_arg = NULL;
David Benjamin82c9e902014-12-12 15:55:27 -05001879
Adam Langleyfcf25832014-12-18 17:42:32 -08001880 ret->next_protos_advertised_cb = 0;
1881 ret->next_proto_select_cb = 0;
1882 ret->psk_identity_hint = NULL;
1883 ret->psk_client_callback = NULL;
1884 ret->psk_server_callback = NULL;
1885
1886 /* Default is to connect to non-RI servers. When RI is more widely deployed
1887 * might change this. */
1888 ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
1889
1890 /* Lock the SSL_CTX to the specified version, for compatibility with legacy
1891 * uses of SSL_METHOD. */
1892 if (meth->version != 0) {
1893 SSL_CTX_set_max_version(ret, meth->version);
1894 SSL_CTX_set_min_version(ret, meth->version);
1895 }
1896
1897 return ret;
1898
Adam Langley95c29f32014-06-20 12:00:00 -07001899err:
Adam Langleyfcf25832014-12-18 17:42:32 -08001900 OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, ERR_R_MALLOC_FAILURE);
Adam Langley95c29f32014-06-20 12:00:00 -07001901err2:
Adam Langleyfcf25832014-12-18 17:42:32 -08001902 if (ret != NULL) {
1903 SSL_CTX_free(ret);
1904 }
1905 return NULL;
1906}
Adam Langley95c29f32014-06-20 12:00:00 -07001907
Adam Langleyfcf25832014-12-18 17:42:32 -08001908void SSL_CTX_free(SSL_CTX *a) {
1909 int i;
Adam Langley95c29f32014-06-20 12:00:00 -07001910
Adam Langleyfcf25832014-12-18 17:42:32 -08001911 if (a == NULL) {
1912 return;
1913 }
Adam Langley95c29f32014-06-20 12:00:00 -07001914
Adam Langleyfcf25832014-12-18 17:42:32 -08001915 i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_SSL_CTX);
1916 if (i > 0) {
1917 return;
1918 }
Adam Langley95c29f32014-06-20 12:00:00 -07001919
Adam Langleyfcf25832014-12-18 17:42:32 -08001920 if (a->param) {
1921 X509_VERIFY_PARAM_free(a->param);
1922 }
Adam Langley95c29f32014-06-20 12:00:00 -07001923
Adam Langleyfcf25832014-12-18 17:42:32 -08001924 /* Free internal session cache. However: the remove_cb() may reference the
1925 * ex_data of SSL_CTX, thus the ex_data store can only be removed after the
1926 * sessions were flushed. As the ex_data handling routines might also touch
1927 * the session cache, the most secure solution seems to be: empty (flush) the
1928 * cache, then free ex_data, then finally free the cache. (See ticket
1929 * [openssl.org #212].) */
1930 if (a->sessions != NULL) {
1931 SSL_CTX_flush_sessions(a, 0);
1932 }
Adam Langley95c29f32014-06-20 12:00:00 -07001933
Adam Langleyfcf25832014-12-18 17:42:32 -08001934 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data);
Adam Langley95c29f32014-06-20 12:00:00 -07001935
Adam Langleyfcf25832014-12-18 17:42:32 -08001936 if (a->sessions != NULL) {
1937 lh_SSL_SESSION_free(a->sessions);
1938 }
1939 if (a->cert_store != NULL) {
1940 X509_STORE_free(a->cert_store);
1941 }
1942 if (a->cipher_list != NULL) {
1943 ssl_cipher_preference_list_free(a->cipher_list);
1944 }
1945 if (a->cipher_list_by_id != NULL) {
1946 sk_SSL_CIPHER_free(a->cipher_list_by_id);
1947 }
1948 if (a->cipher_list_tls11 != NULL) {
1949 ssl_cipher_preference_list_free(a->cipher_list_tls11);
1950 }
1951 if (a->cert != NULL) {
1952 ssl_cert_free(a->cert);
1953 }
1954 if (a->client_CA != NULL) {
1955 sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free);
1956 }
1957 if (a->extra_certs != NULL) {
1958 sk_X509_pop_free(a->extra_certs, X509_free);
1959 }
1960 if (a->srtp_profiles) {
1961 sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
1962 }
1963 if (a->psk_identity_hint) {
1964 OPENSSL_free(a->psk_identity_hint);
1965 }
1966 if (a->tlsext_ecpointformatlist) {
1967 OPENSSL_free(a->tlsext_ecpointformatlist);
1968 }
1969 if (a->tlsext_ellipticcurvelist) {
1970 OPENSSL_free(a->tlsext_ellipticcurvelist);
1971 }
1972 if (a->alpn_client_proto_list != NULL) {
1973 OPENSSL_free(a->alpn_client_proto_list);
1974 }
1975 if (a->tlsext_channel_id_private) {
1976 EVP_PKEY_free(a->tlsext_channel_id_private);
1977 }
1978 if (a->keylog_bio) {
1979 BIO_free(a->keylog_bio);
1980 }
Adam Langley95c29f32014-06-20 12:00:00 -07001981
Adam Langleyfcf25832014-12-18 17:42:32 -08001982 OPENSSL_free(a);
1983}
Adam Langley95c29f32014-06-20 12:00:00 -07001984
Adam Langleyfcf25832014-12-18 17:42:32 -08001985void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) {
1986 ctx->default_passwd_callback = cb;
1987}
Adam Langley95c29f32014-06-20 12:00:00 -07001988
Adam Langleyfcf25832014-12-18 17:42:32 -08001989void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) {
1990 ctx->default_passwd_callback_userdata = u;
1991}
Adam Langley95c29f32014-06-20 12:00:00 -07001992
Adam Langleyfcf25832014-12-18 17:42:32 -08001993void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
1994 int (*cb)(X509_STORE_CTX *, void *),
1995 void *arg) {
1996 ctx->app_verify_callback = cb;
1997 ctx->app_verify_arg = arg;
1998}
Adam Langley95c29f32014-06-20 12:00:00 -07001999
Adam Langleyfcf25832014-12-18 17:42:32 -08002000void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
2001 int (*cb)(int, X509_STORE_CTX *)) {
2002 ctx->verify_mode = mode;
2003 ctx->default_verify_callback = cb;
2004}
Adam Langley95c29f32014-06-20 12:00:00 -07002005
Adam Langleyfcf25832014-12-18 17:42:32 -08002006void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) {
2007 X509_VERIFY_PARAM_set_depth(ctx->param, depth);
2008}
Adam Langley1258b6a2014-06-20 12:00:00 -07002009
Adam Langleyfcf25832014-12-18 17:42:32 -08002010void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb)(SSL *ssl, void *arg),
2011 void *arg) {
2012 ssl_cert_set_cert_cb(c->cert, cb, arg);
2013}
David Benjamin859ec3c2014-09-02 16:29:36 -04002014
Adam Langleyfcf25832014-12-18 17:42:32 -08002015void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg), void *arg) {
2016 ssl_cert_set_cert_cb(s->cert, cb, arg);
2017}
Adam Langley95c29f32014-06-20 12:00:00 -07002018
Adam Langleyfcf25832014-12-18 17:42:32 -08002019static int ssl_has_key(SSL *s, size_t idx) {
2020 CERT_PKEY *cpk = &s->cert->pkeys[idx];
2021 return cpk->x509 && cpk->privatekey;
2022}
David Benjamin033e5f42014-11-13 18:47:41 -05002023
David Benjaminf31e6812014-11-13 18:05:55 -05002024void ssl_get_compatible_server_ciphers(SSL *s, unsigned long *out_mask_k,
Adam Langleyfcf25832014-12-18 17:42:32 -08002025 unsigned long *out_mask_a) {
2026 CERT *c = s->cert;
2027 int rsa_enc, rsa_sign, dh_tmp;
2028 unsigned long mask_k, mask_a;
2029 int have_ecc_cert, ecdsa_ok;
2030 int have_ecdh_tmp;
2031 X509 *x;
Adam Langley95c29f32014-06-20 12:00:00 -07002032
Adam Langleyfcf25832014-12-18 17:42:32 -08002033 if (c == NULL) {
2034 /* TODO(davidben): Is this codepath possible? */
2035 *out_mask_k = 0;
2036 *out_mask_a = 0;
2037 return;
2038 }
Adam Langley95c29f32014-06-20 12:00:00 -07002039
Adam Langleyfcf25832014-12-18 17:42:32 -08002040 dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
Adam Langley95c29f32014-06-20 12:00:00 -07002041
Adam Langleyfcf25832014-12-18 17:42:32 -08002042 have_ecdh_tmp = (c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto);
2043 rsa_enc = ssl_has_key(s, SSL_PKEY_RSA_ENC);
2044 rsa_sign = ssl_has_key(s, SSL_PKEY_RSA_SIGN);
2045 have_ecc_cert = ssl_has_key(s, SSL_PKEY_ECC);
2046 mask_k = 0;
2047 mask_a = 0;
David Benjaminf31e6812014-11-13 18:05:55 -05002048
Adam Langleyfcf25832014-12-18 17:42:32 -08002049 if (rsa_enc) {
2050 mask_k |= SSL_kRSA;
2051 }
2052 if (dh_tmp) {
2053 mask_k |= SSL_kEDH;
2054 }
2055 if (rsa_enc || rsa_sign) {
2056 mask_a |= SSL_aRSA;
2057 }
Adam Langley95c29f32014-06-20 12:00:00 -07002058
Adam Langleyfcf25832014-12-18 17:42:32 -08002059 mask_a |= SSL_aNULL;
Adam Langley95c29f32014-06-20 12:00:00 -07002060
Adam Langleyfcf25832014-12-18 17:42:32 -08002061 /* An ECC certificate may be usable for ECDSA cipher suites depending on the
2062 * key usage extension and on the client's curve preferences. */
2063 if (have_ecc_cert) {
2064 x = c->pkeys[SSL_PKEY_ECC].x509;
2065 /* This call populates extension flags (ex_flags). */
2066 X509_check_purpose(x, -1, 0);
2067 ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE)
2068 ? (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)
2069 : 1;
2070 if (!tls1_check_ec_cert(s, x)) {
2071 ecdsa_ok = 0;
2072 }
2073 if (ecdsa_ok) {
2074 mask_a |= SSL_aECDSA;
2075 }
2076 }
Adam Langley95c29f32014-06-20 12:00:00 -07002077
Adam Langleyfcf25832014-12-18 17:42:32 -08002078 /* If we are considering an ECC cipher suite that uses an ephemeral EC
2079 * key, check it. */
2080 if (have_ecdh_tmp && tls1_check_ec_tmp_key(s)) {
2081 mask_k |= SSL_kEECDH;
2082 }
Adam Langley95c29f32014-06-20 12:00:00 -07002083
Adam Langleyfcf25832014-12-18 17:42:32 -08002084 /* PSK requires a server callback. */
2085 if (s->psk_server_callback != NULL) {
2086 mask_k |= SSL_kPSK;
2087 mask_a |= SSL_aPSK;
2088 }
Adam Langley95c29f32014-06-20 12:00:00 -07002089
Adam Langleyfcf25832014-12-18 17:42:32 -08002090 *out_mask_k = mask_k;
2091 *out_mask_a = mask_a;
2092}
Adam Langley95c29f32014-06-20 12:00:00 -07002093
2094/* This handy macro borrowed from crypto/x509v3/v3_purp.c */
2095#define ku_reject(x, usage) \
Adam Langleyfcf25832014-12-18 17:42:32 -08002096 (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
Adam Langley95c29f32014-06-20 12:00:00 -07002097
Adam Langleyfcf25832014-12-18 17:42:32 -08002098int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) {
2099 unsigned long alg_a;
2100 int signature_nid = 0, md_nid = 0, pk_nid = 0;
2101 const SSL_CIPHER *cs = s->s3->tmp.new_cipher;
Adam Langley95c29f32014-06-20 12:00:00 -07002102
Adam Langleyfcf25832014-12-18 17:42:32 -08002103 alg_a = cs->algorithm_auth;
Adam Langley95c29f32014-06-20 12:00:00 -07002104
Adam Langleyfcf25832014-12-18 17:42:32 -08002105 /* This call populates the ex_flags field correctly */
2106 X509_check_purpose(x, -1, 0);
2107 if (x->sig_alg && x->sig_alg->algorithm) {
2108 signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
2109 OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
2110 }
2111 if (alg_a & SSL_aECDSA) {
2112 /* key usage, if present, must allow signing */
2113 if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) {
2114 OPENSSL_PUT_ERROR(SSL, ssl_check_srvr_ecc_cert_and_alg,
2115 SSL_R_ECC_CERT_NOT_FOR_SIGNING);
2116 return 0;
2117 }
2118 }
Adam Langley95c29f32014-06-20 12:00:00 -07002119
Adam Langleyfcf25832014-12-18 17:42:32 -08002120 return 1; /* all checks are ok */
2121}
Adam Langley95c29f32014-06-20 12:00:00 -07002122
Adam Langleyfcf25832014-12-18 17:42:32 -08002123static int ssl_get_server_cert_index(const SSL *s) {
2124 int idx;
2125 idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
2126 if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509) {
2127 idx = SSL_PKEY_RSA_SIGN;
2128 }
2129 if (idx == -1) {
2130 OPENSSL_PUT_ERROR(SSL, ssl_get_server_cert_index, ERR_R_INTERNAL_ERROR);
2131 }
2132 return idx;
2133}
Adam Langley95c29f32014-06-20 12:00:00 -07002134
Adam Langleyfcf25832014-12-18 17:42:32 -08002135CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) {
2136 int i = ssl_get_server_cert_index(s);
Adam Langley95c29f32014-06-20 12:00:00 -07002137
Adam Langleyfcf25832014-12-18 17:42:32 -08002138 /* This may or may not be an error. */
2139 if (i < 0) {
2140 return NULL;
2141 }
Adam Langley95c29f32014-06-20 12:00:00 -07002142
Adam Langleyfcf25832014-12-18 17:42:32 -08002143 /* May be NULL. */
2144 return &s->cert->pkeys[i];
2145}
Adam Langley95c29f32014-06-20 12:00:00 -07002146
Adam Langleyfcf25832014-12-18 17:42:32 -08002147EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher) {
2148 unsigned long alg_a;
2149 CERT *c;
2150 int idx = -1;
Adam Langley95c29f32014-06-20 12:00:00 -07002151
Adam Langleyfcf25832014-12-18 17:42:32 -08002152 alg_a = cipher->algorithm_auth;
2153 c = s->cert;
Adam Langley95c29f32014-06-20 12:00:00 -07002154
Adam Langleyfcf25832014-12-18 17:42:32 -08002155 if (alg_a & SSL_aRSA) {
2156 if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) {
2157 idx = SSL_PKEY_RSA_SIGN;
2158 } else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) {
2159 idx = SSL_PKEY_RSA_ENC;
2160 }
2161 } else if ((alg_a & SSL_aECDSA) &&
2162 (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) {
2163 idx = SSL_PKEY_ECC;
2164 }
Adam Langley95c29f32014-06-20 12:00:00 -07002165
Adam Langleyfcf25832014-12-18 17:42:32 -08002166 if (idx == -1) {
2167 OPENSSL_PUT_ERROR(SSL, ssl_get_sign_pkey, ERR_R_INTERNAL_ERROR);
2168 return NULL;
2169 }
Adam Langley95c29f32014-06-20 12:00:00 -07002170
Adam Langleyfcf25832014-12-18 17:42:32 -08002171 return c->pkeys[idx].privatekey;
2172}
Adam Langley95c29f32014-06-20 12:00:00 -07002173
Adam Langleyfcf25832014-12-18 17:42:32 -08002174void ssl_update_cache(SSL *s, int mode) {
2175 int i;
Adam Langley95c29f32014-06-20 12:00:00 -07002176
Adam Langleyfcf25832014-12-18 17:42:32 -08002177 /* If the session_id_length is 0, we are not supposed to cache it, and it
2178 * would be rather hard to do anyway :-) */
2179 if (s->session->session_id_length == 0) {
2180 return;
2181 }
Adam Langley95c29f32014-06-20 12:00:00 -07002182
Adam Langleyfcf25832014-12-18 17:42:32 -08002183 i = s->initial_ctx->session_cache_mode;
2184 if ((i & mode) && !s->hit &&
2185 ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) ||
2186 SSL_CTX_add_session(s->initial_ctx, s->session)) &&
2187 s->initial_ctx->new_session_cb != NULL) {
2188 CRYPTO_add(&s->session->references, 1, CRYPTO_LOCK_SSL_SESSION);
2189 if (!s->initial_ctx->new_session_cb(s, s->session)) {
2190 SSL_SESSION_free(s->session);
2191 }
2192 }
Adam Langley95c29f32014-06-20 12:00:00 -07002193
Adam Langleyfcf25832014-12-18 17:42:32 -08002194 /* auto flush every 255 connections */
2195 if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && ((i & mode) == mode)) {
2196 if ((((mode & SSL_SESS_CACHE_CLIENT)
2197 ? s->initial_ctx->stats.sess_connect_good
2198 : s->initial_ctx->stats.sess_accept_good) &
2199 0xff) == 0xff) {
2200 SSL_CTX_flush_sessions(s->initial_ctx, (unsigned long)time(NULL));
2201 }
2202 }
2203}
Adam Langley95c29f32014-06-20 12:00:00 -07002204
Adam Langleyfcf25832014-12-18 17:42:32 -08002205int SSL_get_error(const SSL *s, int i) {
2206 int reason;
2207 unsigned long l;
2208 BIO *bio;
Adam Langley95c29f32014-06-20 12:00:00 -07002209
Adam Langleyfcf25832014-12-18 17:42:32 -08002210 if (i > 0) {
2211 return SSL_ERROR_NONE;
2212 }
Adam Langley95c29f32014-06-20 12:00:00 -07002213
Adam Langleyfcf25832014-12-18 17:42:32 -08002214 /* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
2215 * where we do encode the error */
2216 l = ERR_peek_error();
2217 if (l != 0) {
2218 if (ERR_GET_LIB(l) == ERR_LIB_SYS) {
2219 return SSL_ERROR_SYSCALL;
2220 }
2221 return SSL_ERROR_SSL;
2222 }
Adam Langley95c29f32014-06-20 12:00:00 -07002223
Adam Langleyfcf25832014-12-18 17:42:32 -08002224 if (i == 0 && (s->shutdown & SSL_RECEIVED_SHUTDOWN) &&
2225 (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) {
2226 return SSL_ERROR_ZERO_RETURN;
2227 }
Adam Langleyb2ce0582014-06-20 12:00:00 -07002228
Adam Langleyfcf25832014-12-18 17:42:32 -08002229 assert(i < 0);
Adam Langleydc9b1412014-06-20 12:00:00 -07002230
Adam Langleyfcf25832014-12-18 17:42:32 -08002231 if (SSL_want_session(s)) {
2232 return SSL_ERROR_PENDING_SESSION;
2233 }
Adam Langley95c29f32014-06-20 12:00:00 -07002234
Adam Langleyfcf25832014-12-18 17:42:32 -08002235 if (SSL_want_certificate(s)) {
2236 return SSL_ERROR_PENDING_CERTIFICATE;
2237 }
Adam Langley95c29f32014-06-20 12:00:00 -07002238
Adam Langleyfcf25832014-12-18 17:42:32 -08002239 if (SSL_want_read(s)) {
2240 bio = SSL_get_rbio(s);
2241 if (BIO_should_read(bio)) {
2242 return SSL_ERROR_WANT_READ;
2243 }
Adam Langley95c29f32014-06-20 12:00:00 -07002244
Adam Langleyfcf25832014-12-18 17:42:32 -08002245 if (BIO_should_write(bio)) {
2246 /* This one doesn't make too much sense ... We never try to write to the
2247 * rbio, and an application program where rbio and wbio are separate
2248 * couldn't even know what it should wait for. However if we ever set
2249 * s->rwstate incorrectly (so that we have SSL_want_read(s) instead of
2250 * SSL_want_write(s)) and rbio and wbio *are* the same, this test works
2251 * around that bug; so it might be safer to keep it. */
2252 return SSL_ERROR_WANT_WRITE;
2253 }
Adam Langley95c29f32014-06-20 12:00:00 -07002254
Adam Langleyfcf25832014-12-18 17:42:32 -08002255 if (BIO_should_io_special(bio)) {
2256 reason = BIO_get_retry_reason(bio);
2257 if (reason == BIO_RR_CONNECT) {
2258 return SSL_ERROR_WANT_CONNECT;
2259 }
Adam Langley95c29f32014-06-20 12:00:00 -07002260
Adam Langleyfcf25832014-12-18 17:42:32 -08002261 if (reason == BIO_RR_ACCEPT) {
2262 return SSL_ERROR_WANT_ACCEPT;
2263 }
Adam Langley95c29f32014-06-20 12:00:00 -07002264
Adam Langleyfcf25832014-12-18 17:42:32 -08002265 return SSL_ERROR_SYSCALL; /* unknown */
2266 }
2267 }
Adam Langley95c29f32014-06-20 12:00:00 -07002268
Adam Langleyfcf25832014-12-18 17:42:32 -08002269 if (SSL_want_write(s)) {
2270 bio = SSL_get_wbio(s);
2271 if (BIO_should_write(bio)) {
2272 return SSL_ERROR_WANT_WRITE;
2273 }
Adam Langley95c29f32014-06-20 12:00:00 -07002274
Adam Langleyfcf25832014-12-18 17:42:32 -08002275 if (BIO_should_read(bio)) {
2276 /* See above (SSL_want_read(s) with BIO_should_write(bio)) */
2277 return SSL_ERROR_WANT_READ;
2278 }
Adam Langley95c29f32014-06-20 12:00:00 -07002279
Adam Langleyfcf25832014-12-18 17:42:32 -08002280 if (BIO_should_io_special(bio)) {
2281 reason = BIO_get_retry_reason(bio);
2282 if (reason == BIO_RR_CONNECT) {
2283 return SSL_ERROR_WANT_CONNECT;
2284 }
Adam Langley95c29f32014-06-20 12:00:00 -07002285
Adam Langleyfcf25832014-12-18 17:42:32 -08002286 if (reason == BIO_RR_ACCEPT) {
2287 return SSL_ERROR_WANT_ACCEPT;
2288 }
Adam Langley95c29f32014-06-20 12:00:00 -07002289
Adam Langleyfcf25832014-12-18 17:42:32 -08002290 return SSL_ERROR_SYSCALL;
2291 }
2292 }
Adam Langley95c29f32014-06-20 12:00:00 -07002293
Adam Langleyfcf25832014-12-18 17:42:32 -08002294 if (SSL_want_x509_lookup(s)) {
2295 return SSL_ERROR_WANT_X509_LOOKUP;
2296 }
Adam Langley95c29f32014-06-20 12:00:00 -07002297
Adam Langleyfcf25832014-12-18 17:42:32 -08002298 if (SSL_want_channel_id_lookup(s)) {
2299 return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP;
2300 }
Adam Langley0f4746e2014-08-13 12:26:32 -07002301
Adam Langleyfcf25832014-12-18 17:42:32 -08002302 return SSL_ERROR_SYSCALL;
2303}
Adam Langley0f4746e2014-08-13 12:26:32 -07002304
Adam Langleyfcf25832014-12-18 17:42:32 -08002305int SSL_do_handshake(SSL *s) {
2306 int ret = 1;
Adam Langley95c29f32014-06-20 12:00:00 -07002307
Adam Langleyfcf25832014-12-18 17:42:32 -08002308 if (s->handshake_func == NULL) {
2309 OPENSSL_PUT_ERROR(SSL, SSL_do_handshake, SSL_R_CONNECTION_TYPE_NOT_SET);
2310 return -1;
2311 }
Adam Langley95c29f32014-06-20 12:00:00 -07002312
Adam Langleyfcf25832014-12-18 17:42:32 -08002313 s->method->ssl_renegotiate_check(s);
Adam Langley95c29f32014-06-20 12:00:00 -07002314
Adam Langleyfcf25832014-12-18 17:42:32 -08002315 if (SSL_in_init(s)) {
2316 ret = s->handshake_func(s);
2317 }
2318 return ret;
2319}
Adam Langley95c29f32014-06-20 12:00:00 -07002320
Adam Langleyfcf25832014-12-18 17:42:32 -08002321void SSL_set_accept_state(SSL *s) {
2322 s->server = 1;
2323 s->shutdown = 0;
2324 s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE;
2325 s->handshake_func = s->method->ssl_accept;
2326 /* clear the current cipher */
2327 ssl_clear_cipher_ctx(s);
2328 ssl_clear_hash_ctx(&s->read_hash);
2329 ssl_clear_hash_ctx(&s->write_hash);
2330}
Adam Langley95c29f32014-06-20 12:00:00 -07002331
Adam Langleyfcf25832014-12-18 17:42:32 -08002332void SSL_set_connect_state(SSL *s) {
2333 s->server = 0;
2334 s->shutdown = 0;
2335 s->state = SSL_ST_CONNECT | SSL_ST_BEFORE;
2336 s->handshake_func = s->method->ssl_connect;
2337 /* clear the current cipher */
2338 ssl_clear_cipher_ctx(s);
2339 ssl_clear_hash_ctx(&s->read_hash);
2340 ssl_clear_hash_ctx(&s->write_hash);
2341}
Adam Langley95c29f32014-06-20 12:00:00 -07002342
Adam Langleyfcf25832014-12-18 17:42:32 -08002343int ssl_undefined_function(SSL *s) {
2344 OPENSSL_PUT_ERROR(SSL, ssl_undefined_function,
2345 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
2346 return 0;
2347}
Adam Langley95c29f32014-06-20 12:00:00 -07002348
Adam Langleyfcf25832014-12-18 17:42:32 -08002349int ssl_undefined_void_function(void) {
2350 OPENSSL_PUT_ERROR(SSL, ssl_undefined_void_function,
2351 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
2352 return 0;
2353}
Adam Langley95c29f32014-06-20 12:00:00 -07002354
Adam Langleyfcf25832014-12-18 17:42:32 -08002355int ssl_undefined_const_function(const SSL *s) {
2356 OPENSSL_PUT_ERROR(SSL, ssl_undefined_const_function,
2357 ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
2358 return 0;
2359}
Adam Langley95c29f32014-06-20 12:00:00 -07002360
Adam Langleyfcf25832014-12-18 17:42:32 -08002361static const char *ssl_get_version(int version) {
2362 switch (version) {
2363 case TLS1_2_VERSION:
2364 return "TLSv1.2";
Adam Langley95c29f32014-06-20 12:00:00 -07002365
Adam Langleyfcf25832014-12-18 17:42:32 -08002366 case TLS1_1_VERSION:
2367 return "TLSv1.1";
Adam Langley95c29f32014-06-20 12:00:00 -07002368
Adam Langleyfcf25832014-12-18 17:42:32 -08002369 case TLS1_VERSION:
2370 return "TLSv1";
Adam Langley95c29f32014-06-20 12:00:00 -07002371
Adam Langleyfcf25832014-12-18 17:42:32 -08002372 case SSL3_VERSION:
2373 return "SSLv3";
Adam Langley95c29f32014-06-20 12:00:00 -07002374
Adam Langleyfcf25832014-12-18 17:42:32 -08002375 default:
2376 return "unknown";
2377 }
2378}
Adam Langley95c29f32014-06-20 12:00:00 -07002379
Adam Langleyfcf25832014-12-18 17:42:32 -08002380const char *SSL_get_version(const SSL *s) {
2381 return ssl_get_version(s->version);
2382}
Adam Langley95c29f32014-06-20 12:00:00 -07002383
Adam Langleyfcf25832014-12-18 17:42:32 -08002384const char *SSL_SESSION_get_version(const SSL_SESSION *sess) {
2385 return ssl_get_version(sess->ssl_version);
2386}
Adam Langley95c29f32014-06-20 12:00:00 -07002387
Adam Langleyfcf25832014-12-18 17:42:32 -08002388void ssl_clear_cipher_ctx(SSL *s) {
2389 if (s->enc_read_ctx != NULL) {
2390 EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
2391 OPENSSL_free(s->enc_read_ctx);
2392 s->enc_read_ctx = NULL;
2393 }
Adam Langley95c29f32014-06-20 12:00:00 -07002394
Adam Langleyfcf25832014-12-18 17:42:32 -08002395 if (s->enc_write_ctx != NULL) {
2396 EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
2397 OPENSSL_free(s->enc_write_ctx);
2398 s->enc_write_ctx = NULL;
2399 }
Adam Langleya5dc5452014-06-20 12:00:00 -07002400
Adam Langleyfcf25832014-12-18 17:42:32 -08002401 if (s->aead_read_ctx != NULL) {
2402 EVP_AEAD_CTX_cleanup(&s->aead_read_ctx->ctx);
2403 OPENSSL_free(s->aead_read_ctx);
2404 s->aead_read_ctx = NULL;
2405 }
Adam Langleya5dc5452014-06-20 12:00:00 -07002406
Adam Langleyfcf25832014-12-18 17:42:32 -08002407 if (s->aead_write_ctx != NULL) {
2408 EVP_AEAD_CTX_cleanup(&s->aead_write_ctx->ctx);
2409 OPENSSL_free(s->aead_write_ctx);
2410 s->aead_write_ctx = NULL;
2411 }
2412}
Adam Langley95c29f32014-06-20 12:00:00 -07002413
Adam Langleyfcf25832014-12-18 17:42:32 -08002414X509 *SSL_get_certificate(const SSL *s) {
2415 if (s->cert != NULL) {
2416 return s->cert->key->x509;
2417 }
2418
2419 return NULL;
2420}
2421
2422EVP_PKEY *SSL_get_privatekey(const SSL *s) {
2423 if (s->cert != NULL) {
2424 return s->cert->key->privatekey;
2425 }
2426
2427 return NULL;
2428}
2429
2430X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
2431 if (ctx->cert != NULL) {
2432 return ctx->cert->key->x509;
2433 }
2434
2435 return NULL;
2436}
2437
2438EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) {
2439 if (ctx->cert != NULL) {
2440 return ctx->cert->key->privatekey;
2441 }
2442
2443 return NULL;
2444}
2445
2446const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) {
2447 if (s->session != NULL && s->session->cipher != NULL) {
2448 return s->session->cipher;
2449 }
2450
2451 return NULL;
2452}
2453
2454const void *SSL_get_current_compression(SSL *s) { return NULL; }
2455
2456const void *SSL_get_current_expansion(SSL *s) { return NULL; }
2457
2458int ssl_init_wbio_buffer(SSL *s, int push) {
2459 BIO *bbio;
2460
2461 if (s->bbio == NULL) {
2462 bbio = BIO_new(BIO_f_buffer());
2463 if (bbio == NULL) {
2464 return 0;
2465 }
2466 s->bbio = bbio;
2467 } else {
2468 bbio = s->bbio;
2469 if (s->bbio == s->wbio) {
2470 s->wbio = BIO_pop(s->wbio);
2471 }
2472 }
2473
2474 BIO_reset(bbio);
2475 if (!BIO_set_read_buffer_size(bbio, 1)) {
2476 OPENSSL_PUT_ERROR(SSL, ssl_init_wbio_buffer, ERR_R_BUF_LIB);
2477 return 0;
2478 }
2479
2480 if (push) {
2481 if (s->wbio != bbio) {
2482 s->wbio = BIO_push(bbio, s->wbio);
2483 }
2484 } else {
2485 if (s->wbio == bbio) {
2486 s->wbio = BIO_pop(bbio);
2487 }
2488 }
2489
2490 return 1;
2491}
2492
2493void ssl_free_wbio_buffer(SSL *s) {
2494 if (s->bbio == NULL) {
2495 return;
2496 }
2497
2498 if (s->bbio == s->wbio) {
2499 /* remove buffering */
2500 s->wbio = BIO_pop(s->wbio);
2501 }
2502
2503 BIO_free(s->bbio);
2504 s->bbio = NULL;
2505}
2506
2507void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) {
2508 ctx->quiet_shutdown = mode;
2509}
2510
2511int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) {
2512 return ctx->quiet_shutdown;
2513}
2514
2515void SSL_set_quiet_shutdown(SSL *s, int mode) { s->quiet_shutdown = mode; }
2516
2517int SSL_get_quiet_shutdown(const SSL *s) { return s->quiet_shutdown; }
2518
2519void SSL_set_shutdown(SSL *s, int mode) { s->shutdown = mode; }
2520
2521int SSL_get_shutdown(const SSL *s) { return s->shutdown; }
2522
2523int SSL_version(const SSL *s) { return s->version; }
2524
2525SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return ssl->ctx; }
2526
2527SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) {
2528 if (ssl->ctx == ctx) {
2529 return ssl->ctx;
2530 }
2531
2532 if (ctx == NULL) {
2533 ctx = ssl->initial_ctx;
2534 }
2535
2536 if (ssl->cert != NULL) {
2537 ssl_cert_free(ssl->cert);
2538 }
2539
2540 ssl->cert = ssl_cert_dup(ctx->cert);
2541 CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
2542 if (ssl->ctx != NULL) {
2543 SSL_CTX_free(ssl->ctx); /* decrement reference count */
2544 }
2545 ssl->ctx = ctx;
2546
2547 ssl->sid_ctx_length = ctx->sid_ctx_length;
2548 assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx));
2549 memcpy(ssl->sid_ctx, ctx->sid_ctx, sizeof(ssl->sid_ctx));
2550
2551 return ssl->ctx;
2552}
2553
2554int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) {
2555 return X509_STORE_set_default_paths(ctx->cert_store);
2556}
Adam Langley95c29f32014-06-20 12:00:00 -07002557
2558int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
Adam Langleyfcf25832014-12-18 17:42:32 -08002559 const char *CApath) {
2560 return X509_STORE_load_locations(ctx->cert_store, CAfile, CApath);
2561}
Adam Langley95c29f32014-06-20 12:00:00 -07002562
2563void SSL_set_info_callback(SSL *ssl,
Adam Langleyfcf25832014-12-18 17:42:32 -08002564 void (*cb)(const SSL *ssl, int type, int val)) {
2565 ssl->info_callback = cb;
2566}
Adam Langley95c29f32014-06-20 12:00:00 -07002567
Adam Langleyfcf25832014-12-18 17:42:32 -08002568void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/, int /*type*/,
2569 int /*val*/) {
2570 return ssl->info_callback;
2571}
Adam Langley95c29f32014-06-20 12:00:00 -07002572
Adam Langleyfcf25832014-12-18 17:42:32 -08002573int SSL_state(const SSL *ssl) { return ssl->state; }
Adam Langley95c29f32014-06-20 12:00:00 -07002574
Adam Langleyfcf25832014-12-18 17:42:32 -08002575void SSL_set_state(SSL *ssl, int state) { ssl->state = state; }
Adam Langley95c29f32014-06-20 12:00:00 -07002576
Adam Langleyfcf25832014-12-18 17:42:32 -08002577void SSL_set_verify_result(SSL *ssl, long arg) { ssl->verify_result = arg; }
Adam Langley95c29f32014-06-20 12:00:00 -07002578
Adam Langleyfcf25832014-12-18 17:42:32 -08002579long SSL_get_verify_result(const SSL *ssl) { return ssl->verify_result; }
Adam Langley95c29f32014-06-20 12:00:00 -07002580
Adam Langleyfcf25832014-12-18 17:42:32 -08002581int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
2582 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
2583 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp, new_func,
2584 dup_func, free_func);
2585}
Adam Langley95c29f32014-06-20 12:00:00 -07002586
Adam Langleyfcf25832014-12-18 17:42:32 -08002587int SSL_set_ex_data(SSL *s, int idx, void *arg) {
2588 return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
2589}
Adam Langley95c29f32014-06-20 12:00:00 -07002590
Adam Langleyfcf25832014-12-18 17:42:32 -08002591void *SSL_get_ex_data(const SSL *s, int idx) {
2592 return CRYPTO_get_ex_data(&s->ex_data, idx);
2593}
Adam Langley95c29f32014-06-20 12:00:00 -07002594
Adam Langleyfcf25832014-12-18 17:42:32 -08002595int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
2596 CRYPTO_EX_dup *dup_func,
2597 CRYPTO_EX_free *free_func) {
2598 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp, new_func,
2599 dup_func, free_func);
2600}
Adam Langley95c29f32014-06-20 12:00:00 -07002601
Adam Langleyfcf25832014-12-18 17:42:32 -08002602int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg) {
2603 return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
2604}
Adam Langley95c29f32014-06-20 12:00:00 -07002605
Adam Langleyfcf25832014-12-18 17:42:32 -08002606void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx) {
2607 return CRYPTO_get_ex_data(&s->ex_data, idx);
2608}
Adam Langley95c29f32014-06-20 12:00:00 -07002609
Adam Langleyfcf25832014-12-18 17:42:32 -08002610int ssl_ok(SSL *s) { return 1; }
Adam Langley95c29f32014-06-20 12:00:00 -07002611
Adam Langleyfcf25832014-12-18 17:42:32 -08002612X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
2613 return ctx->cert_store;
2614}
Adam Langley95c29f32014-06-20 12:00:00 -07002615
Adam Langleyfcf25832014-12-18 17:42:32 -08002616void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) {
2617 if (ctx->cert_store != NULL) {
2618 X509_STORE_free(ctx->cert_store);
2619 }
2620 ctx->cert_store = store;
2621}
Adam Langley95c29f32014-06-20 12:00:00 -07002622
Adam Langleyfcf25832014-12-18 17:42:32 -08002623int SSL_want(const SSL *s) { return s->rwstate; }
Adam Langley95c29f32014-06-20 12:00:00 -07002624
Adam Langleyfcf25832014-12-18 17:42:32 -08002625void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
2626 RSA *(*cb)(SSL *ssl, int is_export,
2627 int keylength)) {
2628 SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb);
2629}
Adam Langley95c29f32014-06-20 12:00:00 -07002630
Adam Langleyfcf25832014-12-18 17:42:32 -08002631void SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb)(SSL *ssl, int is_export,
2632 int keylength)) {
2633 SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb);
2634}
2635
2636void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
2637 DH *(*dh)(SSL *ssl, int is_export,
2638 int keylength)) {
2639 SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh);
2640}
2641
2642void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh)(SSL *ssl, int is_export,
2643 int keylength)) {
2644 SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh);
2645}
2646
2647void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
2648 EC_KEY *(*ecdh)(SSL *ssl, int is_export,
2649 int keylength)) {
2650 SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH_CB, (void (*)(void))ecdh);
2651}
2652
2653void SSL_set_tmp_ecdh_callback(SSL *ssl,
2654 EC_KEY *(*ecdh)(SSL *ssl, int is_export,
2655 int keylength)) {
2656 SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_ECDH_CB, (void (*)(void))ecdh);
2657}
2658
2659int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) {
2660 if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
2661 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_psk_identity_hint,
2662 SSL_R_DATA_LENGTH_TOO_LONG);
2663 return 0;
2664 }
2665
2666 if (ctx->psk_identity_hint != NULL) {
2667 OPENSSL_free(ctx->psk_identity_hint);
2668 }
2669
2670 if (identity_hint != NULL) {
2671 ctx->psk_identity_hint = BUF_strdup(identity_hint);
2672 if (ctx->psk_identity_hint == NULL) {
2673 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07002674 }
Adam Langleyfcf25832014-12-18 17:42:32 -08002675 } else {
2676 ctx->psk_identity_hint = NULL;
2677 }
Adam Langley95c29f32014-06-20 12:00:00 -07002678
Adam Langleyfcf25832014-12-18 17:42:32 -08002679 return 1;
2680}
2681
2682int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) {
2683 if (s == NULL) {
2684 return 0;
2685 }
2686
2687 if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
2688 OPENSSL_PUT_ERROR(SSL, SSL_use_psk_identity_hint,
2689 SSL_R_DATA_LENGTH_TOO_LONG);
2690 return 0;
2691 }
2692
2693 /* Clear currently configured hint, if any. */
2694 if (s->psk_identity_hint != NULL) {
2695 OPENSSL_free(s->psk_identity_hint);
2696 s->psk_identity_hint = NULL;
2697 }
2698
2699 if (identity_hint != NULL) {
2700 s->psk_identity_hint = BUF_strdup(identity_hint);
2701 if (s->psk_identity_hint == NULL) {
2702 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -07002703 }
Adam Langleyfcf25832014-12-18 17:42:32 -08002704 }
Adam Langley95c29f32014-06-20 12:00:00 -07002705
Adam Langleyfcf25832014-12-18 17:42:32 -08002706 return 1;
2707}
Adam Langley95c29f32014-06-20 12:00:00 -07002708
Adam Langleyfcf25832014-12-18 17:42:32 -08002709const char *SSL_get_psk_identity_hint(const SSL *s) {
2710 if (s == NULL) {
2711 return NULL;
2712 }
2713 return s->psk_identity_hint;
2714}
Adam Langley95c29f32014-06-20 12:00:00 -07002715
Adam Langleyfcf25832014-12-18 17:42:32 -08002716const char *SSL_get_psk_identity(const SSL *s) {
2717 if (s == NULL || s->session == NULL) {
2718 return NULL;
2719 }
Adam Langley95c29f32014-06-20 12:00:00 -07002720
Adam Langleyfcf25832014-12-18 17:42:32 -08002721 return s->session->psk_identity;
2722}
Adam Langley95c29f32014-06-20 12:00:00 -07002723
Adam Langleyfcf25832014-12-18 17:42:32 -08002724void SSL_set_psk_client_callback(
2725 SSL *s, unsigned int (*cb)(SSL *ssl, const char *hint, char *identity,
2726 unsigned int max_identity_len, uint8_t *psk,
2727 unsigned int max_psk_len)) {
2728 s->psk_client_callback = cb;
2729}
Adam Langley95c29f32014-06-20 12:00:00 -07002730
Adam Langleyfcf25832014-12-18 17:42:32 -08002731void SSL_CTX_set_psk_client_callback(
2732 SSL_CTX *ctx, unsigned int (*cb)(SSL *ssl, const char *hint, char *identity,
2733 unsigned int max_identity_len,
2734 uint8_t *psk, unsigned int max_psk_len)) {
2735 ctx->psk_client_callback = cb;
2736}
Adam Langley95c29f32014-06-20 12:00:00 -07002737
Adam Langleyfcf25832014-12-18 17:42:32 -08002738void SSL_set_psk_server_callback(
2739 SSL *s, unsigned int (*cb)(SSL *ssl, const char *identity, uint8_t *psk,
2740 unsigned int max_psk_len)) {
2741 s->psk_server_callback = cb;
2742}
Adam Langley95c29f32014-06-20 12:00:00 -07002743
Adam Langleyfcf25832014-12-18 17:42:32 -08002744void SSL_CTX_set_psk_server_callback(
2745 SSL_CTX *ctx, unsigned int (*cb)(SSL *ssl, const char *identity,
2746 uint8_t *psk, unsigned int max_psk_len)) {
2747 ctx->psk_server_callback = cb;
2748}
Adam Langley95c29f32014-06-20 12:00:00 -07002749
Adam Langleyfcf25832014-12-18 17:42:32 -08002750void SSL_CTX_set_min_version(SSL_CTX *ctx, uint16_t version) {
2751 ctx->min_version = version;
2752}
Adam Langley95c29f32014-06-20 12:00:00 -07002753
Adam Langleyfcf25832014-12-18 17:42:32 -08002754void SSL_CTX_set_max_version(SSL_CTX *ctx, uint16_t version) {
2755 ctx->max_version = version;
2756}
Adam Langley0289c732014-06-20 12:00:00 -07002757
Adam Langleyfcf25832014-12-18 17:42:32 -08002758void SSL_set_min_version(SSL *ssl, uint16_t version) {
2759 ssl->min_version = version;
2760}
Adam Langley0289c732014-06-20 12:00:00 -07002761
Adam Langleyfcf25832014-12-18 17:42:32 -08002762void SSL_set_max_version(SSL *ssl, uint16_t version) {
2763 ssl->max_version = version;
2764}
Adam Langley95c29f32014-06-20 12:00:00 -07002765
Adam Langleyfcf25832014-12-18 17:42:32 -08002766void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
2767 void (*cb)(int write_p, int version,
2768 int content_type, const void *buf,
2769 size_t len, SSL *ssl, void *arg)) {
2770 SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
2771}
2772void SSL_set_msg_callback(SSL *ssl,
2773 void (*cb)(int write_p, int version, int content_type,
2774 const void *buf, size_t len, SSL *ssl,
2775 void *arg)) {
2776 SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
2777}
Adam Langley95c29f32014-06-20 12:00:00 -07002778
Adam Langleyfcf25832014-12-18 17:42:32 -08002779void SSL_CTX_set_keylog_bio(SSL_CTX *ctx, BIO *keylog_bio) {
2780 if (ctx->keylog_bio != NULL) {
2781 BIO_free(ctx->keylog_bio);
2782 }
2783 ctx->keylog_bio = keylog_bio;
2784}
Adam Langley95c29f32014-06-20 12:00:00 -07002785
Adam Langleyfcf25832014-12-18 17:42:32 -08002786static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) {
2787 static const char hextable[] = "0123456789abcdef";
2788 uint8_t *out;
2789 size_t i;
Adam Langley95c29f32014-06-20 12:00:00 -07002790
Adam Langleyfcf25832014-12-18 17:42:32 -08002791 if (!CBB_add_space(cbb, &out, in_len * 2)) {
2792 return 0;
2793 }
Adam Langley95c29f32014-06-20 12:00:00 -07002794
Adam Langleyfcf25832014-12-18 17:42:32 -08002795 for (i = 0; i < in_len; i++) {
2796 *(out++) = (uint8_t)hextable[in[i] >> 4];
2797 *(out++) = (uint8_t)hextable[in[i] & 0xf];
2798 }
Adam Langley95c29f32014-06-20 12:00:00 -07002799
Adam Langleyfcf25832014-12-18 17:42:32 -08002800 return 1;
2801}
David Benjamin859ec3c2014-09-02 16:29:36 -04002802
2803int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx,
Adam Langleyfcf25832014-12-18 17:42:32 -08002804 const uint8_t *encrypted_premaster,
2805 size_t encrypted_premaster_len,
2806 const uint8_t *premaster,
2807 size_t premaster_len) {
2808 BIO *bio = ctx->keylog_bio;
2809 CBB cbb;
2810 uint8_t *out;
2811 size_t out_len;
2812 int ret;
David Benjamin859ec3c2014-09-02 16:29:36 -04002813
Adam Langleyfcf25832014-12-18 17:42:32 -08002814 if (bio == NULL) {
2815 return 1;
2816 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002817
Adam Langleyfcf25832014-12-18 17:42:32 -08002818 if (encrypted_premaster_len < 8) {
2819 OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_rsa_client_key_exchange,
2820 ERR_R_INTERNAL_ERROR);
2821 return 0;
2822 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002823
Adam Langleyfcf25832014-12-18 17:42:32 -08002824 if (!CBB_init(&cbb, 4 + 16 + 1 + premaster_len * 2 + 1)) {
2825 return 0;
2826 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002827
Adam Langleyfcf25832014-12-18 17:42:32 -08002828 if (!CBB_add_bytes(&cbb, (const uint8_t *)"RSA ", 4) ||
2829 /* Only the first 8 bytes of the encrypted premaster secret are
2830 * logged. */
2831 !cbb_add_hex(&cbb, encrypted_premaster, 8) ||
2832 !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
2833 !cbb_add_hex(&cbb, premaster, premaster_len) ||
2834 !CBB_add_bytes(&cbb, (const uint8_t *)"\n", 1) ||
2835 !CBB_finish(&cbb, &out, &out_len)) {
2836 CBB_cleanup(&cbb);
2837 return 0;
2838 }
David Benjamin859ec3c2014-09-02 16:29:36 -04002839
Adam Langleyfcf25832014-12-18 17:42:32 -08002840 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
2841 ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio);
2842 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
David Benjamin859ec3c2014-09-02 16:29:36 -04002843
Adam Langleyfcf25832014-12-18 17:42:32 -08002844 OPENSSL_free(out);
2845 return ret;
Adam Langley95f22882014-06-20 12:00:00 -07002846}
2847
Adam Langleyfcf25832014-12-18 17:42:32 -08002848int ssl_ctx_log_master_secret(SSL_CTX *ctx, const uint8_t *client_random,
2849 size_t client_random_len, const uint8_t *master,
2850 size_t master_len) {
2851 BIO *bio = ctx->keylog_bio;
2852 CBB cbb;
2853 uint8_t *out;
2854 size_t out_len;
2855 int ret;
Adam Langleyadb739e2014-06-20 12:00:00 -07002856
Adam Langleyfcf25832014-12-18 17:42:32 -08002857 if (bio == NULL) {
2858 return 1;
2859 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002860
Adam Langleyfcf25832014-12-18 17:42:32 -08002861 if (client_random_len != 32) {
2862 OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_master_secret, ERR_R_INTERNAL_ERROR);
2863 return 0;
2864 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002865
Adam Langleyfcf25832014-12-18 17:42:32 -08002866 if (!CBB_init(&cbb, 14 + 64 + 1 + master_len * 2 + 1)) {
2867 return 0;
2868 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002869
Adam Langleyfcf25832014-12-18 17:42:32 -08002870 if (!CBB_add_bytes(&cbb, (const uint8_t *)"CLIENT_RANDOM ", 14) ||
2871 !cbb_add_hex(&cbb, client_random, 32) ||
2872 !CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
2873 !cbb_add_hex(&cbb, master, master_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 }
Adam Langleyadb739e2014-06-20 12:00:00 -07002879
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 Benjamine99e9122014-12-11 01:46:01 -05002883
Adam Langleyfcf25832014-12-18 17:42:32 -08002884 OPENSSL_free(out);
2885 return ret;
Adam Langley95c29f32014-06-20 12:00:00 -07002886}
2887
Adam Langleyfcf25832014-12-18 17:42:32 -08002888int SSL_cutthrough_complete(const SSL *s) {
2889 return (
2890 !s->server && /* cutthrough only applies to clients */
2891 !s->hit && /* full-handshake */
2892 s->version >= SSL3_VERSION &&
2893 s->s3->in_read_app_data == 0 && /* cutthrough only applies to write() */
2894 (SSL_get_mode((SSL *)s) &
2895 SSL_MODE_HANDSHAKE_CUTTHROUGH) && /* cutthrough enabled */
2896 ssl3_can_cutthrough(s) && /* cutthrough allowed */
2897 s->s3->previous_server_finished_len ==
2898 0 && /* not a renegotiation handshake */
2899 (s->state == SSL3_ST_CR_SESSION_TICKET_A || /* ready to write app-data*/
2900 s->state == SSL3_ST_CR_CHANGE || s->state == SSL3_ST_CR_FINISHED_A));
2901}
Adam Langley95c29f32014-06-20 12:00:00 -07002902
Adam Langleyfcf25832014-12-18 17:42:32 -08002903void SSL_get_structure_sizes(size_t *ssl_size, size_t *ssl_ctx_size,
2904 size_t *ssl_session_size) {
2905 *ssl_size = sizeof(SSL);
2906 *ssl_ctx_size = sizeof(SSL_CTX);
2907 *ssl_session_size = sizeof(SSL_SESSION);
2908}
Feng Lu41aa3252014-11-21 22:47:56 -08002909
Adam Langleyfcf25832014-12-18 17:42:32 -08002910int ssl3_can_cutthrough(const SSL *s) {
2911 const SSL_CIPHER *c;
2912
2913 /* require a strong enough cipher */
2914 if (SSL_get_cipher_bits(s, NULL) < 128) {
2915 return 0;
2916 }
2917
2918 /* require ALPN or NPN extension */
2919 if (!s->s3->alpn_selected && !s->s3->next_proto_neg_seen) {
2920 return 0;
2921 }
2922
2923 /* require a forward-secret cipher */
2924 c = SSL_get_current_cipher(s);
2925 if (!c ||
2926 (c->algorithm_mkey != SSL_kEDH && c->algorithm_mkey != SSL_kEECDH)) {
2927 return 0;
2928 }
2929
2930 return 1;
2931}
2932
2933const SSL3_ENC_METHOD *ssl3_get_enc_method(uint16_t version) {
2934 switch (version) {
2935 case SSL3_VERSION:
2936 return &SSLv3_enc_data;
2937
2938 case TLS1_VERSION:
2939 return &TLSv1_enc_data;
2940
2941 case TLS1_1_VERSION:
2942 return &TLSv1_1_enc_data;
2943
2944 case TLS1_2_VERSION:
2945 return &TLSv1_2_enc_data;
2946
2947 case DTLS1_VERSION:
2948 return &DTLSv1_enc_data;
2949
2950 case DTLS1_2_VERSION:
2951 return &DTLSv1_2_enc_data;
2952
2953 default:
2954 return NULL;
2955 }
2956}
2957
2958uint16_t ssl3_get_max_server_version(const SSL *s) {
2959 uint16_t max_version;
2960
2961 if (SSL_IS_DTLS(s)) {
2962 max_version = (s->max_version != 0) ? s->max_version : DTLS1_2_VERSION;
2963 if (!(s->options & SSL_OP_NO_DTLSv1_2) && DTLS1_2_VERSION >= max_version) {
2964 return DTLS1_2_VERSION;
2965 }
2966 if (!(s->options & SSL_OP_NO_DTLSv1) && DTLS1_VERSION >= max_version) {
2967 return DTLS1_VERSION;
2968 }
2969 return 0;
2970 }
2971
2972 max_version = (s->max_version != 0) ? s->max_version : TLS1_2_VERSION;
2973 if (!(s->options & SSL_OP_NO_TLSv1_2) && TLS1_2_VERSION <= max_version) {
2974 return TLS1_2_VERSION;
2975 }
2976 if (!(s->options & SSL_OP_NO_TLSv1_1) && TLS1_1_VERSION <= max_version) {
2977 return TLS1_1_VERSION;
2978 }
2979 if (!(s->options & SSL_OP_NO_TLSv1) && TLS1_VERSION <= max_version) {
2980 return TLS1_VERSION;
2981 }
2982 if (!(s->options & SSL_OP_NO_SSLv3) && SSL3_VERSION <= max_version) {
2983 return SSL3_VERSION;
2984 }
2985 return 0;
2986}
2987
2988uint16_t ssl3_get_mutual_version(SSL *s, uint16_t client_version) {
2989 uint16_t version = 0;
2990
2991 if (SSL_IS_DTLS(s)) {
2992 /* Clamp client_version to max_version. */
2993 if (s->max_version != 0 && client_version < s->max_version) {
2994 client_version = s->max_version;
2995 }
2996
2997 if (client_version <= DTLS1_2_VERSION && !(s->options & SSL_OP_NO_DTLSv1_2)) {
2998 version = DTLS1_2_VERSION;
2999 } else if (client_version <= DTLS1_VERSION &&
3000 !(s->options & SSL_OP_NO_DTLSv1)) {
3001 version = DTLS1_VERSION;
3002 }
3003
3004 /* Check against min_version. */
3005 if (version != 0 && s->min_version != 0 && version > s->min_version) {
3006 return 0;
3007 }
3008 return version;
3009 } else {
3010 /* Clamp client_version to max_version. */
3011 if (s->max_version != 0 && client_version > s->max_version) {
3012 client_version = s->max_version;
3013 }
3014
3015 if (client_version >= TLS1_2_VERSION && !(s->options & SSL_OP_NO_TLSv1_2)) {
3016 version = TLS1_2_VERSION;
3017 } else if (client_version >= TLS1_1_VERSION &&
3018 !(s->options & SSL_OP_NO_TLSv1_1)) {
3019 version = TLS1_1_VERSION;
3020 } else if (client_version >= TLS1_VERSION && !(s->options & SSL_OP_NO_TLSv1)) {
3021 version = TLS1_VERSION;
3022 } else if (client_version >= SSL3_VERSION && !(s->options & SSL_OP_NO_SSLv3)) {
3023 version = SSL3_VERSION;
3024 }
3025
3026 /* Check against min_version. */
3027 if (version != 0 && s->min_version != 0 && version < s->min_version) {
3028 return 0;
3029 }
3030 return version;
3031 }
3032}
3033
3034uint16_t ssl3_get_max_client_version(SSL *s) {
3035 unsigned long options = s->options;
3036 uint16_t version = 0;
3037
3038 /* OpenSSL's API for controlling versions entails blacklisting individual
3039 * protocols. This has two problems. First, on the client, the protocol can
3040 * only express a contiguous range of versions. Second, a library consumer
3041 * trying to set a maximum version cannot disable protocol versions that get
3042 * added in a future version of the library.
3043 *
3044 * To account for both of these, OpenSSL interprets the client-side bitmask
3045 * as a min/max range by picking the lowest contiguous non-empty range of
3046 * enabled protocols. Note that this means it is impossible to set a maximum
3047 * version of TLS 1.2 in a future-proof way.
3048 *
3049 * By this scheme, the maximum version is the lowest version V such that V is
3050 * enabled and V+1 is disabled or unimplemented. */
3051 if (SSL_IS_DTLS(s)) {
3052 if (!(options & SSL_OP_NO_DTLSv1_2)) {
3053 version = DTLS1_2_VERSION;
3054 }
3055 if (!(options & SSL_OP_NO_DTLSv1) && (options & SSL_OP_NO_DTLSv1_2)) {
3056 version = DTLS1_VERSION;
3057 }
3058 if (s->max_version != 0 && version < s->max_version) {
3059 version = s->max_version;
3060 }
3061 } else {
3062 if (!(options & SSL_OP_NO_TLSv1_2)) {
3063 version = TLS1_2_VERSION;
3064 }
3065 if (!(options & SSL_OP_NO_TLSv1_1) && (options & SSL_OP_NO_TLSv1_2)) {
3066 version = TLS1_1_VERSION;
3067 }
3068 if (!(options & SSL_OP_NO_TLSv1) && (options & SSL_OP_NO_TLSv1_1)) {
3069 version = TLS1_VERSION;
3070 }
3071 if (!(options & SSL_OP_NO_SSLv3) && (options & SSL_OP_NO_TLSv1)) {
3072 version = SSL3_VERSION;
3073 }
3074 if (s->max_version != 0 && version > s->max_version) {
3075 version = s->max_version;
3076 }
3077 }
3078
3079 return version;
3080}
3081
3082int ssl3_is_version_enabled(SSL *s, uint16_t version) {
3083 if (SSL_IS_DTLS(s)) {
3084 if (s->max_version != 0 && version < s->max_version) {
3085 return 0;
3086 }
3087 if (s->min_version != 0 && version > s->min_version) {
3088 return 0;
3089 }
3090
3091 switch (version) {
3092 case DTLS1_VERSION:
3093 return !(s->options & SSL_OP_NO_DTLSv1);
3094
3095 case DTLS1_2_VERSION:
3096 return !(s->options & SSL_OP_NO_DTLSv1_2);
3097
3098 default:
3099 return 0;
3100 }
3101 } else {
3102 if (s->max_version != 0 && version > s->max_version) {
3103 return 0;
3104 }
3105 if (s->min_version != 0 && version < s->min_version) {
3106 return 0;
3107 }
3108
3109 switch (version) {
3110 case SSL3_VERSION:
3111 return !(s->options & SSL_OP_NO_SSLv3);
3112
3113 case TLS1_VERSION:
3114 return !(s->options & SSL_OP_NO_TLSv1);
3115
3116 case TLS1_1_VERSION:
3117 return !(s->options & SSL_OP_NO_TLSv1_1);
3118
3119 case TLS1_2_VERSION:
3120 return !(s->options & SSL_OP_NO_TLSv1_2);
3121
3122 default:
3123 return 0;
3124 }
3125 }
3126}
3127
3128/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer vairable,
3129 * freeing EVP_MD_CTX previously stored in that variable, if any. If EVP_MD
3130 * pointer is passed, initializes ctx with this md Returns newly allocated
3131 * ctx. */
3132EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md) {
3133 ssl_clear_hash_ctx(hash);
3134 *hash = EVP_MD_CTX_create();
3135 if (md != NULL && *hash != NULL && !EVP_DigestInit_ex(*hash, md, NULL)) {
3136 EVP_MD_CTX_destroy(*hash);
3137 *hash = NULL;
3138 }
3139 return *hash;
3140}
3141
3142void ssl_clear_hash_ctx(EVP_MD_CTX **hash) {
3143 if (*hash) {
3144 EVP_MD_CTX_destroy(*hash);
3145 }
3146 *hash = NULL;
3147}
3148
3149int SSL_cache_hit(SSL *s) { return s->hit; }
3150
3151int SSL_is_server(SSL *s) { return s->server; }
3152
3153void SSL_enable_fastradio_padding(SSL *s, char on_off) {
3154 s->fastradio_padding = on_off;
3155}