Coverage Report

Created: 2025-06-24 07:00

/src/boringssl/ssl/ssl_cert.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
//
4
// Licensed under the Apache License, Version 2.0 (the "License");
5
// you may not use this file except in compliance with the License.
6
// You may obtain a copy of the License at
7
//
8
//     https://www.apache.org/licenses/LICENSE-2.0
9
//
10
// Unless required by applicable law or agreed to in writing, software
11
// distributed under the License is distributed on an "AS IS" BASIS,
12
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
// See the License for the specific language governing permissions and
14
// limitations under the License.
15
16
#include <openssl/ssl.h>
17
18
#include <assert.h>
19
#include <limits.h>
20
#include <string.h>
21
22
#include <utility>
23
24
#include <openssl/bn.h>
25
#include <openssl/bytestring.h>
26
#include <openssl/ec_key.h>
27
#include <openssl/err.h>
28
#include <openssl/mem.h>
29
#include <openssl/sha.h>
30
#include <openssl/x509.h>
31
32
#include "../crypto/internal.h"
33
#include "internal.h"
34
35
36
BSSL_NAMESPACE_BEGIN
37
38
CERT::CERT(const SSL_X509_METHOD *x509_method_arg)
39
126k
    : legacy_credential(MakeUnique<SSL_CREDENTIAL>(SSLCredentialType::kX509)),
40
126k
      x509_method(x509_method_arg) {}
41
42
126k
CERT::~CERT() { x509_method->cert_free(this); }
43
44
121k
UniquePtr<CERT> ssl_cert_dup(CERT *cert) {
45
121k
  UniquePtr<CERT> ret = MakeUnique<CERT>(cert->x509_method);
46
121k
  if (!ret) {
47
0
    return nullptr;
48
0
  }
49
50
  // TODO(crbug.com/boringssl/431): This should just be |CopyFrom|.
51
121k
  for (const auto &cred : cert->credentials) {
52
0
    if (!ret->credentials.Push(UpRef(cred))) {
53
0
      return nullptr;
54
0
    }
55
0
  }
56
57
  // |legacy_credential| is mutable, so it must be copied. We cannot simply
58
  // bump the reference count.
59
121k
  ret->legacy_credential = cert->legacy_credential->Dup();
60
121k
  if (ret->legacy_credential == nullptr) {
61
0
    return nullptr;
62
0
  }
63
64
121k
  ret->cert_cb = cert->cert_cb;
65
121k
  ret->cert_cb_arg = cert->cert_cb_arg;
66
67
121k
  ret->x509_method->cert_dup(ret.get(), cert);
68
69
121k
  ret->sid_ctx = cert->sid_ctx;
70
121k
  return ret;
71
121k
}
72
73
static void ssl_cert_set_cert_cb(CERT *cert, int (*cb)(SSL *ssl, void *arg),
74
0
                                 void *arg) {
75
0
  cert->cert_cb = cb;
76
0
  cert->cert_cb_arg = arg;
77
0
}
78
79
static int cert_set_chain_and_key(
80
    CERT *cert, CRYPTO_BUFFER *const *certs, size_t num_certs,
81
0
    EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method) {
82
0
  if (num_certs == 0 ||  //
83
0
      (privkey == NULL && privkey_method == NULL)) {
84
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
85
0
    return 0;
86
0
  }
87
88
0
  if (privkey != NULL && privkey_method != NULL) {
89
0
    OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD);
90
0
    return 0;
91
0
  }
92
93
0
  cert->legacy_credential->ClearCertAndKey();
94
0
  if (!SSL_CREDENTIAL_set1_cert_chain(cert->legacy_credential.get(), certs,
95
0
                                      num_certs)) {
96
0
    return 0;
97
0
  }
98
99
0
  cert->x509_method->cert_flush_cached_leaf(cert);
100
0
  cert->x509_method->cert_flush_cached_chain(cert);
101
102
0
  return privkey != nullptr
103
0
             ? SSL_CREDENTIAL_set1_private_key(cert->legacy_credential.get(),
104
0
                                               privkey)
105
0
             : SSL_CREDENTIAL_set_private_key_method(
106
0
                   cert->legacy_credential.get(), privkey_method);
107
0
}
108
109
6.95k
bool ssl_set_cert(CERT *cert, UniquePtr<CRYPTO_BUFFER> buffer) {
110
  // Don't fail for a cert/key mismatch, just free the current private key.
111
  // (When switching to a different keypair, the caller should switch the
112
  // certificate, then the key.)
113
6.95k
  if (!cert->legacy_credential->SetLeafCert(std::move(buffer),
114
6.95k
                                            /*discard_key_on_mismatch=*/true)) {
115
0
    return false;
116
0
  }
117
118
6.95k
  cert->x509_method->cert_flush_cached_leaf(cert);
119
6.95k
  return true;
120
6.95k
}
121
122
bool ssl_parse_cert_chain(uint8_t *out_alert,
123
                          UniquePtr<STACK_OF(CRYPTO_BUFFER)> *out_chain,
124
                          UniquePtr<EVP_PKEY> *out_pubkey,
125
                          uint8_t *out_leaf_sha256, CBS *cbs,
126
59.6k
                          CRYPTO_BUFFER_POOL *pool) {
127
59.6k
  out_chain->reset();
128
59.6k
  out_pubkey->reset();
129
130
59.6k
  CBS certificate_list;
131
59.6k
  if (!CBS_get_u24_length_prefixed(cbs, &certificate_list)) {
132
117
    *out_alert = SSL_AD_DECODE_ERROR;
133
117
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
134
117
    return false;
135
117
  }
136
137
59.5k
  if (CBS_len(&certificate_list) == 0) {
138
53
    return true;
139
53
  }
140
141
59.4k
  UniquePtr<STACK_OF(CRYPTO_BUFFER)> chain(sk_CRYPTO_BUFFER_new_null());
142
59.4k
  if (!chain) {
143
0
    *out_alert = SSL_AD_INTERNAL_ERROR;
144
0
    return false;
145
0
  }
146
147
59.4k
  UniquePtr<EVP_PKEY> pubkey;
148
117k
  while (CBS_len(&certificate_list) > 0) {
149
60.0k
    CBS certificate;
150
60.0k
    if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) ||
151
60.0k
        CBS_len(&certificate) == 0) {
152
94
      *out_alert = SSL_AD_DECODE_ERROR;
153
94
      OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
154
94
      return false;
155
94
    }
156
157
59.9k
    if (sk_CRYPTO_BUFFER_num(chain.get()) == 0) {
158
59.4k
      pubkey = ssl_cert_parse_pubkey(&certificate);
159
59.4k
      if (!pubkey) {
160
1.84k
        *out_alert = SSL_AD_DECODE_ERROR;
161
1.84k
        return false;
162
1.84k
      }
163
164
      // Retain the hash of the leaf certificate if requested.
165
57.6k
      if (out_leaf_sha256 != NULL) {
166
0
        SHA256(CBS_data(&certificate), CBS_len(&certificate), out_leaf_sha256);
167
0
      }
168
57.6k
    }
169
170
58.0k
    UniquePtr<CRYPTO_BUFFER> buf(
171
58.0k
        CRYPTO_BUFFER_new_from_CBS(&certificate, pool));
172
58.0k
    if (!buf ||  //
173
58.0k
        !PushToStack(chain.get(), std::move(buf))) {
174
0
      *out_alert = SSL_AD_INTERNAL_ERROR;
175
0
      return false;
176
0
    }
177
58.0k
  }
178
179
57.5k
  *out_chain = std::move(chain);
180
57.5k
  *out_pubkey = std::move(pubkey);
181
57.5k
  return true;
182
59.4k
}
183
184
// ssl_cert_skip_to_spki parses a DER-encoded, X.509 certificate from |in| and
185
// positions |*out_tbs_cert| to cover the TBSCertificate, starting at the
186
// subjectPublicKeyInfo.
187
122k
static bool ssl_cert_skip_to_spki(const CBS *in, CBS *out_tbs_cert) {
188
  /* From RFC 5280, section 4.1
189
   *    Certificate  ::=  SEQUENCE  {
190
   *      tbsCertificate       TBSCertificate,
191
   *      signatureAlgorithm   AlgorithmIdentifier,
192
   *      signatureValue       BIT STRING  }
193
194
   * TBSCertificate  ::=  SEQUENCE  {
195
   *      version         [0]  EXPLICIT Version DEFAULT v1,
196
   *      serialNumber         CertificateSerialNumber,
197
   *      signature            AlgorithmIdentifier,
198
   *      issuer               Name,
199
   *      validity             Validity,
200
   *      subject              Name,
201
   *      subjectPublicKeyInfo SubjectPublicKeyInfo,
202
   *      ... } */
203
122k
  CBS buf = *in;
204
205
122k
  CBS toplevel;
206
122k
  if (!CBS_get_asn1(&buf, &toplevel, CBS_ASN1_SEQUENCE) ||          //
207
122k
      CBS_len(&buf) != 0 ||                                         //
208
122k
      !CBS_get_asn1(&toplevel, out_tbs_cert, CBS_ASN1_SEQUENCE) ||  //
209
      // version
210
122k
      !CBS_get_optional_asn1(
211
122k
          out_tbs_cert, NULL, NULL,
212
122k
          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||  //
213
214
      // serialNumber
215
122k
      !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_INTEGER) ||
216
      // signature algorithm
217
122k
      !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) ||
218
      // issuer
219
122k
      !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) ||
220
      // validity
221
122k
      !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) ||
222
      // subject
223
122k
      !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE)) {
224
145
    return false;
225
145
  }
226
227
121k
  return true;
228
122k
}
229
230
0
bool ssl_cert_extract_issuer(const CBS *in, CBS *out_dn) {
231
0
  CBS buf = *in;
232
233
0
  CBS toplevel;
234
0
  CBS cert;
235
0
  if (!CBS_get_asn1(&buf, &toplevel, CBS_ASN1_SEQUENCE) ||   //
236
0
      CBS_len(&buf) != 0 ||                                  //
237
0
      !CBS_get_asn1(&toplevel, &cert, CBS_ASN1_SEQUENCE) ||  //
238
      // version
239
0
      !CBS_get_optional_asn1(
240
0
          &cert, NULL, NULL,
241
0
          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||  //
242
      // serialNumber
243
0
      !CBS_get_asn1(&cert, NULL, CBS_ASN1_INTEGER) ||  //
244
      // signature algorithm
245
0
      !CBS_get_asn1(&cert, NULL, CBS_ASN1_SEQUENCE) ||  //
246
      // issuer
247
0
      !CBS_get_asn1_element(&cert, out_dn, CBS_ASN1_SEQUENCE)) {
248
0
    return false;
249
0
  }
250
0
  return true;
251
0
}
252
253
0
bool ssl_cert_matches_issuer(const CBS *in, const CBS *dn) {
254
0
  CBS issuer;
255
256
0
  if (!ssl_cert_extract_issuer(in, &issuer)) {
257
0
    return false;
258
0
  }
259
0
  return CBS_mem_equal(&issuer, CBS_data(dn), CBS_len(dn));
260
0
}
261
262
67.9k
UniquePtr<EVP_PKEY> ssl_cert_parse_pubkey(const CBS *in) {
263
67.9k
  CBS buf = *in, tbs_cert;
264
67.9k
  if (!ssl_cert_skip_to_spki(&buf, &tbs_cert)) {
265
145
    OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
266
145
    return nullptr;
267
145
  }
268
269
67.8k
  return UniquePtr<EVP_PKEY>(EVP_parse_public_key(&tbs_cert));
270
67.9k
}
271
272
bool ssl_compare_public_and_private_key(const EVP_PKEY *pubkey,
273
11.3k
                                        const EVP_PKEY *privkey) {
274
11.3k
  if (EVP_PKEY_is_opaque(privkey)) {
275
    // We cannot check an opaque private key and have to trust that it
276
    // matches.
277
0
    return true;
278
0
  }
279
280
11.3k
  switch (EVP_PKEY_cmp(pubkey, privkey)) {
281
11.3k
    case 1:
282
11.3k
      return true;
283
0
    case 0:
284
0
      OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
285
0
      return false;
286
0
    case -1:
287
0
      OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
288
0
      return false;
289
0
    case -2:
290
0
      OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
291
0
      return false;
292
11.3k
  }
293
294
0
  assert(0);
295
0
  return false;
296
0
}
297
298
54.1k
bool ssl_cert_check_key_usage(const CBS *in, enum ssl_key_usage_t bit) {
299
54.1k
  CBS buf = *in;
300
301
54.1k
  CBS tbs_cert, outer_extensions;
302
54.1k
  int has_extensions;
303
54.1k
  if (!ssl_cert_skip_to_spki(&buf, &tbs_cert) ||
304
      // subjectPublicKeyInfo
305
54.1k
      !CBS_get_asn1(&tbs_cert, NULL, CBS_ASN1_SEQUENCE) ||
306
      // issuerUniqueID
307
54.1k
      !CBS_get_optional_asn1(&tbs_cert, NULL, NULL,
308
54.1k
                             CBS_ASN1_CONTEXT_SPECIFIC | 1) ||
309
      // subjectUniqueID
310
54.1k
      !CBS_get_optional_asn1(&tbs_cert, NULL, NULL,
311
54.1k
                             CBS_ASN1_CONTEXT_SPECIFIC | 2) ||
312
54.1k
      !CBS_get_optional_asn1(
313
54.1k
          &tbs_cert, &outer_extensions, &has_extensions,
314
54.1k
          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3)) {
315
15
    OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
316
15
    return false;
317
15
  }
318
319
54.1k
  if (!has_extensions) {
320
204
    return true;
321
204
  }
322
323
53.9k
  CBS extensions;
324
53.9k
  if (!CBS_get_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) {
325
7
    OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
326
7
    return false;
327
7
  }
328
329
213k
  while (CBS_len(&extensions) > 0) {
330
159k
    CBS extension, oid, contents;
331
159k
    if (!CBS_get_asn1(&extensions, &extension, CBS_ASN1_SEQUENCE) ||
332
159k
        !CBS_get_asn1(&extension, &oid, CBS_ASN1_OBJECT) ||
333
159k
        (CBS_peek_asn1_tag(&extension, CBS_ASN1_BOOLEAN) &&
334
159k
         !CBS_get_asn1(&extension, NULL, CBS_ASN1_BOOLEAN)) ||
335
159k
        !CBS_get_asn1(&extension, &contents, CBS_ASN1_OCTETSTRING) ||
336
159k
        CBS_len(&extension) != 0) {
337
41
      OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
338
41
      return false;
339
41
    }
340
341
159k
    static const uint8_t kKeyUsageOID[3] = {0x55, 0x1d, 0x0f};
342
159k
    if (CBS_len(&oid) != sizeof(kKeyUsageOID) ||
343
159k
        OPENSSL_memcmp(CBS_data(&oid), kKeyUsageOID, sizeof(kKeyUsageOID)) !=
344
159k
            0) {
345
159k
      continue;
346
159k
    }
347
348
551
    CBS bit_string;
349
551
    if (!CBS_get_asn1(&contents, &bit_string, CBS_ASN1_BITSTRING) ||
350
551
        CBS_len(&contents) != 0) {
351
26
      OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
352
26
      return false;
353
26
    }
354
355
    // This is the KeyUsage extension. See
356
    // https://tools.ietf.org/html/rfc5280#section-4.2.1.3
357
525
    if (!CBS_is_valid_asn1_bitstring(&bit_string)) {
358
18
      OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
359
18
      return false;
360
18
    }
361
362
507
    if (!CBS_asn1_bitstring_has_bit(&bit_string, bit)) {
363
10
      OPENSSL_PUT_ERROR(SSL, SSL_R_KEY_USAGE_BIT_INCORRECT);
364
10
      return false;
365
10
    }
366
367
497
    return true;
368
507
  }
369
370
  // No KeyUsage extension found.
371
53.3k
  return true;
372
53.9k
}
373
374
UniquePtr<STACK_OF(CRYPTO_BUFFER)> SSL_parse_CA_list(SSL *ssl,
375
                                                     uint8_t *out_alert,
376
26.6k
                                                     CBS *cbs) {
377
26.6k
  CRYPTO_BUFFER_POOL *const pool = ssl->ctx->pool;
378
379
26.6k
  UniquePtr<STACK_OF(CRYPTO_BUFFER)> ret(sk_CRYPTO_BUFFER_new_null());
380
26.6k
  if (!ret) {
381
0
    *out_alert = SSL_AD_INTERNAL_ERROR;
382
0
    return nullptr;
383
0
  }
384
385
26.6k
  CBS child;
386
26.6k
  if (!CBS_get_u16_length_prefixed(cbs, &child)) {
387
25
    *out_alert = SSL_AD_DECODE_ERROR;
388
25
    OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH);
389
25
    return nullptr;
390
25
  }
391
392
36.1k
  while (CBS_len(&child) > 0) {
393
9.55k
    CBS distinguished_name;
394
9.55k
    if (!CBS_get_u16_length_prefixed(&child, &distinguished_name)) {
395
61
      *out_alert = SSL_AD_DECODE_ERROR;
396
61
      OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_TOO_LONG);
397
61
      return nullptr;
398
61
    }
399
400
9.49k
    UniquePtr<CRYPTO_BUFFER> buffer(
401
9.49k
        CRYPTO_BUFFER_new_from_CBS(&distinguished_name, pool));
402
9.49k
    if (!buffer ||  //
403
9.49k
        !PushToStack(ret.get(), std::move(buffer))) {
404
0
      *out_alert = SSL_AD_INTERNAL_ERROR;
405
0
      return nullptr;
406
0
    }
407
9.49k
  }
408
409
26.5k
  if (!ssl->ctx->x509_method->check_CA_list(ret.get())) {
410
605
    *out_alert = SSL_AD_DECODE_ERROR;
411
605
    OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
412
605
    return nullptr;
413
605
  }
414
415
25.9k
  return ret;
416
26.5k
}
417
418
static bool CA_names_non_empty(const STACK_OF(CRYPTO_BUFFER) *config_names,
419
65.0k
                               const STACK_OF(CRYPTO_BUFFER) *ctx_names) {
420
65.0k
  if (config_names != nullptr) {
421
0
    return sk_CRYPTO_BUFFER_num(config_names) > 0;
422
0
  }
423
65.0k
  if (ctx_names != nullptr) {
424
65.0k
    return sk_CRYPTO_BUFFER_num(ctx_names) > 0;
425
65.0k
  }
426
0
  return false;
427
65.0k
}
428
429
430
static bool marshal_CA_names(const STACK_OF(CRYPTO_BUFFER) *config_names,
431
                             const STACK_OF(CRYPTO_BUFFER) *ctx_names,
432
4.03k
                             CBB *cbb) {
433
4.03k
  const STACK_OF(CRYPTO_BUFFER) *names =
434
4.03k
      config_names == nullptr ? ctx_names : config_names;
435
4.03k
  CBB child, name_cbb;
436
437
4.03k
  if (!CBB_add_u16_length_prefixed(cbb, &child)) {
438
0
    return false;
439
0
  }
440
441
4.03k
  if (names == nullptr) {
442
0
    return CBB_flush(cbb);
443
0
  }
444
445
4.03k
  for (const CRYPTO_BUFFER *name : names) {
446
0
    if (!CBB_add_u16_length_prefixed(&child, &name_cbb) ||
447
0
        !CBB_add_bytes(&name_cbb, CRYPTO_BUFFER_data(name),
448
0
                       CRYPTO_BUFFER_len(name))) {
449
0
      return false;
450
0
    }
451
0
  }
452
453
4.03k
  return CBB_flush(cbb);
454
4.03k
}
455
456
244
bool ssl_has_client_CAs(const SSL_CONFIG *cfg) {
457
244
  return CA_names_non_empty(cfg->client_CA.get(),
458
244
                            cfg->ssl->ctx->client_CA.get());
459
244
}
460
461
64.7k
bool ssl_has_CA_names(const SSL_CONFIG *cfg) {
462
64.7k
  return CA_names_non_empty(cfg->CA_names.get(), cfg->ssl->ctx->CA_names.get());
463
64.7k
}
464
465
4.03k
bool ssl_add_client_CA_list(const SSL_HANDSHAKE *hs, CBB *cbb) {
466
4.03k
  return marshal_CA_names(hs->config->client_CA.get(),
467
4.03k
                          hs->ssl->ctx->client_CA.get(), cbb);
468
4.03k
}
469
470
0
bool ssl_add_CA_names(const SSL_HANDSHAKE *hs, CBB *cbb) {
471
0
  return marshal_CA_names(hs->config->CA_names.get(),
472
0
                          hs->ssl->ctx->CA_names.get(), cbb);
473
0
}
474
475
bool ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey,
476
53.0k
                                const CRYPTO_BUFFER *leaf) {
477
53.0k
  assert(ssl_protocol_version(hs->ssl) < TLS1_3_VERSION);
478
479
  // Check the certificate's type matches the cipher. This does not check key
480
  // usage restrictions, which are handled separately.
481
  //
482
  // TODO(davidben): Put the key type and key usage checks in one place.
483
53.0k
  if (!(hs->new_cipher->algorithm_auth &
484
53.0k
        ssl_cipher_auth_mask_for_key(pkey, /*sign_ok=*/true))) {
485
8
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE);
486
8
    return false;
487
8
  }
488
489
53.0k
  if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
490
    // Check the key's group and point format are acceptable.
491
14.7k
    EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
492
14.7k
    uint16_t group_id;
493
14.7k
    if (!ssl_nid_to_group_id(
494
14.7k
            &group_id, EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key))) ||
495
14.7k
        !tls1_check_group_id(hs, group_id) ||
496
14.7k
        EC_KEY_get_conv_form(ec_key) != POINT_CONVERSION_UNCOMPRESSED) {
497
3
      OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT);
498
3
      return false;
499
3
    }
500
14.7k
  }
501
502
53.0k
  return true;
503
53.0k
}
504
505
BSSL_NAMESPACE_END
506
507
using namespace bssl;
508
509
int SSL_set_chain_and_key(SSL *ssl, CRYPTO_BUFFER *const *certs,
510
                          size_t num_certs, EVP_PKEY *privkey,
511
0
                          const SSL_PRIVATE_KEY_METHOD *privkey_method) {
512
0
  if (!ssl->config) {
513
0
    return 0;
514
0
  }
515
0
  return cert_set_chain_and_key(ssl->config->cert.get(), certs, num_certs,
516
0
                                privkey, privkey_method);
517
0
}
518
519
int SSL_CTX_set_chain_and_key(SSL_CTX *ctx, CRYPTO_BUFFER *const *certs,
520
                              size_t num_certs, EVP_PKEY *privkey,
521
0
                              const SSL_PRIVATE_KEY_METHOD *privkey_method) {
522
0
  return cert_set_chain_and_key(ctx->cert.get(), certs, num_certs, privkey,
523
0
                                privkey_method);
524
0
}
525
526
0
void SSL_certs_clear(SSL *ssl) {
527
0
  if (!ssl->config) {
528
0
    return;
529
0
  }
530
531
0
  CERT *cert = ssl->config->cert.get();
532
0
  cert->x509_method->cert_clear(cert);
533
0
  cert->credentials.clear();
534
0
  cert->legacy_credential->ClearCertAndKey();
535
0
}
536
537
0
const STACK_OF(CRYPTO_BUFFER) *SSL_CTX_get0_chain(const SSL_CTX *ctx) {
538
0
  return ctx->cert->legacy_credential->chain.get();
539
0
}
540
541
0
const STACK_OF(CRYPTO_BUFFER) *SSL_get0_chain(const SSL *ssl) {
542
0
  if (!ssl->config) {
543
0
    return nullptr;
544
0
  }
545
0
  return ssl->config->cert->legacy_credential->chain.get();
546
0
}
547
548
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len,
549
0
                                 const uint8_t *der) {
550
0
  UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(der, der_len, NULL));
551
0
  if (!buffer) {
552
0
    return 0;
553
0
  }
554
555
0
  return ssl_set_cert(ctx->cert.get(), std::move(buffer));
556
0
}
557
558
0
int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
559
0
  UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(der, der_len, NULL));
560
0
  if (!buffer || !ssl->config) {
561
0
    return 0;
562
0
  }
563
564
0
  return ssl_set_cert(ssl->config->cert.get(), std::move(buffer));
565
0
}
566
567
void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg),
568
0
                         void *arg) {
569
0
  ssl_cert_set_cert_cb(ctx->cert.get(), cb, arg);
570
0
}
571
572
0
void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) {
573
0
  if (!ssl->config) {
574
0
    return;
575
0
  }
576
0
  ssl_cert_set_cert_cb(ssl->config->cert.get(), cb, arg);
577
0
}
578
579
0
const STACK_OF(CRYPTO_BUFFER) *SSL_get0_peer_certificates(const SSL *ssl) {
580
0
  SSL_SESSION *session = SSL_get_session(ssl);
581
0
  if (session == NULL) {
582
0
    return NULL;
583
0
  }
584
585
0
  return session->certs.get();
586
0
}
587
588
0
const STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs(const SSL *ssl) {
589
0
  if (ssl->s3->hs == NULL) {
590
0
    return NULL;
591
0
  }
592
0
  return ssl->s3->hs->ca_names.get();
593
0
}
594
595
int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list,
596
2.92k
                                           size_t list_len) {
597
2.92k
  UniquePtr<CRYPTO_BUFFER> buf(CRYPTO_BUFFER_new(list, list_len, nullptr));
598
2.92k
  return buf != nullptr && SSL_CREDENTIAL_set1_signed_cert_timestamp_list(
599
2.92k
                               ctx->cert->legacy_credential.get(), buf.get());
600
2.92k
}
601
602
int SSL_set_signed_cert_timestamp_list(SSL *ssl, const uint8_t *list,
603
0
                                       size_t list_len) {
604
0
  if (!ssl->config) {
605
0
    return 0;
606
0
  }
607
0
  UniquePtr<CRYPTO_BUFFER> buf(CRYPTO_BUFFER_new(list, list_len, nullptr));
608
0
  return buf != nullptr &&
609
0
         SSL_CREDENTIAL_set1_signed_cert_timestamp_list(
610
0
             ssl->config->cert->legacy_credential.get(), buf.get());
611
0
}
612
613
int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response,
614
20.2k
                              size_t response_len) {
615
20.2k
  UniquePtr<CRYPTO_BUFFER> buf(
616
20.2k
      CRYPTO_BUFFER_new(response, response_len, nullptr));
617
20.2k
  return buf != nullptr && SSL_CREDENTIAL_set1_ocsp_response(
618
20.2k
                               ctx->cert->legacy_credential.get(), buf.get());
619
20.2k
}
620
621
int SSL_set_ocsp_response(SSL *ssl, const uint8_t *response,
622
0
                          size_t response_len) {
623
0
  if (!ssl->config) {
624
0
    return 0;
625
0
  }
626
0
  UniquePtr<CRYPTO_BUFFER> buf(
627
0
      CRYPTO_BUFFER_new(response, response_len, nullptr));
628
0
  return buf != nullptr &&
629
0
         SSL_CREDENTIAL_set1_ocsp_response(
630
0
             ssl->config->cert->legacy_credential.get(), buf.get());
631
0
}
632
633
0
void SSL_CTX_set0_client_CAs(SSL_CTX *ctx, STACK_OF(CRYPTO_BUFFER) *name_list) {
634
0
  ctx->x509_method->ssl_ctx_flush_cached_client_CA(ctx);
635
0
  ctx->client_CA.reset(name_list);
636
0
}
637
638
0
void SSL_set0_client_CAs(SSL *ssl, STACK_OF(CRYPTO_BUFFER) *name_list) {
639
0
  if (!ssl->config) {
640
0
    return;
641
0
  }
642
0
  ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl->config.get());
643
0
  ssl->config->client_CA.reset(name_list);
644
0
}
645
646
0
void SSL_set0_CA_names(SSL *ssl, STACK_OF(CRYPTO_BUFFER) *name_list) {
647
0
  if (!ssl->config) {
648
0
    return;
649
0
  }
650
0
  ssl->config->CA_names.reset(name_list);
651
0
}