xref: /aosp_15_r20/external/boringssl/src/ssl/ssl_cert.cc (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1 /* Copyright (C) 1995-1998 Eric Young ([email protected])
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young ([email protected]).
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 ([email protected]).
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 ([email protected])"
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 ([email protected])"
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  *    [email protected].
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  * ([email protected]).  This product includes software written by Tim
107  * Hudson ([email protected]).
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 #include <openssl/ssl.h>
116 
117 #include <assert.h>
118 #include <limits.h>
119 #include <string.h>
120 
121 #include <utility>
122 
123 #include <openssl/bn.h>
124 #include <openssl/bytestring.h>
125 #include <openssl/ec_key.h>
126 #include <openssl/err.h>
127 #include <openssl/mem.h>
128 #include <openssl/sha.h>
129 #include <openssl/x509.h>
130 
131 #include "../crypto/internal.h"
132 #include "internal.h"
133 
134 
135 BSSL_NAMESPACE_BEGIN
136 
CERT(const SSL_X509_METHOD * x509_method_arg)137 CERT::CERT(const SSL_X509_METHOD *x509_method_arg)
138     : default_credential(MakeUnique<SSL_CREDENTIAL>(SSLCredentialType::kX509)),
139       x509_method(x509_method_arg) {}
140 
~CERT()141 CERT::~CERT() { x509_method->cert_free(this); }
142 
ssl_cert_dup(CERT * cert)143 UniquePtr<CERT> ssl_cert_dup(CERT *cert) {
144   UniquePtr<CERT> ret = MakeUnique<CERT>(cert->x509_method);
145   if (!ret) {
146     return nullptr;
147   }
148 
149   // TODO(crbug.com/boringssl/431): This should just be |CopyFrom|.
150   for (const auto &cred : cert->credentials) {
151     if (!ret->credentials.Push(UpRef(cred))) {
152       return nullptr;
153     }
154   }
155 
156   // |default_credential| is mutable, so it must be copied. We cannot simply
157   // bump the reference count.
158   ret->default_credential = cert->default_credential->Dup();
159   if (ret->default_credential == nullptr) {
160     return nullptr;
161   }
162 
163   ret->cert_cb = cert->cert_cb;
164   ret->cert_cb_arg = cert->cert_cb_arg;
165 
166   ret->x509_method->cert_dup(ret.get(), cert);
167 
168   ret->sid_ctx_length = cert->sid_ctx_length;
169   OPENSSL_memcpy(ret->sid_ctx, cert->sid_ctx, sizeof(ret->sid_ctx));
170 
171   return ret;
172 }
173 
ssl_cert_set_cert_cb(CERT * cert,int (* cb)(SSL * ssl,void * arg),void * arg)174 static void ssl_cert_set_cert_cb(CERT *cert, int (*cb)(SSL *ssl, void *arg),
175                                  void *arg) {
176   cert->cert_cb = cb;
177   cert->cert_cb_arg = arg;
178 }
179 
cert_set_chain_and_key(CERT * cert,CRYPTO_BUFFER * const * certs,size_t num_certs,EVP_PKEY * privkey,const SSL_PRIVATE_KEY_METHOD * privkey_method)180 static int cert_set_chain_and_key(
181     CERT *cert, CRYPTO_BUFFER *const *certs, size_t num_certs,
182     EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method) {
183   if (num_certs == 0 ||
184       (privkey == NULL && privkey_method == NULL)) {
185     OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
186     return 0;
187   }
188 
189   if (privkey != NULL && privkey_method != NULL) {
190     OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD);
191     return 0;
192   }
193 
194   cert->default_credential->ClearCertAndKey();
195   if (!SSL_CREDENTIAL_set1_cert_chain(cert->default_credential.get(), certs,
196                                       num_certs)) {
197     return 0;
198   }
199 
200   cert->x509_method->cert_flush_cached_leaf(cert);
201   cert->x509_method->cert_flush_cached_chain(cert);
202 
203   return privkey != nullptr
204              ? SSL_CREDENTIAL_set1_private_key(cert->default_credential.get(),
205                                                privkey)
206              : SSL_CREDENTIAL_set_private_key_method(
207                    cert->default_credential.get(), privkey_method);
208 }
209 
ssl_set_cert(CERT * cert,UniquePtr<CRYPTO_BUFFER> buffer)210 bool ssl_set_cert(CERT *cert, UniquePtr<CRYPTO_BUFFER> buffer) {
211   // Don't fail for a cert/key mismatch, just free the current private key.
212   // (When switching to a different keypair, the caller should switch the
213   // certificate, then the key.)
214   if (!cert->default_credential->SetLeafCert(
215           std::move(buffer), /*discard_key_on_mismatch=*/true)) {
216     return false;
217   }
218 
219   cert->x509_method->cert_flush_cached_leaf(cert);
220   return true;
221 }
222 
ssl_parse_cert_chain(uint8_t * out_alert,UniquePtr<STACK_OF (CRYPTO_BUFFER)> * out_chain,UniquePtr<EVP_PKEY> * out_pubkey,uint8_t * out_leaf_sha256,CBS * cbs,CRYPTO_BUFFER_POOL * pool)223 bool ssl_parse_cert_chain(uint8_t *out_alert,
224                           UniquePtr<STACK_OF(CRYPTO_BUFFER)> *out_chain,
225                           UniquePtr<EVP_PKEY> *out_pubkey,
226                           uint8_t *out_leaf_sha256, CBS *cbs,
227                           CRYPTO_BUFFER_POOL *pool) {
228   out_chain->reset();
229   out_pubkey->reset();
230 
231   CBS certificate_list;
232   if (!CBS_get_u24_length_prefixed(cbs, &certificate_list)) {
233     *out_alert = SSL_AD_DECODE_ERROR;
234     OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
235     return false;
236   }
237 
238   if (CBS_len(&certificate_list) == 0) {
239     return true;
240   }
241 
242   UniquePtr<STACK_OF(CRYPTO_BUFFER)> chain(sk_CRYPTO_BUFFER_new_null());
243   if (!chain) {
244     *out_alert = SSL_AD_INTERNAL_ERROR;
245     return false;
246   }
247 
248   UniquePtr<EVP_PKEY> pubkey;
249   while (CBS_len(&certificate_list) > 0) {
250     CBS certificate;
251     if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) ||
252         CBS_len(&certificate) == 0) {
253       *out_alert = SSL_AD_DECODE_ERROR;
254       OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
255       return false;
256     }
257 
258     if (sk_CRYPTO_BUFFER_num(chain.get()) == 0) {
259       pubkey = ssl_cert_parse_pubkey(&certificate);
260       if (!pubkey) {
261         *out_alert = SSL_AD_DECODE_ERROR;
262         return false;
263       }
264 
265       // Retain the hash of the leaf certificate if requested.
266       if (out_leaf_sha256 != NULL) {
267         SHA256(CBS_data(&certificate), CBS_len(&certificate), out_leaf_sha256);
268       }
269     }
270 
271     UniquePtr<CRYPTO_BUFFER> buf(
272         CRYPTO_BUFFER_new_from_CBS(&certificate, pool));
273     if (!buf ||
274         !PushToStack(chain.get(), std::move(buf))) {
275       *out_alert = SSL_AD_INTERNAL_ERROR;
276       return false;
277     }
278   }
279 
280   *out_chain = std::move(chain);
281   *out_pubkey = std::move(pubkey);
282   return true;
283 }
284 
285 // ssl_cert_skip_to_spki parses a DER-encoded, X.509 certificate from |in| and
286 // positions |*out_tbs_cert| to cover the TBSCertificate, starting at the
287 // subjectPublicKeyInfo.
ssl_cert_skip_to_spki(const CBS * in,CBS * out_tbs_cert)288 static bool ssl_cert_skip_to_spki(const CBS *in, CBS *out_tbs_cert) {
289   /* From RFC 5280, section 4.1
290    *    Certificate  ::=  SEQUENCE  {
291    *      tbsCertificate       TBSCertificate,
292    *      signatureAlgorithm   AlgorithmIdentifier,
293    *      signatureValue       BIT STRING  }
294 
295    * TBSCertificate  ::=  SEQUENCE  {
296    *      version         [0]  EXPLICIT Version DEFAULT v1,
297    *      serialNumber         CertificateSerialNumber,
298    *      signature            AlgorithmIdentifier,
299    *      issuer               Name,
300    *      validity             Validity,
301    *      subject              Name,
302    *      subjectPublicKeyInfo SubjectPublicKeyInfo,
303    *      ... } */
304   CBS buf = *in;
305 
306   CBS toplevel;
307   if (!CBS_get_asn1(&buf, &toplevel, CBS_ASN1_SEQUENCE) ||
308       CBS_len(&buf) != 0 ||
309       !CBS_get_asn1(&toplevel, out_tbs_cert, CBS_ASN1_SEQUENCE) ||
310       // version
311       !CBS_get_optional_asn1(
312           out_tbs_cert, NULL, NULL,
313           CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
314       // serialNumber
315       !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_INTEGER) ||
316       // signature algorithm
317       !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) ||
318       // issuer
319       !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) ||
320       // validity
321       !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) ||
322       // subject
323       !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE)) {
324     return false;
325   }
326 
327   return true;
328 }
329 
ssl_cert_parse_pubkey(const CBS * in)330 UniquePtr<EVP_PKEY> ssl_cert_parse_pubkey(const CBS *in) {
331   CBS buf = *in, tbs_cert;
332   if (!ssl_cert_skip_to_spki(&buf, &tbs_cert)) {
333     OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
334     return nullptr;
335   }
336 
337   return UniquePtr<EVP_PKEY>(EVP_parse_public_key(&tbs_cert));
338 }
339 
ssl_compare_public_and_private_key(const EVP_PKEY * pubkey,const EVP_PKEY * privkey)340 bool ssl_compare_public_and_private_key(const EVP_PKEY *pubkey,
341                                         const EVP_PKEY *privkey) {
342   if (EVP_PKEY_is_opaque(privkey)) {
343     // We cannot check an opaque private key and have to trust that it
344     // matches.
345     return true;
346   }
347 
348   switch (EVP_PKEY_cmp(pubkey, privkey)) {
349     case 1:
350       return true;
351     case 0:
352       OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
353       return false;
354     case -1:
355       OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
356       return false;
357     case -2:
358       OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
359       return false;
360   }
361 
362   assert(0);
363   return false;
364 }
365 
ssl_cert_check_key_usage(const CBS * in,enum ssl_key_usage_t bit)366 bool ssl_cert_check_key_usage(const CBS *in, enum ssl_key_usage_t bit) {
367   CBS buf = *in;
368 
369   CBS tbs_cert, outer_extensions;
370   int has_extensions;
371   if (!ssl_cert_skip_to_spki(&buf, &tbs_cert) ||
372       // subjectPublicKeyInfo
373       !CBS_get_asn1(&tbs_cert, NULL, CBS_ASN1_SEQUENCE) ||
374       // issuerUniqueID
375       !CBS_get_optional_asn1(&tbs_cert, NULL, NULL,
376                              CBS_ASN1_CONTEXT_SPECIFIC | 1) ||
377       // subjectUniqueID
378       !CBS_get_optional_asn1(&tbs_cert, NULL, NULL,
379                              CBS_ASN1_CONTEXT_SPECIFIC | 2) ||
380       !CBS_get_optional_asn1(
381           &tbs_cert, &outer_extensions, &has_extensions,
382           CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3)) {
383     OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
384     return false;
385   }
386 
387   if (!has_extensions) {
388     return true;
389   }
390 
391   CBS extensions;
392   if (!CBS_get_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) {
393     OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
394     return false;
395   }
396 
397   while (CBS_len(&extensions) > 0) {
398     CBS extension, oid, contents;
399     if (!CBS_get_asn1(&extensions, &extension, CBS_ASN1_SEQUENCE) ||
400         !CBS_get_asn1(&extension, &oid, CBS_ASN1_OBJECT) ||
401         (CBS_peek_asn1_tag(&extension, CBS_ASN1_BOOLEAN) &&
402          !CBS_get_asn1(&extension, NULL, CBS_ASN1_BOOLEAN)) ||
403         !CBS_get_asn1(&extension, &contents, CBS_ASN1_OCTETSTRING) ||
404         CBS_len(&extension) != 0) {
405       OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
406       return false;
407     }
408 
409     static const uint8_t kKeyUsageOID[3] = {0x55, 0x1d, 0x0f};
410     if (CBS_len(&oid) != sizeof(kKeyUsageOID) ||
411         OPENSSL_memcmp(CBS_data(&oid), kKeyUsageOID, sizeof(kKeyUsageOID)) !=
412             0) {
413       continue;
414     }
415 
416     CBS bit_string;
417     if (!CBS_get_asn1(&contents, &bit_string, CBS_ASN1_BITSTRING) ||
418         CBS_len(&contents) != 0) {
419       OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
420       return false;
421     }
422 
423     // This is the KeyUsage extension. See
424     // https://tools.ietf.org/html/rfc5280#section-4.2.1.3
425     if (!CBS_is_valid_asn1_bitstring(&bit_string)) {
426       OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
427       return false;
428     }
429 
430     if (!CBS_asn1_bitstring_has_bit(&bit_string, bit)) {
431       OPENSSL_PUT_ERROR(SSL, SSL_R_KEY_USAGE_BIT_INCORRECT);
432       return false;
433     }
434 
435     return true;
436   }
437 
438   // No KeyUsage extension found.
439   return true;
440 }
441 
ssl_parse_client_CA_list(SSL * ssl,uint8_t * out_alert,CBS * cbs)442 UniquePtr<STACK_OF(CRYPTO_BUFFER)> ssl_parse_client_CA_list(SSL *ssl,
443                                                             uint8_t *out_alert,
444                                                             CBS *cbs) {
445   CRYPTO_BUFFER_POOL *const pool = ssl->ctx->pool;
446 
447   UniquePtr<STACK_OF(CRYPTO_BUFFER)> ret(sk_CRYPTO_BUFFER_new_null());
448   if (!ret) {
449     *out_alert = SSL_AD_INTERNAL_ERROR;
450     return nullptr;
451   }
452 
453   CBS child;
454   if (!CBS_get_u16_length_prefixed(cbs, &child)) {
455     *out_alert = SSL_AD_DECODE_ERROR;
456     OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH);
457     return nullptr;
458   }
459 
460   while (CBS_len(&child) > 0) {
461     CBS distinguished_name;
462     if (!CBS_get_u16_length_prefixed(&child, &distinguished_name)) {
463       *out_alert = SSL_AD_DECODE_ERROR;
464       OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_TOO_LONG);
465       return nullptr;
466     }
467 
468     UniquePtr<CRYPTO_BUFFER> buffer(
469         CRYPTO_BUFFER_new_from_CBS(&distinguished_name, pool));
470     if (!buffer ||
471         !PushToStack(ret.get(), std::move(buffer))) {
472       *out_alert = SSL_AD_INTERNAL_ERROR;
473       return nullptr;
474     }
475   }
476 
477   if (!ssl->ctx->x509_method->check_client_CA_list(ret.get())) {
478     *out_alert = SSL_AD_DECODE_ERROR;
479     OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
480     return nullptr;
481   }
482 
483   return ret;
484 }
485 
ssl_has_client_CAs(const SSL_CONFIG * cfg)486 bool ssl_has_client_CAs(const SSL_CONFIG *cfg) {
487   const STACK_OF(CRYPTO_BUFFER) *names = cfg->client_CA.get();
488   if (names == nullptr) {
489     names = cfg->ssl->ctx->client_CA.get();
490   }
491   if (names == nullptr) {
492     return false;
493   }
494   return sk_CRYPTO_BUFFER_num(names) > 0;
495 }
496 
ssl_add_client_CA_list(SSL_HANDSHAKE * hs,CBB * cbb)497 bool ssl_add_client_CA_list(SSL_HANDSHAKE *hs, CBB *cbb) {
498   CBB child, name_cbb;
499   if (!CBB_add_u16_length_prefixed(cbb, &child)) {
500     return false;
501   }
502 
503   const STACK_OF(CRYPTO_BUFFER) *names = hs->config->client_CA.get();
504   if (names == NULL) {
505     names = hs->ssl->ctx->client_CA.get();
506   }
507   if (names == NULL) {
508     return CBB_flush(cbb);
509   }
510 
511   for (const CRYPTO_BUFFER *name : names) {
512     if (!CBB_add_u16_length_prefixed(&child, &name_cbb) ||
513         !CBB_add_bytes(&name_cbb, CRYPTO_BUFFER_data(name),
514                        CRYPTO_BUFFER_len(name))) {
515       return false;
516     }
517   }
518 
519   return CBB_flush(cbb);
520 }
521 
ssl_check_leaf_certificate(SSL_HANDSHAKE * hs,EVP_PKEY * pkey,const CRYPTO_BUFFER * leaf)522 bool ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey,
523                                 const CRYPTO_BUFFER *leaf) {
524   assert(ssl_protocol_version(hs->ssl) < TLS1_3_VERSION);
525 
526   // Check the certificate's type matches the cipher. This does not check key
527   // usage restrictions, which are handled separately.
528   //
529   // TODO(davidben): Put the key type and key usage checks in one place.
530   if (!(hs->new_cipher->algorithm_auth &
531         ssl_cipher_auth_mask_for_key(pkey, /*sign_ok=*/true))) {
532     OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE);
533     return false;
534   }
535 
536   if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
537     // Check the key's group and point format are acceptable.
538     EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
539     uint16_t group_id;
540     if (!ssl_nid_to_group_id(
541             &group_id, EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key))) ||
542         !tls1_check_group_id(hs, group_id) ||
543         EC_KEY_get_conv_form(ec_key) != POINT_CONVERSION_UNCOMPRESSED) {
544       OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT);
545       return false;
546     }
547   }
548 
549   return true;
550 }
551 
552 BSSL_NAMESPACE_END
553 
554 using namespace bssl;
555 
SSL_set_chain_and_key(SSL * ssl,CRYPTO_BUFFER * const * certs,size_t num_certs,EVP_PKEY * privkey,const SSL_PRIVATE_KEY_METHOD * privkey_method)556 int SSL_set_chain_and_key(SSL *ssl, CRYPTO_BUFFER *const *certs,
557                           size_t num_certs, EVP_PKEY *privkey,
558                           const SSL_PRIVATE_KEY_METHOD *privkey_method) {
559   if (!ssl->config) {
560     return 0;
561   }
562   return cert_set_chain_and_key(ssl->config->cert.get(), certs, num_certs,
563                                 privkey, privkey_method);
564 }
565 
SSL_CTX_set_chain_and_key(SSL_CTX * ctx,CRYPTO_BUFFER * const * certs,size_t num_certs,EVP_PKEY * privkey,const SSL_PRIVATE_KEY_METHOD * privkey_method)566 int SSL_CTX_set_chain_and_key(SSL_CTX *ctx, CRYPTO_BUFFER *const *certs,
567                               size_t num_certs, EVP_PKEY *privkey,
568                               const SSL_PRIVATE_KEY_METHOD *privkey_method) {
569   return cert_set_chain_and_key(ctx->cert.get(), certs, num_certs, privkey,
570                                 privkey_method);
571 }
572 
SSL_certs_clear(SSL * ssl)573 void SSL_certs_clear(SSL *ssl) {
574   if (!ssl->config) {
575     return;
576   }
577 
578   CERT *cert = ssl->config->cert.get();
579   cert->x509_method->cert_clear(cert);
580   cert->credentials.clear();
581   cert->default_credential->ClearCertAndKey();
582 }
583 
STACK_OF(CRYPTO_BUFFER)584 const STACK_OF(CRYPTO_BUFFER) *SSL_CTX_get0_chain(const SSL_CTX *ctx) {
585   return ctx->cert->default_credential->chain.get();
586 }
587 
STACK_OF(CRYPTO_BUFFER)588 const STACK_OF(CRYPTO_BUFFER) *SSL_get0_chain(const SSL *ssl) {
589   if (!ssl->config) {
590     return nullptr;
591   }
592   return ssl->config->cert->default_credential->chain.get();
593 }
594 
SSL_CTX_use_certificate_ASN1(SSL_CTX * ctx,size_t der_len,const uint8_t * der)595 int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len,
596                                  const uint8_t *der) {
597   UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(der, der_len, NULL));
598   if (!buffer) {
599     return 0;
600   }
601 
602   return ssl_set_cert(ctx->cert.get(), std::move(buffer));
603 }
604 
SSL_use_certificate_ASN1(SSL * ssl,const uint8_t * der,size_t der_len)605 int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
606   UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(der, der_len, NULL));
607   if (!buffer || !ssl->config) {
608     return 0;
609   }
610 
611   return ssl_set_cert(ssl->config->cert.get(), std::move(buffer));
612 }
613 
SSL_CTX_set_cert_cb(SSL_CTX * ctx,int (* cb)(SSL * ssl,void * arg),void * arg)614 void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg),
615                          void *arg) {
616   ssl_cert_set_cert_cb(ctx->cert.get(), cb, arg);
617 }
618 
SSL_set_cert_cb(SSL * ssl,int (* cb)(SSL * ssl,void * arg),void * arg)619 void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) {
620   if (!ssl->config) {
621     return;
622   }
623   ssl_cert_set_cert_cb(ssl->config->cert.get(), cb, arg);
624 }
625 
STACK_OF(CRYPTO_BUFFER)626 const STACK_OF(CRYPTO_BUFFER) *SSL_get0_peer_certificates(const SSL *ssl) {
627   SSL_SESSION *session = SSL_get_session(ssl);
628   if (session == NULL) {
629     return NULL;
630   }
631 
632   return session->certs.get();
633 }
634 
STACK_OF(CRYPTO_BUFFER)635 const STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs(const SSL *ssl) {
636   if (ssl->s3->hs == NULL) {
637     return NULL;
638   }
639   return ssl->s3->hs->ca_names.get();
640 }
641 
SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX * ctx,const uint8_t * list,size_t list_len)642 int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list,
643                                            size_t list_len) {
644   UniquePtr<CRYPTO_BUFFER> buf(CRYPTO_BUFFER_new(list, list_len, nullptr));
645   return buf != nullptr && SSL_CREDENTIAL_set1_signed_cert_timestamp_list(
646                                ctx->cert->default_credential.get(), buf.get());
647 }
648 
SSL_set_signed_cert_timestamp_list(SSL * ssl,const uint8_t * list,size_t list_len)649 int SSL_set_signed_cert_timestamp_list(SSL *ssl, const uint8_t *list,
650                                        size_t list_len) {
651   if (!ssl->config) {
652     return 0;
653   }
654   UniquePtr<CRYPTO_BUFFER> buf(CRYPTO_BUFFER_new(list, list_len, nullptr));
655   return buf != nullptr &&
656          SSL_CREDENTIAL_set1_signed_cert_timestamp_list(
657              ssl->config->cert->default_credential.get(), buf.get());
658 }
659 
SSL_CTX_set_ocsp_response(SSL_CTX * ctx,const uint8_t * response,size_t response_len)660 int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response,
661                               size_t response_len) {
662   UniquePtr<CRYPTO_BUFFER> buf(
663       CRYPTO_BUFFER_new(response, response_len, nullptr));
664   return buf != nullptr && SSL_CREDENTIAL_set1_ocsp_response(
665                                ctx->cert->default_credential.get(), buf.get());
666 }
667 
SSL_set_ocsp_response(SSL * ssl,const uint8_t * response,size_t response_len)668 int SSL_set_ocsp_response(SSL *ssl, const uint8_t *response,
669                           size_t response_len) {
670   if (!ssl->config) {
671     return 0;
672   }
673   UniquePtr<CRYPTO_BUFFER> buf(
674       CRYPTO_BUFFER_new(response, response_len, nullptr));
675   return buf != nullptr &&
676          SSL_CREDENTIAL_set1_ocsp_response(
677              ssl->config->cert->default_credential.get(), buf.get());
678 }
679 
SSL_CTX_set0_client_CAs(SSL_CTX * ctx,STACK_OF (CRYPTO_BUFFER)* name_list)680 void SSL_CTX_set0_client_CAs(SSL_CTX *ctx, STACK_OF(CRYPTO_BUFFER) *name_list) {
681   ctx->x509_method->ssl_ctx_flush_cached_client_CA(ctx);
682   ctx->client_CA.reset(name_list);
683 }
684 
SSL_set0_client_CAs(SSL * ssl,STACK_OF (CRYPTO_BUFFER)* name_list)685 void SSL_set0_client_CAs(SSL *ssl, STACK_OF(CRYPTO_BUFFER) *name_list) {
686   if (!ssl->config) {
687     return;
688   }
689   ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl->config.get());
690   ssl->config->client_CA.reset(name_list);
691 }
692