• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.]
56  */
57 /* ====================================================================
58  * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
59  *
60  * Redistribution and use in source and binary forms, with or without
61  * modification, are permitted provided that the following conditions
62  * are met:
63  *
64  * 1. Redistributions of source code must retain the above copyright
65  *    notice, this list of conditions and the following disclaimer.
66  *
67  * 2. Redistributions in binary form must reproduce the above copyright
68  *    notice, this list of conditions and the following disclaimer in
69  *    the documentation and/or other materials provided with the
70  *    distribution.
71  *
72  * 3. All advertising materials mentioning features or use of this
73  *    software must display the following acknowledgment:
74  *    "This product includes software developed by the OpenSSL Project
75  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76  *
77  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78  *    endorse or promote products derived from this software without
79  *    prior written permission. For written permission, please contact
80  *    openssl-core@openssl.org.
81  *
82  * 5. Products derived from this software may not be called "OpenSSL"
83  *    nor may "OpenSSL" appear in their names without prior written
84  *    permission of the OpenSSL Project.
85  *
86  * 6. Redistributions of any form whatsoever must retain the following
87  *    acknowledgment:
88  *    "This product includes software developed by the OpenSSL Project
89  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90  *
91  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
95  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102  * OF THE POSSIBILITY OF SUCH DAMAGE.
103  * ====================================================================
104  *
105  * This product includes cryptographic software written by Eric Young
106  * (eay@cryptsoft.com).  This product includes software written by Tim
107  * Hudson (tjh@cryptsoft.com).
108  *
109  */
110 /* ====================================================================
111  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
112  * ECC cipher suite support in OpenSSL originally developed by
113  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */
114 
115 #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     : legacy_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   // |legacy_credential| is mutable, so it must be copied. We cannot simply
157   // bump the reference count.
158   ret->legacy_credential = cert->legacy_credential->Dup();
159   if (ret->legacy_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 = cert->sid_ctx;
169   return ret;
170 }
171 
ssl_cert_set_cert_cb(CERT * cert,int (* cb)(SSL * ssl,void * arg),void * arg)172 static void ssl_cert_set_cert_cb(CERT *cert, int (*cb)(SSL *ssl, void *arg),
173                                  void *arg) {
174   cert->cert_cb = cb;
175   cert->cert_cb_arg = arg;
176 }
177 
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)178 static int cert_set_chain_and_key(
179     CERT *cert, CRYPTO_BUFFER *const *certs, size_t num_certs,
180     EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method) {
181   if (num_certs == 0 ||  //
182       (privkey == NULL && privkey_method == NULL)) {
183     OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
184     return 0;
185   }
186 
187   if (privkey != NULL && privkey_method != NULL) {
188     OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD);
189     return 0;
190   }
191 
192   cert->legacy_credential->ClearCertAndKey();
193   if (!SSL_CREDENTIAL_set1_cert_chain(cert->legacy_credential.get(), certs,
194                                       num_certs)) {
195     return 0;
196   }
197 
198   cert->x509_method->cert_flush_cached_leaf(cert);
199   cert->x509_method->cert_flush_cached_chain(cert);
200 
201   return privkey != nullptr
202              ? SSL_CREDENTIAL_set1_private_key(cert->legacy_credential.get(),
203                                                privkey)
204              : SSL_CREDENTIAL_set_private_key_method(
205                    cert->legacy_credential.get(), privkey_method);
206 }
207 
ssl_set_cert(CERT * cert,UniquePtr<CRYPTO_BUFFER> buffer)208 bool ssl_set_cert(CERT *cert, UniquePtr<CRYPTO_BUFFER> buffer) {
209   // Don't fail for a cert/key mismatch, just free the current private key.
210   // (When switching to a different keypair, the caller should switch the
211   // certificate, then the key.)
212   if (!cert->legacy_credential->SetLeafCert(std::move(buffer),
213                                             /*discard_key_on_mismatch=*/true)) {
214     return false;
215   }
216 
217   cert->x509_method->cert_flush_cached_leaf(cert);
218   return true;
219 }
220 
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)221 bool ssl_parse_cert_chain(uint8_t *out_alert,
222                           UniquePtr<STACK_OF(CRYPTO_BUFFER)> *out_chain,
223                           UniquePtr<EVP_PKEY> *out_pubkey,
224                           uint8_t *out_leaf_sha256, CBS *cbs,
225                           CRYPTO_BUFFER_POOL *pool) {
226   out_chain->reset();
227   out_pubkey->reset();
228 
229   CBS certificate_list;
230   if (!CBS_get_u24_length_prefixed(cbs, &certificate_list)) {
231     *out_alert = SSL_AD_DECODE_ERROR;
232     OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
233     return false;
234   }
235 
236   if (CBS_len(&certificate_list) == 0) {
237     return true;
238   }
239 
240   UniquePtr<STACK_OF(CRYPTO_BUFFER)> chain(sk_CRYPTO_BUFFER_new_null());
241   if (!chain) {
242     *out_alert = SSL_AD_INTERNAL_ERROR;
243     return false;
244   }
245 
246   UniquePtr<EVP_PKEY> pubkey;
247   while (CBS_len(&certificate_list) > 0) {
248     CBS certificate;
249     if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) ||
250         CBS_len(&certificate) == 0) {
251       *out_alert = SSL_AD_DECODE_ERROR;
252       OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
253       return false;
254     }
255 
256     if (sk_CRYPTO_BUFFER_num(chain.get()) == 0) {
257       pubkey = ssl_cert_parse_pubkey(&certificate);
258       if (!pubkey) {
259         *out_alert = SSL_AD_DECODE_ERROR;
260         return false;
261       }
262 
263       // Retain the hash of the leaf certificate if requested.
264       if (out_leaf_sha256 != NULL) {
265         SHA256(CBS_data(&certificate), CBS_len(&certificate), out_leaf_sha256);
266       }
267     }
268 
269     UniquePtr<CRYPTO_BUFFER> buf(
270         CRYPTO_BUFFER_new_from_CBS(&certificate, pool));
271     if (!buf ||  //
272         !PushToStack(chain.get(), std::move(buf))) {
273       *out_alert = SSL_AD_INTERNAL_ERROR;
274       return false;
275     }
276   }
277 
278   *out_chain = std::move(chain);
279   *out_pubkey = std::move(pubkey);
280   return true;
281 }
282 
283 // ssl_cert_skip_to_spki parses a DER-encoded, X.509 certificate from |in| and
284 // positions |*out_tbs_cert| to cover the TBSCertificate, starting at the
285 // subjectPublicKeyInfo.
ssl_cert_skip_to_spki(const CBS * in,CBS * out_tbs_cert)286 static bool ssl_cert_skip_to_spki(const CBS *in, CBS *out_tbs_cert) {
287   /* From RFC 5280, section 4.1
288    *    Certificate  ::=  SEQUENCE  {
289    *      tbsCertificate       TBSCertificate,
290    *      signatureAlgorithm   AlgorithmIdentifier,
291    *      signatureValue       BIT STRING  }
292 
293    * TBSCertificate  ::=  SEQUENCE  {
294    *      version         [0]  EXPLICIT Version DEFAULT v1,
295    *      serialNumber         CertificateSerialNumber,
296    *      signature            AlgorithmIdentifier,
297    *      issuer               Name,
298    *      validity             Validity,
299    *      subject              Name,
300    *      subjectPublicKeyInfo SubjectPublicKeyInfo,
301    *      ... } */
302   CBS buf = *in;
303 
304   CBS toplevel;
305   if (!CBS_get_asn1(&buf, &toplevel, CBS_ASN1_SEQUENCE) ||          //
306       CBS_len(&buf) != 0 ||                                         //
307       !CBS_get_asn1(&toplevel, out_tbs_cert, CBS_ASN1_SEQUENCE) ||  //
308       // version
309       !CBS_get_optional_asn1(
310           out_tbs_cert, NULL, NULL,
311           CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||  //
312 
313       // serialNumber
314       !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_INTEGER) ||
315       // signature algorithm
316       !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) ||
317       // issuer
318       !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) ||
319       // validity
320       !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) ||
321       // subject
322       !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE)) {
323     return false;
324   }
325 
326   return true;
327 }
328 
ssl_cert_extract_issuer(const CBS * in,CBS * out_dn)329 bool ssl_cert_extract_issuer(const CBS *in, CBS *out_dn) {
330   CBS buf = *in;
331 
332   CBS toplevel;
333   CBS cert;
334   if (!CBS_get_asn1(&buf, &toplevel, CBS_ASN1_SEQUENCE) ||   //
335       CBS_len(&buf) != 0 ||                                  //
336       !CBS_get_asn1(&toplevel, &cert, CBS_ASN1_SEQUENCE) ||  //
337       // version
338       !CBS_get_optional_asn1(
339           &cert, NULL, NULL,
340           CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||  //
341       // serialNumber
342       !CBS_get_asn1(&cert, NULL, CBS_ASN1_INTEGER) ||  //
343       // signature algorithm
344       !CBS_get_asn1(&cert, NULL, CBS_ASN1_SEQUENCE) ||  //
345       // issuer
346       !CBS_get_asn1_element(&cert, out_dn, CBS_ASN1_SEQUENCE)) {
347     return false;
348   }
349   return true;
350 }
351 
ssl_cert_matches_issuer(const CBS * in,const CBS * dn)352 bool ssl_cert_matches_issuer(const CBS *in, const CBS *dn) {
353   CBS issuer;
354 
355   if (!ssl_cert_extract_issuer(in, &issuer)) {
356     return false;
357   }
358   return CBS_mem_equal(&issuer, CBS_data(dn), CBS_len(dn));
359 }
360 
ssl_cert_parse_pubkey(const CBS * in)361 UniquePtr<EVP_PKEY> ssl_cert_parse_pubkey(const CBS *in) {
362   CBS buf = *in, tbs_cert;
363   if (!ssl_cert_skip_to_spki(&buf, &tbs_cert)) {
364     OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
365     return nullptr;
366   }
367 
368   return UniquePtr<EVP_PKEY>(EVP_parse_public_key(&tbs_cert));
369 }
370 
ssl_compare_public_and_private_key(const EVP_PKEY * pubkey,const EVP_PKEY * privkey)371 bool ssl_compare_public_and_private_key(const EVP_PKEY *pubkey,
372                                         const EVP_PKEY *privkey) {
373   if (EVP_PKEY_is_opaque(privkey)) {
374     // We cannot check an opaque private key and have to trust that it
375     // matches.
376     return true;
377   }
378 
379   switch (EVP_PKEY_cmp(pubkey, privkey)) {
380     case 1:
381       return true;
382     case 0:
383       OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
384       return false;
385     case -1:
386       OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
387       return false;
388     case -2:
389       OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
390       return false;
391   }
392 
393   assert(0);
394   return false;
395 }
396 
ssl_cert_check_key_usage(const CBS * in,enum ssl_key_usage_t bit)397 bool ssl_cert_check_key_usage(const CBS *in, enum ssl_key_usage_t bit) {
398   CBS buf = *in;
399 
400   CBS tbs_cert, outer_extensions;
401   int has_extensions;
402   if (!ssl_cert_skip_to_spki(&buf, &tbs_cert) ||
403       // subjectPublicKeyInfo
404       !CBS_get_asn1(&tbs_cert, NULL, CBS_ASN1_SEQUENCE) ||
405       // issuerUniqueID
406       !CBS_get_optional_asn1(&tbs_cert, NULL, NULL,
407                              CBS_ASN1_CONTEXT_SPECIFIC | 1) ||
408       // subjectUniqueID
409       !CBS_get_optional_asn1(&tbs_cert, NULL, NULL,
410                              CBS_ASN1_CONTEXT_SPECIFIC | 2) ||
411       !CBS_get_optional_asn1(
412           &tbs_cert, &outer_extensions, &has_extensions,
413           CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3)) {
414     OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
415     return false;
416   }
417 
418   if (!has_extensions) {
419     return true;
420   }
421 
422   CBS extensions;
423   if (!CBS_get_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) {
424     OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
425     return false;
426   }
427 
428   while (CBS_len(&extensions) > 0) {
429     CBS extension, oid, contents;
430     if (!CBS_get_asn1(&extensions, &extension, CBS_ASN1_SEQUENCE) ||
431         !CBS_get_asn1(&extension, &oid, CBS_ASN1_OBJECT) ||
432         (CBS_peek_asn1_tag(&extension, CBS_ASN1_BOOLEAN) &&
433          !CBS_get_asn1(&extension, NULL, CBS_ASN1_BOOLEAN)) ||
434         !CBS_get_asn1(&extension, &contents, CBS_ASN1_OCTETSTRING) ||
435         CBS_len(&extension) != 0) {
436       OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
437       return false;
438     }
439 
440     static const uint8_t kKeyUsageOID[3] = {0x55, 0x1d, 0x0f};
441     if (CBS_len(&oid) != sizeof(kKeyUsageOID) ||
442         OPENSSL_memcmp(CBS_data(&oid), kKeyUsageOID, sizeof(kKeyUsageOID)) !=
443             0) {
444       continue;
445     }
446 
447     CBS bit_string;
448     if (!CBS_get_asn1(&contents, &bit_string, CBS_ASN1_BITSTRING) ||
449         CBS_len(&contents) != 0) {
450       OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
451       return false;
452     }
453 
454     // This is the KeyUsage extension. See
455     // https://tools.ietf.org/html/rfc5280#section-4.2.1.3
456     if (!CBS_is_valid_asn1_bitstring(&bit_string)) {
457       OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
458       return false;
459     }
460 
461     if (!CBS_asn1_bitstring_has_bit(&bit_string, bit)) {
462       OPENSSL_PUT_ERROR(SSL, SSL_R_KEY_USAGE_BIT_INCORRECT);
463       return false;
464     }
465 
466     return true;
467   }
468 
469   // No KeyUsage extension found.
470   return true;
471 }
472 
SSL_parse_CA_list(SSL * ssl,uint8_t * out_alert,CBS * cbs)473 UniquePtr<STACK_OF(CRYPTO_BUFFER)> SSL_parse_CA_list(SSL *ssl,
474                                                      uint8_t *out_alert,
475                                                      CBS *cbs) {
476   CRYPTO_BUFFER_POOL *const pool = ssl->ctx->pool;
477 
478   UniquePtr<STACK_OF(CRYPTO_BUFFER)> ret(sk_CRYPTO_BUFFER_new_null());
479   if (!ret) {
480     *out_alert = SSL_AD_INTERNAL_ERROR;
481     return nullptr;
482   }
483 
484   CBS child;
485   if (!CBS_get_u16_length_prefixed(cbs, &child)) {
486     *out_alert = SSL_AD_DECODE_ERROR;
487     OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH);
488     return nullptr;
489   }
490 
491   while (CBS_len(&child) > 0) {
492     CBS distinguished_name;
493     if (!CBS_get_u16_length_prefixed(&child, &distinguished_name)) {
494       *out_alert = SSL_AD_DECODE_ERROR;
495       OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_TOO_LONG);
496       return nullptr;
497     }
498 
499     UniquePtr<CRYPTO_BUFFER> buffer(
500         CRYPTO_BUFFER_new_from_CBS(&distinguished_name, pool));
501     if (!buffer ||  //
502         !PushToStack(ret.get(), std::move(buffer))) {
503       *out_alert = SSL_AD_INTERNAL_ERROR;
504       return nullptr;
505     }
506   }
507 
508   if (!ssl->ctx->x509_method->check_CA_list(ret.get())) {
509     *out_alert = SSL_AD_DECODE_ERROR;
510     OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
511     return nullptr;
512   }
513 
514   return ret;
515 }
516 
CA_names_non_empty(const STACK_OF (CRYPTO_BUFFER)* config_names,const STACK_OF (CRYPTO_BUFFER)* ctx_names)517 static bool CA_names_non_empty(const STACK_OF(CRYPTO_BUFFER) *config_names,
518                                const STACK_OF(CRYPTO_BUFFER) *ctx_names) {
519   if (config_names != nullptr) {
520     return sk_CRYPTO_BUFFER_num(config_names) > 0;
521   }
522   if (ctx_names != nullptr) {
523     return sk_CRYPTO_BUFFER_num(ctx_names) > 0;
524   }
525   return false;
526 }
527 
528 
marshal_CA_names(const STACK_OF (CRYPTO_BUFFER)* config_names,const STACK_OF (CRYPTO_BUFFER)* ctx_names,CBB * cbb)529 static bool marshal_CA_names(const STACK_OF(CRYPTO_BUFFER) *config_names,
530                              const STACK_OF(CRYPTO_BUFFER) *ctx_names,
531                              CBB *cbb) {
532   const STACK_OF(CRYPTO_BUFFER) *names =
533       config_names == nullptr ? ctx_names : config_names;
534   CBB child, name_cbb;
535 
536   if (!CBB_add_u16_length_prefixed(cbb, &child)) {
537     return false;
538   }
539 
540   if (names == nullptr) {
541     return CBB_flush(cbb);
542   }
543 
544   for (const CRYPTO_BUFFER *name : names) {
545     if (!CBB_add_u16_length_prefixed(&child, &name_cbb) ||
546         !CBB_add_bytes(&name_cbb, CRYPTO_BUFFER_data(name),
547                        CRYPTO_BUFFER_len(name))) {
548       return false;
549     }
550   }
551 
552   return CBB_flush(cbb);
553 }
554 
ssl_has_client_CAs(const SSL_CONFIG * cfg)555 bool ssl_has_client_CAs(const SSL_CONFIG *cfg) {
556   return CA_names_non_empty(cfg->client_CA.get(),
557                             cfg->ssl->ctx->client_CA.get());
558 }
559 
ssl_has_CA_names(const SSL_CONFIG * cfg)560 bool ssl_has_CA_names(const SSL_CONFIG *cfg) {
561   return CA_names_non_empty(cfg->CA_names.get(), cfg->ssl->ctx->CA_names.get());
562 }
563 
ssl_add_client_CA_list(const SSL_HANDSHAKE * hs,CBB * cbb)564 bool ssl_add_client_CA_list(const SSL_HANDSHAKE *hs, CBB *cbb) {
565   return marshal_CA_names(hs->config->client_CA.get(),
566                           hs->ssl->ctx->client_CA.get(), cbb);
567 }
568 
ssl_add_CA_names(const SSL_HANDSHAKE * hs,CBB * cbb)569 bool ssl_add_CA_names(const SSL_HANDSHAKE *hs, CBB *cbb) {
570   return marshal_CA_names(hs->config->CA_names.get(),
571                           hs->ssl->ctx->CA_names.get(), cbb);
572 }
573 
ssl_check_leaf_certificate(SSL_HANDSHAKE * hs,EVP_PKEY * pkey,const CRYPTO_BUFFER * leaf)574 bool ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey,
575                                 const CRYPTO_BUFFER *leaf) {
576   assert(ssl_protocol_version(hs->ssl) < TLS1_3_VERSION);
577 
578   // Check the certificate's type matches the cipher. This does not check key
579   // usage restrictions, which are handled separately.
580   //
581   // TODO(davidben): Put the key type and key usage checks in one place.
582   if (!(hs->new_cipher->algorithm_auth &
583         ssl_cipher_auth_mask_for_key(pkey, /*sign_ok=*/true))) {
584     OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE);
585     return false;
586   }
587 
588   if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
589     // Check the key's group and point format are acceptable.
590     EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
591     uint16_t group_id;
592     if (!ssl_nid_to_group_id(
593             &group_id, EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key))) ||
594         !tls1_check_group_id(hs, group_id) ||
595         EC_KEY_get_conv_form(ec_key) != POINT_CONVERSION_UNCOMPRESSED) {
596       OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT);
597       return false;
598     }
599   }
600 
601   return true;
602 }
603 
604 BSSL_NAMESPACE_END
605 
606 using namespace bssl;
607 
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)608 int SSL_set_chain_and_key(SSL *ssl, CRYPTO_BUFFER *const *certs,
609                           size_t num_certs, EVP_PKEY *privkey,
610                           const SSL_PRIVATE_KEY_METHOD *privkey_method) {
611   if (!ssl->config) {
612     return 0;
613   }
614   return cert_set_chain_and_key(ssl->config->cert.get(), certs, num_certs,
615                                 privkey, privkey_method);
616 }
617 
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)618 int SSL_CTX_set_chain_and_key(SSL_CTX *ctx, CRYPTO_BUFFER *const *certs,
619                               size_t num_certs, EVP_PKEY *privkey,
620                               const SSL_PRIVATE_KEY_METHOD *privkey_method) {
621   return cert_set_chain_and_key(ctx->cert.get(), certs, num_certs, privkey,
622                                 privkey_method);
623 }
624 
SSL_certs_clear(SSL * ssl)625 void SSL_certs_clear(SSL *ssl) {
626   if (!ssl->config) {
627     return;
628   }
629 
630   CERT *cert = ssl->config->cert.get();
631   cert->x509_method->cert_clear(cert);
632   cert->credentials.clear();
633   cert->legacy_credential->ClearCertAndKey();
634 }
635 
STACK_OF(CRYPTO_BUFFER)636 const STACK_OF(CRYPTO_BUFFER) *SSL_CTX_get0_chain(const SSL_CTX *ctx) {
637   return ctx->cert->legacy_credential->chain.get();
638 }
639 
STACK_OF(CRYPTO_BUFFER)640 const STACK_OF(CRYPTO_BUFFER) *SSL_get0_chain(const SSL *ssl) {
641   if (!ssl->config) {
642     return nullptr;
643   }
644   return ssl->config->cert->legacy_credential->chain.get();
645 }
646 
SSL_CTX_use_certificate_ASN1(SSL_CTX * ctx,size_t der_len,const uint8_t * der)647 int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len,
648                                  const uint8_t *der) {
649   UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(der, der_len, NULL));
650   if (!buffer) {
651     return 0;
652   }
653 
654   return ssl_set_cert(ctx->cert.get(), std::move(buffer));
655 }
656 
SSL_use_certificate_ASN1(SSL * ssl,const uint8_t * der,size_t der_len)657 int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
658   UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(der, der_len, NULL));
659   if (!buffer || !ssl->config) {
660     return 0;
661   }
662 
663   return ssl_set_cert(ssl->config->cert.get(), std::move(buffer));
664 }
665 
SSL_CTX_set_cert_cb(SSL_CTX * ctx,int (* cb)(SSL * ssl,void * arg),void * arg)666 void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg),
667                          void *arg) {
668   ssl_cert_set_cert_cb(ctx->cert.get(), cb, arg);
669 }
670 
SSL_set_cert_cb(SSL * ssl,int (* cb)(SSL * ssl,void * arg),void * arg)671 void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) {
672   if (!ssl->config) {
673     return;
674   }
675   ssl_cert_set_cert_cb(ssl->config->cert.get(), cb, arg);
676 }
677 
STACK_OF(CRYPTO_BUFFER)678 const STACK_OF(CRYPTO_BUFFER) *SSL_get0_peer_certificates(const SSL *ssl) {
679   SSL_SESSION *session = SSL_get_session(ssl);
680   if (session == NULL) {
681     return NULL;
682   }
683 
684   return session->certs.get();
685 }
686 
STACK_OF(CRYPTO_BUFFER)687 const STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs(const SSL *ssl) {
688   if (ssl->s3->hs == NULL) {
689     return NULL;
690   }
691   return ssl->s3->hs->ca_names.get();
692 }
693 
SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX * ctx,const uint8_t * list,size_t list_len)694 int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list,
695                                            size_t list_len) {
696   UniquePtr<CRYPTO_BUFFER> buf(CRYPTO_BUFFER_new(list, list_len, nullptr));
697   return buf != nullptr && SSL_CREDENTIAL_set1_signed_cert_timestamp_list(
698                                ctx->cert->legacy_credential.get(), buf.get());
699 }
700 
SSL_set_signed_cert_timestamp_list(SSL * ssl,const uint8_t * list,size_t list_len)701 int SSL_set_signed_cert_timestamp_list(SSL *ssl, const uint8_t *list,
702                                        size_t list_len) {
703   if (!ssl->config) {
704     return 0;
705   }
706   UniquePtr<CRYPTO_BUFFER> buf(CRYPTO_BUFFER_new(list, list_len, nullptr));
707   return buf != nullptr &&
708          SSL_CREDENTIAL_set1_signed_cert_timestamp_list(
709              ssl->config->cert->legacy_credential.get(), buf.get());
710 }
711 
SSL_CTX_set_ocsp_response(SSL_CTX * ctx,const uint8_t * response,size_t response_len)712 int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response,
713                               size_t response_len) {
714   UniquePtr<CRYPTO_BUFFER> buf(
715       CRYPTO_BUFFER_new(response, response_len, nullptr));
716   return buf != nullptr && SSL_CREDENTIAL_set1_ocsp_response(
717                                ctx->cert->legacy_credential.get(), buf.get());
718 }
719 
SSL_set_ocsp_response(SSL * ssl,const uint8_t * response,size_t response_len)720 int SSL_set_ocsp_response(SSL *ssl, const uint8_t *response,
721                           size_t response_len) {
722   if (!ssl->config) {
723     return 0;
724   }
725   UniquePtr<CRYPTO_BUFFER> buf(
726       CRYPTO_BUFFER_new(response, response_len, nullptr));
727   return buf != nullptr &&
728          SSL_CREDENTIAL_set1_ocsp_response(
729              ssl->config->cert->legacy_credential.get(), buf.get());
730 }
731 
SSL_CTX_set0_client_CAs(SSL_CTX * ctx,STACK_OF (CRYPTO_BUFFER)* name_list)732 void SSL_CTX_set0_client_CAs(SSL_CTX *ctx, STACK_OF(CRYPTO_BUFFER) *name_list) {
733   ctx->x509_method->ssl_ctx_flush_cached_client_CA(ctx);
734   ctx->client_CA.reset(name_list);
735 }
736 
SSL_set0_client_CAs(SSL * ssl,STACK_OF (CRYPTO_BUFFER)* name_list)737 void SSL_set0_client_CAs(SSL *ssl, STACK_OF(CRYPTO_BUFFER) *name_list) {
738   if (!ssl->config) {
739     return;
740   }
741   ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl->config.get());
742   ssl->config->client_CA.reset(name_list);
743 }
744 
SSL_set0_CA_names(SSL * ssl,STACK_OF (CRYPTO_BUFFER)* name_list)745 void SSL_set0_CA_names(SSL *ssl, STACK_OF(CRYPTO_BUFFER) *name_list) {
746   if (!ssl->config) {
747     return;
748   }
749   ssl->config->CA_names.reset(name_list);
750 }
751