Coverage Report

Created: 2025-06-11 06:40

/src/boringssl/ssl/ssl_x509.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
2
// Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
3
// Copyright 2005 Nokia. All rights reserved.
4
//
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
//
9
//     https://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
16
17
#include <openssl/ssl.h>
18
19
#include <assert.h>
20
21
#include <openssl/asn1.h>
22
#include <openssl/bytestring.h>
23
#include <openssl/err.h>
24
#include <openssl/pem.h>
25
#include <openssl/stack.h>
26
#include <openssl/x509.h>
27
28
#include "../crypto/internal.h"
29
#include "internal.h"
30
31
32
BSSL_NAMESPACE_BEGIN
33
34
// check_ssl_x509_method asserts that |ssl| has the X509-based method
35
// installed. Calling an X509-based method on an |ssl| with a different method
36
// will likely misbehave and possibly crash or leak memory.
37
1.85k
static void check_ssl_x509_method(const SSL *ssl) {
38
1.85k
  assert(ssl == NULL || ssl->ctx->x509_method == &ssl_crypto_x509_method);
39
1.85k
}
40
41
// check_ssl_ctx_x509_method acts like |check_ssl_x509_method|, but for an
42
// |SSL_CTX|.
43
4
static void check_ssl_ctx_x509_method(const SSL_CTX *ctx) {
44
4
  assert(ctx == NULL || ctx->x509_method == &ssl_crypto_x509_method);
45
4
}
46
47
// x509_to_buffer returns a |CRYPTO_BUFFER| that contains the serialised
48
// contents of |x509|.
49
2
static UniquePtr<CRYPTO_BUFFER> x509_to_buffer(X509 *x509) {
50
2
  uint8_t *buf = NULL;
51
2
  int cert_len = i2d_X509(x509, &buf);
52
2
  if (cert_len <= 0) {
53
0
    return 0;
54
0
  }
55
56
2
  UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(buf, cert_len, NULL));
57
2
  OPENSSL_free(buf);
58
59
2
  return buffer;
60
2
}
61
62
19.3k
static void ssl_crypto_x509_cert_flush_cached_leaf(CERT *cert) {
63
19.3k
  X509_free(cert->x509_leaf);
64
19.3k
  cert->x509_leaf = nullptr;
65
19.3k
}
66
67
19.3k
static void ssl_crypto_x509_cert_flush_cached_chain(CERT *cert) {
68
19.3k
  sk_X509_pop_free(cert->x509_chain, X509_free);
69
19.3k
  cert->x509_chain = nullptr;
70
19.3k
}
71
72
// ssl_cert_set1_chain sets elements 1.. of |cert->chain| to the serialised
73
// forms of elements of |chain|. It returns one on success or zero on error, in
74
// which case no change to |cert->chain| is made. It preverses the existing
75
// leaf from |cert->chain|, if any.
76
0
static bool ssl_cert_set1_chain(CERT *cert, STACK_OF(X509) *chain) {
77
0
  cert->legacy_credential->ClearIntermediateCerts();
78
0
  for (X509 *x509 : chain) {
79
0
    UniquePtr<CRYPTO_BUFFER> buffer = x509_to_buffer(x509);
80
0
    if (!buffer ||
81
0
        !cert->legacy_credential->AppendIntermediateCert(std::move(buffer))) {
82
0
      return false;
83
0
    }
84
0
  }
85
86
0
  ssl_crypto_x509_cert_flush_cached_chain(cert);
87
0
  return true;
88
0
}
89
90
static bool ssl_crypto_x509_check_client_CA_list(
91
148
    STACK_OF(CRYPTO_BUFFER) *names) {
92
152
  for (const CRYPTO_BUFFER *buffer : names) {
93
152
    const uint8_t *inp = CRYPTO_BUFFER_data(buffer);
94
152
    UniquePtr<X509_NAME> name(
95
152
        d2i_X509_NAME(nullptr, &inp, CRYPTO_BUFFER_len(buffer)));
96
152
    if (name == nullptr ||
97
152
        inp != CRYPTO_BUFFER_data(buffer) + CRYPTO_BUFFER_len(buffer)) {
98
112
      return false;
99
112
    }
100
152
  }
101
102
36
  return true;
103
148
}
104
105
19.3k
static void ssl_crypto_x509_cert_clear(CERT *cert) {
106
19.3k
  ssl_crypto_x509_cert_flush_cached_leaf(cert);
107
19.3k
  ssl_crypto_x509_cert_flush_cached_chain(cert);
108
109
19.3k
  X509_free(cert->x509_stash);
110
19.3k
  cert->x509_stash = nullptr;
111
19.3k
}
112
113
19.3k
static void ssl_crypto_x509_cert_free(CERT *cert) {
114
19.3k
  ssl_crypto_x509_cert_clear(cert);
115
19.3k
  X509_STORE_free(cert->verify_store);
116
19.3k
}
117
118
19.3k
static void ssl_crypto_x509_cert_dup(CERT *new_cert, const CERT *cert) {
119
19.3k
  if (cert->verify_store != nullptr) {
120
0
    X509_STORE_up_ref(cert->verify_store);
121
0
    new_cert->verify_store = cert->verify_store;
122
0
  }
123
19.3k
}
124
125
28.9k
static bool ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) {
126
28.9k
  bssl::UniquePtr<STACK_OF(X509)> chain, chain_without_leaf;
127
28.9k
  if (sk_CRYPTO_BUFFER_num(sess->certs.get()) > 0) {
128
19.6k
    chain.reset(sk_X509_new_null());
129
19.6k
    if (!chain) {
130
0
      return false;
131
0
    }
132
19.6k
    if (sess->is_server) {
133
      // chain_without_leaf is only needed for server sessions. See
134
      // |SSL_get_peer_cert_chain|.
135
3.91k
      chain_without_leaf.reset(sk_X509_new_null());
136
3.91k
      if (!chain_without_leaf) {
137
0
        return false;
138
0
      }
139
3.91k
    }
140
19.6k
  }
141
142
28.9k
  bssl::UniquePtr<X509> leaf;
143
28.9k
  for (CRYPTO_BUFFER *cert : sess->certs.get()) {
144
22.9k
    UniquePtr<X509> x509(X509_parse_from_buffer(cert));
145
22.9k
    if (!x509) {
146
1.18k
      OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
147
1.18k
      return false;
148
1.18k
    }
149
21.7k
    if (leaf == nullptr) {
150
18.5k
      leaf = UpRef(x509);
151
18.5k
    } else if (chain_without_leaf &&
152
3.23k
               !PushToStack(chain_without_leaf.get(), UpRef(x509))) {
153
0
      return false;
154
0
    }
155
21.7k
    if (!PushToStack(chain.get(), std::move(x509))) {
156
0
      return false;
157
0
    }
158
21.7k
  }
159
160
27.7k
  sk_X509_pop_free(sess->x509_chain, X509_free);
161
27.7k
  sess->x509_chain = chain.release();
162
163
27.7k
  sk_X509_pop_free(sess->x509_chain_without_leaf, X509_free);
164
27.7k
  sess->x509_chain_without_leaf = chain_without_leaf.release();
165
166
27.7k
  X509_free(sess->x509_peer);
167
27.7k
  sess->x509_peer = leaf.release();
168
27.7k
  return true;
169
28.9k
}
170
171
static bool ssl_crypto_x509_session_dup(SSL_SESSION *new_session,
172
637
                                        const SSL_SESSION *session) {
173
637
  new_session->x509_peer = UpRef(session->x509_peer).release();
174
637
  if (session->x509_chain != nullptr) {
175
28
    new_session->x509_chain = X509_chain_up_ref(session->x509_chain);
176
28
    if (new_session->x509_chain == nullptr) {
177
0
      return false;
178
0
    }
179
28
  }
180
637
  if (session->x509_chain_without_leaf != nullptr) {
181
28
    new_session->x509_chain_without_leaf =
182
28
        X509_chain_up_ref(session->x509_chain_without_leaf);
183
28
    if (new_session->x509_chain_without_leaf == nullptr) {
184
0
      return false;
185
0
    }
186
28
  }
187
188
637
  return true;
189
637
}
190
191
33.2k
static void ssl_crypto_x509_session_clear(SSL_SESSION *session) {
192
33.2k
  X509_free(session->x509_peer);
193
33.2k
  session->x509_peer = nullptr;
194
33.2k
  sk_X509_pop_free(session->x509_chain, X509_free);
195
33.2k
  session->x509_chain = nullptr;
196
33.2k
  sk_X509_pop_free(session->x509_chain_without_leaf, X509_free);
197
33.2k
  session->x509_chain_without_leaf = nullptr;
198
33.2k
}
199
200
static bool ssl_crypto_x509_session_verify_cert_chain(SSL_SESSION *session,
201
                                                      SSL_HANDSHAKE *hs,
202
819
                                                      uint8_t *out_alert) {
203
819
  *out_alert = SSL_AD_INTERNAL_ERROR;
204
819
  STACK_OF(X509) *const cert_chain = session->x509_chain;
205
819
  if (cert_chain == nullptr || sk_X509_num(cert_chain) == 0) {
206
0
    return false;
207
0
  }
208
209
819
  SSL *const ssl = hs->ssl;
210
819
  SSL_CTX *ssl_ctx = ssl->ctx.get();
211
819
  X509_STORE *verify_store = ssl_ctx->cert_store;
212
819
  if (hs->config->cert->verify_store != nullptr) {
213
0
    verify_store = hs->config->cert->verify_store;
214
0
  }
215
216
819
  X509 *leaf = sk_X509_value(cert_chain, 0);
217
819
  const char *name;
218
819
  size_t name_len;
219
819
  SSL_get0_ech_name_override(ssl, &name, &name_len);
220
819
  UniquePtr<X509_STORE_CTX> ctx(X509_STORE_CTX_new());
221
819
  if (!ctx ||                                                             //
222
819
      !X509_STORE_CTX_init(ctx.get(), verify_store, leaf, cert_chain) ||  //
223
819
      !X509_STORE_CTX_set_ex_data(
224
819
          ctx.get(), SSL_get_ex_data_X509_STORE_CTX_idx(), ssl) ||  //
225
      // We need to inherit the verify parameters. These can be determined by
226
      // the context: if its a server it will verify SSL client certificates or
227
      // vice versa.
228
819
      !X509_STORE_CTX_set_default(
229
819
          ctx.get(),
230
819
          ssl->server ? "ssl_client" : "ssl_server") ||  //
231
      // Anything non-default in "param" should overwrite anything in the ctx.
232
819
      !X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(ctx.get()),
233
819
                              hs->config->param) ||  //
234
      // ClientHelloOuter connections use a different name.
235
819
      (name_len != 0 &&  //
236
819
       !X509_VERIFY_PARAM_set1_host(X509_STORE_CTX_get0_param(ctx.get()), name,
237
0
                                    name_len))) {
238
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
239
0
    return false;
240
0
  }
241
242
819
  if (hs->config->verify_callback) {
243
0
    X509_STORE_CTX_set_verify_cb(ctx.get(), hs->config->verify_callback);
244
0
  }
245
246
819
  int verify_ret;
247
819
  if (ssl_ctx->app_verify_callback != nullptr) {
248
819
    verify_ret =
249
819
        ssl_ctx->app_verify_callback(ctx.get(), ssl_ctx->app_verify_arg);
250
819
  } else {
251
0
    verify_ret = X509_verify_cert(ctx.get());
252
0
  }
253
254
819
  session->verify_result = X509_STORE_CTX_get_error(ctx.get());
255
256
  // If |SSL_VERIFY_NONE|, the error is non-fatal, but we keep the result.
257
819
  if (verify_ret <= 0 && hs->config->verify_mode != SSL_VERIFY_NONE) {
258
0
    *out_alert = SSL_alert_from_verify_result(session->verify_result);
259
0
    return false;
260
0
  }
261
262
819
  ERR_clear_error();
263
819
  return true;
264
819
}
265
266
19.3k
static void ssl_crypto_x509_hs_flush_cached_ca_names(SSL_HANDSHAKE *hs) {
267
19.3k
  sk_X509_NAME_pop_free(hs->cached_x509_ca_names, X509_NAME_free);
268
19.3k
  hs->cached_x509_ca_names = nullptr;
269
19.3k
}
270
271
19.3k
static bool ssl_crypto_x509_ssl_new(SSL_HANDSHAKE *hs) {
272
19.3k
  hs->config->param = X509_VERIFY_PARAM_new();
273
19.3k
  if (hs->config->param == nullptr) {
274
0
    return false;
275
0
  }
276
19.3k
  X509_VERIFY_PARAM_inherit(hs->config->param, hs->ssl->ctx->param);
277
19.3k
  return true;
278
19.3k
}
279
280
0
static void ssl_crypto_x509_ssl_flush_cached_client_CA(SSL_CONFIG *cfg) {
281
0
  sk_X509_NAME_pop_free(cfg->cached_x509_client_CA, X509_NAME_free);
282
0
  cfg->cached_x509_client_CA = nullptr;
283
0
}
284
285
19.3k
static void ssl_crypto_x509_ssl_config_free(SSL_CONFIG *cfg) {
286
19.3k
  sk_X509_NAME_pop_free(cfg->cached_x509_client_CA, X509_NAME_free);
287
19.3k
  cfg->cached_x509_client_CA = nullptr;
288
19.3k
  X509_VERIFY_PARAM_free(cfg->param);
289
19.3k
}
290
291
3.80k
static bool ssl_crypto_x509_ssl_auto_chain_if_needed(SSL_HANDSHAKE *hs) {
292
  // Only build a chain if the feature isn't disabled, the legacy credential
293
  // exists but has no intermediates configured.
294
3.80k
  SSL *ssl = hs->ssl;
295
3.80k
  SSL_CREDENTIAL *cred = hs->config->cert->legacy_credential.get();
296
3.80k
  if ((ssl->mode & SSL_MODE_NO_AUTO_CHAIN) || !cred->IsComplete() ||
297
3.80k
      sk_CRYPTO_BUFFER_num(cred->chain.get()) != 1) {
298
3.80k
    return true;
299
3.80k
  }
300
301
0
  UniquePtr<X509> leaf(
302
0
      X509_parse_from_buffer(sk_CRYPTO_BUFFER_value(cred->chain.get(), 0)));
303
0
  if (!leaf) {
304
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
305
0
    return false;
306
0
  }
307
308
0
  UniquePtr<X509_STORE_CTX> ctx(X509_STORE_CTX_new());
309
0
  if (!ctx || !X509_STORE_CTX_init(ctx.get(), ssl->ctx->cert_store, leaf.get(),
310
0
                                   nullptr)) {
311
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
312
0
    return false;
313
0
  }
314
315
  // Attempt to build a chain, ignoring the result.
316
0
  X509_verify_cert(ctx.get());
317
0
  ERR_clear_error();
318
319
  // Remove the leaf from the generated chain.
320
0
  UniquePtr<STACK_OF(X509)> chain(X509_STORE_CTX_get1_chain(ctx.get()));
321
0
  if (!chain) {
322
0
    return false;
323
0
  }
324
0
  X509_free(sk_X509_shift(chain.get()));
325
326
0
  return SSL_set1_chain(ssl, chain.get());
327
0
}
328
329
0
static void ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(SSL_CTX *ctx) {
330
0
  sk_X509_NAME_pop_free(ctx->cached_x509_client_CA, X509_NAME_free);
331
0
  ctx->cached_x509_client_CA = nullptr;
332
0
}
333
334
2
static bool ssl_crypto_x509_ssl_ctx_new(SSL_CTX *ctx) {
335
2
  ctx->cert_store = X509_STORE_new();
336
2
  ctx->param = X509_VERIFY_PARAM_new();
337
2
  return (ctx->cert_store != nullptr && ctx->param != nullptr);
338
2
}
339
340
0
static void ssl_crypto_x509_ssl_ctx_free(SSL_CTX *ctx) {
341
0
  ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(ctx);
342
0
  X509_VERIFY_PARAM_free(ctx->param);
343
0
  X509_STORE_free(ctx->cert_store);
344
0
}
345
346
const SSL_X509_METHOD ssl_crypto_x509_method = {
347
    ssl_crypto_x509_check_client_CA_list,
348
    ssl_crypto_x509_cert_clear,
349
    ssl_crypto_x509_cert_free,
350
    ssl_crypto_x509_cert_dup,
351
    ssl_crypto_x509_cert_flush_cached_chain,
352
    ssl_crypto_x509_cert_flush_cached_leaf,
353
    ssl_crypto_x509_session_cache_objects,
354
    ssl_crypto_x509_session_dup,
355
    ssl_crypto_x509_session_clear,
356
    ssl_crypto_x509_session_verify_cert_chain,
357
    ssl_crypto_x509_hs_flush_cached_ca_names,
358
    ssl_crypto_x509_ssl_new,
359
    ssl_crypto_x509_ssl_config_free,
360
    ssl_crypto_x509_ssl_flush_cached_client_CA,
361
    ssl_crypto_x509_ssl_auto_chain_if_needed,
362
    ssl_crypto_x509_ssl_ctx_new,
363
    ssl_crypto_x509_ssl_ctx_free,
364
    ssl_crypto_x509_ssl_ctx_flush_cached_client_CA,
365
};
366
367
BSSL_NAMESPACE_END
368
369
using namespace bssl;
370
371
0
X509 *SSL_get_peer_certificate(const SSL *ssl) {
372
0
  check_ssl_x509_method(ssl);
373
0
  if (ssl == NULL) {
374
0
    return NULL;
375
0
  }
376
0
  SSL_SESSION *session = SSL_get_session(ssl);
377
0
  if (session == NULL || session->x509_peer == NULL) {
378
0
    return NULL;
379
0
  }
380
0
  X509_up_ref(session->x509_peer);
381
0
  return session->x509_peer;
382
0
}
383
384
0
STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) {
385
0
  check_ssl_x509_method(ssl);
386
0
  if (ssl == nullptr) {
387
0
    return nullptr;
388
0
  }
389
0
  SSL_SESSION *session = SSL_get_session(ssl);
390
0
  if (session == nullptr) {
391
0
    return nullptr;
392
0
  }
393
394
  // OpenSSL historically didn't include the leaf certificate in the returned
395
  // certificate chain, but only for servers.
396
0
  return ssl->server ? session->x509_chain_without_leaf : session->x509_chain;
397
0
}
398
399
0
STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl) {
400
0
  check_ssl_x509_method(ssl);
401
0
  SSL_SESSION *session = SSL_get_session(ssl);
402
0
  if (session == NULL) {
403
0
    return NULL;
404
0
  }
405
406
0
  return session->x509_chain;
407
0
}
408
409
0
int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) {
410
0
  check_ssl_ctx_x509_method(ctx);
411
0
  return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
412
0
}
413
414
0
int SSL_set_purpose(SSL *ssl, int purpose) {
415
0
  check_ssl_x509_method(ssl);
416
0
  if (!ssl->config) {
417
0
    return 0;
418
0
  }
419
0
  return X509_VERIFY_PARAM_set_purpose(ssl->config->param, purpose);
420
0
}
421
422
0
int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) {
423
0
  check_ssl_ctx_x509_method(ctx);
424
0
  return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
425
0
}
426
427
0
int SSL_set_trust(SSL *ssl, int trust) {
428
0
  check_ssl_x509_method(ssl);
429
0
  if (!ssl->config) {
430
0
    return 0;
431
0
  }
432
0
  return X509_VERIFY_PARAM_set_trust(ssl->config->param, trust);
433
0
}
434
435
0
int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) {
436
0
  check_ssl_ctx_x509_method(ctx);
437
0
  return X509_VERIFY_PARAM_set1(ctx->param, param);
438
0
}
439
440
0
int SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) {
441
0
  check_ssl_x509_method(ssl);
442
0
  if (!ssl->config) {
443
0
    return 0;
444
0
  }
445
0
  return X509_VERIFY_PARAM_set1(ssl->config->param, param);
446
0
}
447
448
0
X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) {
449
0
  check_ssl_ctx_x509_method(ctx);
450
0
  return ctx->param;
451
0
}
452
453
0
X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) {
454
0
  check_ssl_x509_method(ssl);
455
0
  if (!ssl->config) {
456
0
    assert(ssl->config);
457
0
    return 0;
458
0
  }
459
0
  return ssl->config->param;
460
0
}
461
462
0
int SSL_get_verify_depth(const SSL *ssl) {
463
0
  check_ssl_x509_method(ssl);
464
0
  if (!ssl->config) {
465
0
    assert(ssl->config);
466
0
    return 0;
467
0
  }
468
0
  return X509_VERIFY_PARAM_get_depth(ssl->config->param);
469
0
}
470
471
0
int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) {
472
0
  check_ssl_x509_method(ssl);
473
0
  if (!ssl->config) {
474
0
    assert(ssl->config);
475
0
    return 0;
476
0
  }
477
0
  return ssl->config->verify_callback;
478
0
}
479
480
0
int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) {
481
0
  check_ssl_ctx_x509_method(ctx);
482
0
  return ctx->verify_mode;
483
0
}
484
485
0
int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) {
486
0
  check_ssl_ctx_x509_method(ctx);
487
0
  return X509_VERIFY_PARAM_get_depth(ctx->param);
488
0
}
489
490
int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
491
0
    int ok, X509_STORE_CTX *store_ctx) {
492
0
  check_ssl_ctx_x509_method(ctx);
493
0
  return ctx->default_verify_callback;
494
0
}
495
496
void SSL_set_verify(SSL *ssl, int mode,
497
1.85k
                    int (*callback)(int ok, X509_STORE_CTX *store_ctx)) {
498
1.85k
  check_ssl_x509_method(ssl);
499
1.85k
  if (!ssl->config) {
500
0
    return;
501
0
  }
502
1.85k
  ssl->config->verify_mode = mode;
503
1.85k
  if (callback != NULL) {
504
0
    ssl->config->verify_callback = callback;
505
0
  }
506
1.85k
}
507
508
0
void SSL_set_verify_depth(SSL *ssl, int depth) {
509
0
  check_ssl_x509_method(ssl);
510
0
  if (!ssl->config) {
511
0
    return;
512
0
  }
513
0
  X509_VERIFY_PARAM_set_depth(ssl->config->param, depth);
514
0
}
515
516
void SSL_CTX_set_cert_verify_callback(
517
2
    SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *store_ctx, void *arg), void *arg) {
518
2
  check_ssl_ctx_x509_method(ctx);
519
2
  ctx->app_verify_callback = cb;
520
2
  ctx->app_verify_arg = arg;
521
2
}
522
523
void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
524
0
                        int (*cb)(int, X509_STORE_CTX *)) {
525
0
  check_ssl_ctx_x509_method(ctx);
526
0
  ctx->verify_mode = mode;
527
0
  ctx->default_verify_callback = cb;
528
0
}
529
530
0
void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) {
531
0
  check_ssl_ctx_x509_method(ctx);
532
0
  X509_VERIFY_PARAM_set_depth(ctx->param, depth);
533
0
}
534
535
0
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) {
536
0
  check_ssl_ctx_x509_method(ctx);
537
0
  return X509_STORE_set_default_paths(ctx->cert_store);
538
0
}
539
540
int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file,
541
0
                                  const char *ca_dir) {
542
0
  check_ssl_ctx_x509_method(ctx);
543
0
  return X509_STORE_load_locations(ctx->cert_store, ca_file, ca_dir);
544
0
}
545
546
0
long SSL_get_verify_result(const SSL *ssl) {
547
0
  check_ssl_x509_method(ssl);
548
0
  SSL_SESSION *session = SSL_get_session(ssl);
549
0
  if (session == NULL) {
550
0
    return X509_V_ERR_INVALID_CALL;
551
0
  }
552
0
  return session->verify_result;
553
0
}
554
555
0
X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
556
0
  check_ssl_ctx_x509_method(ctx);
557
0
  return ctx->cert_store;
558
0
}
559
560
0
void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) {
561
0
  check_ssl_ctx_x509_method(ctx);
562
0
  X509_STORE_free(ctx->cert_store);
563
0
  ctx->cert_store = store;
564
0
}
565
566
2
static int ssl_use_certificate(CERT *cert, X509 *x) {
567
2
  if (x == NULL) {
568
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
569
0
    return 0;
570
0
  }
571
572
2
  UniquePtr<CRYPTO_BUFFER> buffer = x509_to_buffer(x);
573
2
  if (!buffer) {
574
0
    return 0;
575
0
  }
576
577
2
  return ssl_set_cert(cert, std::move(buffer));
578
2
}
579
580
0
int SSL_use_certificate(SSL *ssl, X509 *x) {
581
0
  check_ssl_x509_method(ssl);
582
0
  if (!ssl->config) {
583
0
    return 0;
584
0
  }
585
0
  return ssl_use_certificate(ssl->config->cert.get(), x);
586
0
}
587
588
2
int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) {
589
2
  check_ssl_ctx_x509_method(ctx);
590
2
  return ssl_use_certificate(ctx->cert.get(), x);
591
2
}
592
593
// ssl_cert_cache_leaf_cert sets |cert->x509_leaf|, if currently NULL, from the
594
// first element of |cert->chain|.
595
0
static int ssl_cert_cache_leaf_cert(CERT *cert) {
596
0
  assert(cert->x509_method);
597
598
0
  const SSL_CREDENTIAL *cred = cert->legacy_credential.get();
599
0
  if (cert->x509_leaf != NULL || cred->chain == NULL) {
600
0
    return 1;
601
0
  }
602
603
0
  CRYPTO_BUFFER *leaf = sk_CRYPTO_BUFFER_value(cred->chain.get(), 0);
604
0
  if (!leaf) {
605
0
    return 1;
606
0
  }
607
608
0
  cert->x509_leaf = X509_parse_from_buffer(leaf);
609
0
  return cert->x509_leaf != NULL;
610
0
}
611
612
0
static X509 *ssl_cert_get0_leaf(CERT *cert) {
613
0
  if (cert->x509_leaf == NULL &&  //
614
0
      !ssl_cert_cache_leaf_cert(cert)) {
615
0
    return NULL;
616
0
  }
617
618
0
  return cert->x509_leaf;
619
0
}
620
621
0
X509 *SSL_get_certificate(const SSL *ssl) {
622
0
  check_ssl_x509_method(ssl);
623
0
  if (!ssl->config) {
624
0
    assert(ssl->config);
625
0
    return 0;
626
0
  }
627
0
  return ssl_cert_get0_leaf(ssl->config->cert.get());
628
0
}
629
630
0
X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
631
0
  check_ssl_ctx_x509_method(ctx);
632
0
  MutexWriteLock lock(const_cast<CRYPTO_MUTEX *>(&ctx->lock));
633
0
  return ssl_cert_get0_leaf(ctx->cert.get());
634
0
}
635
636
0
static int ssl_cert_add1_chain_cert(CERT *cert, X509 *x509) {
637
0
  assert(cert->x509_method);
638
639
0
  UniquePtr<CRYPTO_BUFFER> buffer = x509_to_buffer(x509);
640
0
  if (!buffer ||
641
0
      !cert->legacy_credential->AppendIntermediateCert(std::move(buffer))) {
642
0
    return 0;
643
0
  }
644
645
0
  ssl_crypto_x509_cert_flush_cached_chain(cert);
646
0
  return 1;
647
0
}
648
649
0
static int ssl_cert_add0_chain_cert(CERT *cert, X509 *x509) {
650
0
  if (!ssl_cert_add1_chain_cert(cert, x509)) {
651
0
    return 0;
652
0
  }
653
654
0
  X509_free(cert->x509_stash);
655
0
  cert->x509_stash = x509;
656
0
  return 1;
657
0
}
658
659
0
int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) {
660
0
  check_ssl_ctx_x509_method(ctx);
661
0
  if (!ssl_cert_set1_chain(ctx->cert.get(), chain)) {
662
0
    return 0;
663
0
  }
664
0
  sk_X509_pop_free(chain, X509_free);
665
0
  return 1;
666
0
}
667
668
0
int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) {
669
0
  check_ssl_ctx_x509_method(ctx);
670
0
  return ssl_cert_set1_chain(ctx->cert.get(), chain);
671
0
}
672
673
0
int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain) {
674
0
  check_ssl_x509_method(ssl);
675
0
  if (!ssl->config) {
676
0
    return 0;
677
0
  }
678
0
  if (!ssl_cert_set1_chain(ssl->config->cert.get(), chain)) {
679
0
    return 0;
680
0
  }
681
0
  sk_X509_pop_free(chain, X509_free);
682
0
  return 1;
683
0
}
684
685
0
int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain) {
686
0
  check_ssl_x509_method(ssl);
687
0
  if (!ssl->config) {
688
0
    return 0;
689
0
  }
690
0
  return ssl_cert_set1_chain(ssl->config->cert.get(), chain);
691
0
}
692
693
0
int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509) {
694
0
  check_ssl_ctx_x509_method(ctx);
695
0
  return ssl_cert_add0_chain_cert(ctx->cert.get(), x509);
696
0
}
697
698
0
int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509) {
699
0
  check_ssl_ctx_x509_method(ctx);
700
0
  return ssl_cert_add1_chain_cert(ctx->cert.get(), x509);
701
0
}
702
703
0
int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509) {
704
0
  check_ssl_ctx_x509_method(ctx);
705
0
  return SSL_CTX_add0_chain_cert(ctx, x509);
706
0
}
707
708
0
int SSL_add0_chain_cert(SSL *ssl, X509 *x509) {
709
0
  check_ssl_x509_method(ssl);
710
0
  if (!ssl->config) {
711
0
    return 0;
712
0
  }
713
0
  return ssl_cert_add0_chain_cert(ssl->config->cert.get(), x509);
714
0
}
715
716
0
int SSL_add1_chain_cert(SSL *ssl, X509 *x509) {
717
0
  check_ssl_x509_method(ssl);
718
0
  if (!ssl->config) {
719
0
    return 0;
720
0
  }
721
0
  return ssl_cert_add1_chain_cert(ssl->config->cert.get(), x509);
722
0
}
723
724
0
int SSL_CTX_clear_chain_certs(SSL_CTX *ctx) {
725
0
  check_ssl_ctx_x509_method(ctx);
726
0
  return SSL_CTX_set0_chain(ctx, NULL);
727
0
}
728
729
0
int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx) {
730
0
  check_ssl_ctx_x509_method(ctx);
731
0
  return SSL_CTX_clear_chain_certs(ctx);
732
0
}
733
734
0
int SSL_clear_chain_certs(SSL *ssl) {
735
0
  check_ssl_x509_method(ssl);
736
0
  return SSL_set0_chain(ssl, NULL);
737
0
}
738
739
// ssl_cert_cache_chain_certs fills in |cert->x509_chain| from elements 1.. of
740
// |cert->chain|.
741
0
static int ssl_cert_cache_chain_certs(CERT *cert) {
742
0
  assert(cert->x509_method);
743
744
0
  const SSL_CREDENTIAL *cred = cert->legacy_credential.get();
745
0
  if (cert->x509_chain != nullptr || cred->chain == nullptr ||
746
0
      sk_CRYPTO_BUFFER_num(cred->chain.get()) < 2) {
747
0
    return 1;
748
0
  }
749
750
0
  UniquePtr<STACK_OF(X509)> chain(sk_X509_new_null());
751
0
  if (!chain) {
752
0
    return 0;
753
0
  }
754
755
0
  for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cred->chain.get()); i++) {
756
0
    CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(cred->chain.get(), i);
757
0
    UniquePtr<X509> x509(X509_parse_from_buffer(buffer));
758
0
    if (!x509 ||  //
759
0
        !PushToStack(chain.get(), std::move(x509))) {
760
0
      return 0;
761
0
    }
762
0
  }
763
764
0
  cert->x509_chain = chain.release();
765
0
  return 1;
766
0
}
767
768
0
int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, STACK_OF(X509) **out_chain) {
769
0
  check_ssl_ctx_x509_method(ctx);
770
0
  MutexWriteLock lock(const_cast<CRYPTO_MUTEX *>(&ctx->lock));
771
0
  if (!ssl_cert_cache_chain_certs(ctx->cert.get())) {
772
0
    *out_chain = NULL;
773
0
    return 0;
774
0
  }
775
776
0
  *out_chain = ctx->cert->x509_chain;
777
0
  return 1;
778
0
}
779
780
int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx,
781
0
                                  STACK_OF(X509) **out_chain) {
782
0
  return SSL_CTX_get0_chain_certs(ctx, out_chain);
783
0
}
784
785
0
int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) {
786
0
  check_ssl_x509_method(ssl);
787
0
  if (!ssl->config) {
788
0
    assert(ssl->config);
789
0
    return 0;
790
0
  }
791
0
  if (!ssl_cert_cache_chain_certs(ssl->config->cert.get())) {
792
0
    *out_chain = NULL;
793
0
    return 0;
794
0
  }
795
796
0
  *out_chain = ssl->config->cert->x509_chain;
797
0
  return 1;
798
0
}
799
800
0
SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out) {
801
0
  uint8_t *data;
802
0
  size_t len;
803
0
  if (!BIO_read_asn1(bio, &data, &len, 1024 * 1024)) {
804
0
    return 0;
805
0
  }
806
0
  bssl::UniquePtr<uint8_t> free_data(data);
807
0
  const uint8_t *ptr = data;
808
0
  return d2i_SSL_SESSION(out, &ptr, static_cast<long>(len));
809
0
}
810
811
0
int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session) {
812
0
  uint8_t *data;
813
0
  size_t len;
814
0
  if (!SSL_SESSION_to_bytes(session, &data, &len)) {
815
0
    return 0;
816
0
  }
817
0
  bssl::UniquePtr<uint8_t> free_data(data);
818
0
  return BIO_write_all(bio, data, len);
819
0
}
820
821
IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
822
823
0
SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) {
824
0
  if (length < 0) {
825
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
826
0
    return NULL;
827
0
  }
828
829
0
  CBS cbs;
830
0
  CBS_init(&cbs, *pp, length);
831
832
0
  UniquePtr<SSL_SESSION> ret = SSL_SESSION_parse(&cbs, &ssl_crypto_x509_method,
833
0
                                                 NULL /* no buffer pool */);
834
0
  if (!ret) {
835
0
    return NULL;
836
0
  }
837
838
0
  if (a) {
839
0
    SSL_SESSION_free(*a);
840
0
    *a = ret.get();
841
0
  }
842
0
  *pp = CBS_data(&cbs);
843
0
  return ret.release();
844
0
}
845
846
0
STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list) {
847
  // TODO(https://crbug.com/boringssl/407): |X509_NAME_dup| should be const.
848
0
  auto name_dup = [](const X509_NAME *name) {
849
0
    return X509_NAME_dup(const_cast<X509_NAME *>(name));
850
0
  };
851
0
  return sk_X509_NAME_deep_copy(list, name_dup, X509_NAME_free);
852
0
}
853
854
static void set_client_CA_list(UniquePtr<STACK_OF(CRYPTO_BUFFER)> *ca_list,
855
                               const STACK_OF(X509_NAME) *name_list,
856
0
                               CRYPTO_BUFFER_POOL *pool) {
857
0
  UniquePtr<STACK_OF(CRYPTO_BUFFER)> buffers(sk_CRYPTO_BUFFER_new_null());
858
0
  if (!buffers) {
859
0
    return;
860
0
  }
861
862
0
  for (X509_NAME *name : name_list) {
863
0
    uint8_t *outp = NULL;
864
0
    int len = i2d_X509_NAME(name, &outp);
865
0
    if (len < 0) {
866
0
      return;
867
0
    }
868
869
0
    UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(outp, len, pool));
870
0
    OPENSSL_free(outp);
871
0
    if (!buffer || !PushToStack(buffers.get(), std::move(buffer))) {
872
0
      return;
873
0
    }
874
0
  }
875
876
0
  *ca_list = std::move(buffers);
877
0
}
878
879
0
void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list) {
880
0
  check_ssl_x509_method(ssl);
881
0
  if (!ssl->config) {
882
0
    return;
883
0
  }
884
0
  ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl->config.get());
885
0
  set_client_CA_list(&ssl->config->client_CA, name_list, ssl->ctx->pool);
886
0
  sk_X509_NAME_pop_free(name_list, X509_NAME_free);
887
0
}
888
889
0
void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) {
890
0
  check_ssl_ctx_x509_method(ctx);
891
0
  ctx->x509_method->ssl_ctx_flush_cached_client_CA(ctx);
892
0
  set_client_CA_list(&ctx->client_CA, name_list, ctx->pool);
893
0
  sk_X509_NAME_pop_free(name_list, X509_NAME_free);
894
0
}
895
896
static STACK_OF(X509_NAME) *buffer_names_to_x509(
897
0
    const STACK_OF(CRYPTO_BUFFER) *names, STACK_OF(X509_NAME) **cached) {
898
0
  if (names == NULL) {
899
0
    return NULL;
900
0
  }
901
902
0
  if (*cached != NULL) {
903
0
    return *cached;
904
0
  }
905
906
0
  UniquePtr<STACK_OF(X509_NAME)> new_cache(sk_X509_NAME_new_null());
907
0
  if (!new_cache) {
908
0
    return NULL;
909
0
  }
910
911
0
  for (const CRYPTO_BUFFER *buffer : names) {
912
0
    const uint8_t *inp = CRYPTO_BUFFER_data(buffer);
913
0
    UniquePtr<X509_NAME> name(
914
0
        d2i_X509_NAME(nullptr, &inp, CRYPTO_BUFFER_len(buffer)));
915
0
    if (!name ||
916
0
        inp != CRYPTO_BUFFER_data(buffer) + CRYPTO_BUFFER_len(buffer) ||
917
0
        !PushToStack(new_cache.get(), std::move(name))) {
918
0
      return NULL;
919
0
    }
920
0
  }
921
922
0
  *cached = new_cache.release();
923
0
  return *cached;
924
0
}
925
926
0
STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl) {
927
0
  check_ssl_x509_method(ssl);
928
0
  if (!ssl->config) {
929
0
    assert(ssl->config);
930
0
    return NULL;
931
0
  }
932
  // For historical reasons, this function is used both to query configuration
933
  // state on a server as well as handshake state on a client. However, whether
934
  // |ssl| is a client or server is not known until explicitly configured with
935
  // |SSL_set_connect_state|. If |do_handshake| is NULL, |ssl| is in an
936
  // indeterminate mode and |ssl->server| is unset.
937
0
  if (ssl->do_handshake != NULL && !ssl->server) {
938
0
    if (ssl->s3->hs != NULL) {
939
0
      return buffer_names_to_x509(ssl->s3->hs->ca_names.get(),
940
0
                                  &ssl->s3->hs->cached_x509_ca_names);
941
0
    }
942
943
0
    return NULL;
944
0
  }
945
946
0
  if (ssl->config->client_CA != NULL) {
947
0
    return buffer_names_to_x509(
948
0
        ssl->config->client_CA.get(),
949
0
        (STACK_OF(X509_NAME) **)&ssl->config->cached_x509_client_CA);
950
0
  }
951
0
  return SSL_CTX_get_client_CA_list(ssl->ctx.get());
952
0
}
953
954
0
STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) {
955
0
  check_ssl_ctx_x509_method(ctx);
956
  // This is a logically const operation that may be called on multiple threads,
957
  // so it needs to lock around updating |cached_x509_client_CA|.
958
0
  MutexWriteLock lock(const_cast<CRYPTO_MUTEX *>(&ctx->lock));
959
0
  return buffer_names_to_x509(
960
0
      ctx->client_CA.get(),
961
0
      const_cast<STACK_OF(X509_NAME) **>(&ctx->cached_x509_client_CA));
962
0
}
963
964
static int add_client_CA(UniquePtr<STACK_OF(CRYPTO_BUFFER)> *names, X509 *x509,
965
0
                         CRYPTO_BUFFER_POOL *pool) {
966
0
  if (x509 == NULL) {
967
0
    return 0;
968
0
  }
969
970
0
  uint8_t *outp = NULL;
971
0
  int len = i2d_X509_NAME(X509_get_subject_name(x509), &outp);
972
0
  if (len < 0) {
973
0
    return 0;
974
0
  }
975
976
0
  UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(outp, len, pool));
977
0
  OPENSSL_free(outp);
978
0
  if (!buffer) {
979
0
    return 0;
980
0
  }
981
982
0
  int alloced = 0;
983
0
  if (*names == nullptr) {
984
0
    names->reset(sk_CRYPTO_BUFFER_new_null());
985
0
    alloced = 1;
986
987
0
    if (*names == NULL) {
988
0
      return 0;
989
0
    }
990
0
  }
991
992
0
  if (!PushToStack(names->get(), std::move(buffer))) {
993
0
    if (alloced) {
994
0
      names->reset();
995
0
    }
996
0
    return 0;
997
0
  }
998
999
0
  return 1;
1000
0
}
1001
1002
0
int SSL_add_client_CA(SSL *ssl, X509 *x509) {
1003
0
  check_ssl_x509_method(ssl);
1004
0
  if (!ssl->config) {
1005
0
    return 0;
1006
0
  }
1007
0
  if (!add_client_CA(&ssl->config->client_CA, x509, ssl->ctx->pool)) {
1008
0
    return 0;
1009
0
  }
1010
1011
0
  ssl_crypto_x509_ssl_flush_cached_client_CA(ssl->config.get());
1012
0
  return 1;
1013
0
}
1014
1015
0
int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509) {
1016
0
  check_ssl_ctx_x509_method(ctx);
1017
0
  if (!add_client_CA(&ctx->client_CA, x509, ctx->pool)) {
1018
0
    return 0;
1019
0
  }
1020
1021
0
  ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(ctx);
1022
0
  return 1;
1023
0
}
1024
1025
0
static int do_client_cert_cb(SSL *ssl, void *arg) {
1026
  // Should only be called during handshake, but check to be sure.
1027
0
  BSSL_CHECK(ssl->config);
1028
1029
0
  if (ssl->config->cert->legacy_credential->IsComplete() ||
1030
0
      ssl->ctx->client_cert_cb == nullptr) {
1031
0
    return 1;
1032
0
  }
1033
1034
0
  X509 *x509 = NULL;
1035
0
  EVP_PKEY *pkey = NULL;
1036
0
  int ret = ssl->ctx->client_cert_cb(ssl, &x509, &pkey);
1037
0
  if (ret < 0) {
1038
0
    return -1;
1039
0
  }
1040
0
  UniquePtr<X509> free_x509(x509);
1041
0
  UniquePtr<EVP_PKEY> free_pkey(pkey);
1042
1043
0
  if (ret != 0) {
1044
0
    if (!SSL_use_certificate(ssl, x509) ||  //
1045
0
        !SSL_use_PrivateKey(ssl, pkey)) {
1046
0
      return 0;
1047
0
    }
1048
0
  }
1049
1050
0
  return 1;
1051
0
}
1052
1053
void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
1054
                                int (*cb)(SSL *ssl, X509 **out_x509,
1055
0
                                          EVP_PKEY **out_pkey)) {
1056
0
  check_ssl_ctx_x509_method(ctx);
1057
  // Emulate the old client certificate callback with the new one.
1058
0
  SSL_CTX_set_cert_cb(ctx, do_client_cert_cb, NULL);
1059
0
  ctx->client_cert_cb = cb;
1060
0
}
1061
1062
static int set_cert_store(X509_STORE **store_ptr, X509_STORE *new_store,
1063
0
                          int take_ref) {
1064
0
  X509_STORE_free(*store_ptr);
1065
0
  *store_ptr = new_store;
1066
1067
0
  if (new_store != NULL && take_ref) {
1068
0
    X509_STORE_up_ref(new_store);
1069
0
  }
1070
1071
0
  return 1;
1072
0
}
1073
1074
819
int SSL_get_ex_data_X509_STORE_CTX_idx(void) {
1075
  // The ex_data index to go from |X509_STORE_CTX| to |SSL| always uses the
1076
  // reserved app_data slot. Before ex_data was introduced, app_data was used.
1077
  // Avoid breaking any software which assumes |X509_STORE_CTX_get_app_data|
1078
  // works.
1079
819
  return 0;
1080
819
}
1081
1082
0
int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) {
1083
0
  check_ssl_ctx_x509_method(ctx);
1084
0
  return set_cert_store(&ctx->cert->verify_store, store, 0);
1085
0
}
1086
1087
0
int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) {
1088
0
  check_ssl_ctx_x509_method(ctx);
1089
0
  return set_cert_store(&ctx->cert->verify_store, store, 1);
1090
0
}
1091
1092
0
int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store) {
1093
0
  check_ssl_x509_method(ssl);
1094
0
  if (!ssl->config) {
1095
0
    return 0;
1096
0
  }
1097
0
  return set_cert_store(&ssl->config->cert->verify_store, store, 0);
1098
0
}
1099
1100
0
int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store) {
1101
0
  check_ssl_x509_method(ssl);
1102
0
  if (!ssl->config) {
1103
0
    return 0;
1104
0
  }
1105
0
  return set_cert_store(&ssl->config->cert->verify_store, store, 1);
1106
0
}
1107
1108
0
int SSL_set1_host(SSL *ssl, const char *hostname) {
1109
0
  check_ssl_x509_method(ssl);
1110
0
  if (!ssl->config) {
1111
0
    return 0;
1112
0
  }
1113
0
  return X509_VERIFY_PARAM_set1_host(ssl->config->param, hostname,
1114
0
                                     strlen(hostname));
1115
0
}
1116
1117
0
void SSL_set_hostflags(SSL *ssl, unsigned flags) {
1118
0
  check_ssl_x509_method(ssl);
1119
0
  if (!ssl->config) {
1120
0
    return;
1121
0
  }
1122
0
  X509_VERIFY_PARAM_set_hostflags(ssl->config->param, flags);
1123
0
}
1124
1125
0
int SSL_alert_from_verify_result(long result) {
1126
0
  switch (result) {
1127
0
    case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1128
0
    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1129
0
    case X509_V_ERR_INVALID_CA:
1130
0
    case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1131
0
    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1132
0
    case X509_V_ERR_UNABLE_TO_GET_CRL:
1133
0
    case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
1134
0
    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1135
0
    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1136
0
    case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1137
0
      return SSL_AD_UNKNOWN_CA;
1138
1139
0
    case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1140
0
    case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
1141
0
    case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
1142
0
    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1143
0
    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
1144
0
    case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
1145
0
    case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
1146
0
    case X509_V_ERR_CERT_UNTRUSTED:
1147
0
    case X509_V_ERR_CERT_REJECTED:
1148
0
    case X509_V_ERR_HOSTNAME_MISMATCH:
1149
0
    case X509_V_ERR_EMAIL_MISMATCH:
1150
0
    case X509_V_ERR_IP_ADDRESS_MISMATCH:
1151
0
      return SSL_AD_BAD_CERTIFICATE;
1152
1153
0
    case X509_V_ERR_CERT_SIGNATURE_FAILURE:
1154
0
    case X509_V_ERR_CRL_SIGNATURE_FAILURE:
1155
0
      return SSL_AD_DECRYPT_ERROR;
1156
1157
0
    case X509_V_ERR_CERT_HAS_EXPIRED:
1158
0
    case X509_V_ERR_CERT_NOT_YET_VALID:
1159
0
    case X509_V_ERR_CRL_HAS_EXPIRED:
1160
0
    case X509_V_ERR_CRL_NOT_YET_VALID:
1161
0
      return SSL_AD_CERTIFICATE_EXPIRED;
1162
1163
0
    case X509_V_ERR_CERT_REVOKED:
1164
0
      return SSL_AD_CERTIFICATE_REVOKED;
1165
1166
0
    case X509_V_ERR_UNSPECIFIED:
1167
0
    case X509_V_ERR_OUT_OF_MEM:
1168
0
    case X509_V_ERR_INVALID_CALL:
1169
0
    case X509_V_ERR_STORE_LOOKUP:
1170
0
      return SSL_AD_INTERNAL_ERROR;
1171
1172
0
    case X509_V_ERR_APPLICATION_VERIFICATION:
1173
0
      return SSL_AD_HANDSHAKE_FAILURE;
1174
1175
0
    case X509_V_ERR_INVALID_PURPOSE:
1176
0
      return SSL_AD_UNSUPPORTED_CERTIFICATE;
1177
1178
0
    default:
1179
0
      return SSL_AD_CERTIFICATE_UNKNOWN;
1180
0
  }
1181
0
}