xref: /aosp_15_r20/external/boringssl/src/ssl/ssl_x509.cc (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1*8fb009dcSAndroid Build Coastguard Worker /* Copyright (C) 1995-1998 Eric Young ([email protected])
2*8fb009dcSAndroid Build Coastguard Worker  * All rights reserved.
3*8fb009dcSAndroid Build Coastguard Worker  *
4*8fb009dcSAndroid Build Coastguard Worker  * This package is an SSL implementation written
5*8fb009dcSAndroid Build Coastguard Worker  * by Eric Young ([email protected]).
6*8fb009dcSAndroid Build Coastguard Worker  * The implementation was written so as to conform with Netscapes SSL.
7*8fb009dcSAndroid Build Coastguard Worker  *
8*8fb009dcSAndroid Build Coastguard Worker  * This library is free for commercial and non-commercial use as long as
9*8fb009dcSAndroid Build Coastguard Worker  * the following conditions are aheared to.  The following conditions
10*8fb009dcSAndroid Build Coastguard Worker  * apply to all code found in this distribution, be it the RC4, RSA,
11*8fb009dcSAndroid Build Coastguard Worker  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12*8fb009dcSAndroid Build Coastguard Worker  * included with this distribution is covered by the same copyright terms
13*8fb009dcSAndroid Build Coastguard Worker  * except that the holder is Tim Hudson ([email protected]).
14*8fb009dcSAndroid Build Coastguard Worker  *
15*8fb009dcSAndroid Build Coastguard Worker  * Copyright remains Eric Young's, and as such any Copyright notices in
16*8fb009dcSAndroid Build Coastguard Worker  * the code are not to be removed.
17*8fb009dcSAndroid Build Coastguard Worker  * If this package is used in a product, Eric Young should be given attribution
18*8fb009dcSAndroid Build Coastguard Worker  * as the author of the parts of the library used.
19*8fb009dcSAndroid Build Coastguard Worker  * This can be in the form of a textual message at program startup or
20*8fb009dcSAndroid Build Coastguard Worker  * in documentation (online or textual) provided with the package.
21*8fb009dcSAndroid Build Coastguard Worker  *
22*8fb009dcSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
23*8fb009dcSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
24*8fb009dcSAndroid Build Coastguard Worker  * are met:
25*8fb009dcSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the copyright
26*8fb009dcSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
27*8fb009dcSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
28*8fb009dcSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
29*8fb009dcSAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
30*8fb009dcSAndroid Build Coastguard Worker  * 3. All advertising materials mentioning features or use of this software
31*8fb009dcSAndroid Build Coastguard Worker  *    must display the following acknowledgement:
32*8fb009dcSAndroid Build Coastguard Worker  *    "This product includes cryptographic software written by
33*8fb009dcSAndroid Build Coastguard Worker  *     Eric Young ([email protected])"
34*8fb009dcSAndroid Build Coastguard Worker  *    The word 'cryptographic' can be left out if the rouines from the library
35*8fb009dcSAndroid Build Coastguard Worker  *    being used are not cryptographic related :-).
36*8fb009dcSAndroid Build Coastguard Worker  * 4. If you include any Windows specific code (or a derivative thereof) from
37*8fb009dcSAndroid Build Coastguard Worker  *    the apps directory (application code) you must include an acknowledgement:
38*8fb009dcSAndroid Build Coastguard Worker  *    "This product includes software written by Tim Hudson ([email protected])"
39*8fb009dcSAndroid Build Coastguard Worker  *
40*8fb009dcSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41*8fb009dcSAndroid Build Coastguard Worker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42*8fb009dcSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43*8fb009dcSAndroid Build Coastguard Worker  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44*8fb009dcSAndroid Build Coastguard Worker  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45*8fb009dcSAndroid Build Coastguard Worker  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46*8fb009dcSAndroid Build Coastguard Worker  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47*8fb009dcSAndroid Build Coastguard Worker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48*8fb009dcSAndroid Build Coastguard Worker  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49*8fb009dcSAndroid Build Coastguard Worker  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50*8fb009dcSAndroid Build Coastguard Worker  * SUCH DAMAGE.
51*8fb009dcSAndroid Build Coastguard Worker  *
52*8fb009dcSAndroid Build Coastguard Worker  * The licence and distribution terms for any publically available version or
53*8fb009dcSAndroid Build Coastguard Worker  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54*8fb009dcSAndroid Build Coastguard Worker  * copied and put under another distribution licence
55*8fb009dcSAndroid Build Coastguard Worker  * [including the GNU Public Licence.]
56*8fb009dcSAndroid Build Coastguard Worker  */
57*8fb009dcSAndroid Build Coastguard Worker /* ====================================================================
58*8fb009dcSAndroid Build Coastguard Worker  * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
59*8fb009dcSAndroid Build Coastguard Worker  *
60*8fb009dcSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
61*8fb009dcSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
62*8fb009dcSAndroid Build Coastguard Worker  * are met:
63*8fb009dcSAndroid Build Coastguard Worker  *
64*8fb009dcSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
65*8fb009dcSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
66*8fb009dcSAndroid Build Coastguard Worker  *
67*8fb009dcSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
68*8fb009dcSAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in
69*8fb009dcSAndroid Build Coastguard Worker  *    the documentation and/or other materials provided with the
70*8fb009dcSAndroid Build Coastguard Worker  *    distribution.
71*8fb009dcSAndroid Build Coastguard Worker  *
72*8fb009dcSAndroid Build Coastguard Worker  * 3. All advertising materials mentioning features or use of this
73*8fb009dcSAndroid Build Coastguard Worker  *    software must display the following acknowledgment:
74*8fb009dcSAndroid Build Coastguard Worker  *    "This product includes software developed by the OpenSSL Project
75*8fb009dcSAndroid Build Coastguard Worker  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76*8fb009dcSAndroid Build Coastguard Worker  *
77*8fb009dcSAndroid Build Coastguard Worker  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78*8fb009dcSAndroid Build Coastguard Worker  *    endorse or promote products derived from this software without
79*8fb009dcSAndroid Build Coastguard Worker  *    prior written permission. For written permission, please contact
80*8fb009dcSAndroid Build Coastguard Worker  *    [email protected].
81*8fb009dcSAndroid Build Coastguard Worker  *
82*8fb009dcSAndroid Build Coastguard Worker  * 5. Products derived from this software may not be called "OpenSSL"
83*8fb009dcSAndroid Build Coastguard Worker  *    nor may "OpenSSL" appear in their names without prior written
84*8fb009dcSAndroid Build Coastguard Worker  *    permission of the OpenSSL Project.
85*8fb009dcSAndroid Build Coastguard Worker  *
86*8fb009dcSAndroid Build Coastguard Worker  * 6. Redistributions of any form whatsoever must retain the following
87*8fb009dcSAndroid Build Coastguard Worker  *    acknowledgment:
88*8fb009dcSAndroid Build Coastguard Worker  *    "This product includes software developed by the OpenSSL Project
89*8fb009dcSAndroid Build Coastguard Worker  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90*8fb009dcSAndroid Build Coastguard Worker  *
91*8fb009dcSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92*8fb009dcSAndroid Build Coastguard Worker  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93*8fb009dcSAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94*8fb009dcSAndroid Build Coastguard Worker  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
95*8fb009dcSAndroid Build Coastguard Worker  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96*8fb009dcSAndroid Build Coastguard Worker  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97*8fb009dcSAndroid Build Coastguard Worker  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98*8fb009dcSAndroid Build Coastguard Worker  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99*8fb009dcSAndroid Build Coastguard Worker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100*8fb009dcSAndroid Build Coastguard Worker  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101*8fb009dcSAndroid Build Coastguard Worker  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102*8fb009dcSAndroid Build Coastguard Worker  * OF THE POSSIBILITY OF SUCH DAMAGE.
103*8fb009dcSAndroid Build Coastguard Worker  * ====================================================================
104*8fb009dcSAndroid Build Coastguard Worker  *
105*8fb009dcSAndroid Build Coastguard Worker  * This product includes cryptographic software written by Eric Young
106*8fb009dcSAndroid Build Coastguard Worker  * ([email protected]).  This product includes software written by Tim
107*8fb009dcSAndroid Build Coastguard Worker  * Hudson ([email protected]).
108*8fb009dcSAndroid Build Coastguard Worker  *
109*8fb009dcSAndroid Build Coastguard Worker  */
110*8fb009dcSAndroid Build Coastguard Worker /* ====================================================================
111*8fb009dcSAndroid Build Coastguard Worker  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
112*8fb009dcSAndroid Build Coastguard Worker  * ECC cipher suite support in OpenSSL originally developed by
113*8fb009dcSAndroid Build Coastguard Worker  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
114*8fb009dcSAndroid Build Coastguard Worker  */
115*8fb009dcSAndroid Build Coastguard Worker /* ====================================================================
116*8fb009dcSAndroid Build Coastguard Worker  * Copyright 2005 Nokia. All rights reserved.
117*8fb009dcSAndroid Build Coastguard Worker  *
118*8fb009dcSAndroid Build Coastguard Worker  * The portions of the attached software ("Contribution") is developed by
119*8fb009dcSAndroid Build Coastguard Worker  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
120*8fb009dcSAndroid Build Coastguard Worker  * license.
121*8fb009dcSAndroid Build Coastguard Worker  *
122*8fb009dcSAndroid Build Coastguard Worker  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
123*8fb009dcSAndroid Build Coastguard Worker  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
124*8fb009dcSAndroid Build Coastguard Worker  * support (see RFC 4279) to OpenSSL.
125*8fb009dcSAndroid Build Coastguard Worker  *
126*8fb009dcSAndroid Build Coastguard Worker  * No patent licenses or other rights except those expressly stated in
127*8fb009dcSAndroid Build Coastguard Worker  * the OpenSSL open source license shall be deemed granted or received
128*8fb009dcSAndroid Build Coastguard Worker  * expressly, by implication, estoppel, or otherwise.
129*8fb009dcSAndroid Build Coastguard Worker  *
130*8fb009dcSAndroid Build Coastguard Worker  * No assurances are provided by Nokia that the Contribution does not
131*8fb009dcSAndroid Build Coastguard Worker  * infringe the patent or other intellectual property rights of any third
132*8fb009dcSAndroid Build Coastguard Worker  * party or that the license provides you with all the necessary rights
133*8fb009dcSAndroid Build Coastguard Worker  * to make use of the Contribution.
134*8fb009dcSAndroid Build Coastguard Worker  *
135*8fb009dcSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
136*8fb009dcSAndroid Build Coastguard Worker  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
137*8fb009dcSAndroid Build Coastguard Worker  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
138*8fb009dcSAndroid Build Coastguard Worker  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
139*8fb009dcSAndroid Build Coastguard Worker  * OTHERWISE. */
140*8fb009dcSAndroid Build Coastguard Worker 
141*8fb009dcSAndroid Build Coastguard Worker #include <openssl/ssl.h>
142*8fb009dcSAndroid Build Coastguard Worker 
143*8fb009dcSAndroid Build Coastguard Worker #include <assert.h>
144*8fb009dcSAndroid Build Coastguard Worker 
145*8fb009dcSAndroid Build Coastguard Worker #include <openssl/asn1.h>
146*8fb009dcSAndroid Build Coastguard Worker #include <openssl/bytestring.h>
147*8fb009dcSAndroid Build Coastguard Worker #include <openssl/err.h>
148*8fb009dcSAndroid Build Coastguard Worker #include <openssl/pem.h>
149*8fb009dcSAndroid Build Coastguard Worker #include <openssl/stack.h>
150*8fb009dcSAndroid Build Coastguard Worker #include <openssl/x509.h>
151*8fb009dcSAndroid Build Coastguard Worker 
152*8fb009dcSAndroid Build Coastguard Worker #include "internal.h"
153*8fb009dcSAndroid Build Coastguard Worker #include "../crypto/internal.h"
154*8fb009dcSAndroid Build Coastguard Worker 
155*8fb009dcSAndroid Build Coastguard Worker 
156*8fb009dcSAndroid Build Coastguard Worker BSSL_NAMESPACE_BEGIN
157*8fb009dcSAndroid Build Coastguard Worker 
158*8fb009dcSAndroid Build Coastguard Worker // check_ssl_x509_method asserts that |ssl| has the X509-based method
159*8fb009dcSAndroid Build Coastguard Worker // installed. Calling an X509-based method on an |ssl| with a different method
160*8fb009dcSAndroid Build Coastguard Worker // will likely misbehave and possibly crash or leak memory.
check_ssl_x509_method(const SSL * ssl)161*8fb009dcSAndroid Build Coastguard Worker static void check_ssl_x509_method(const SSL *ssl) {
162*8fb009dcSAndroid Build Coastguard Worker   assert(ssl == NULL || ssl->ctx->x509_method == &ssl_crypto_x509_method);
163*8fb009dcSAndroid Build Coastguard Worker }
164*8fb009dcSAndroid Build Coastguard Worker 
165*8fb009dcSAndroid Build Coastguard Worker // check_ssl_ctx_x509_method acts like |check_ssl_x509_method|, but for an
166*8fb009dcSAndroid Build Coastguard Worker // |SSL_CTX|.
check_ssl_ctx_x509_method(const SSL_CTX * ctx)167*8fb009dcSAndroid Build Coastguard Worker static void check_ssl_ctx_x509_method(const SSL_CTX *ctx) {
168*8fb009dcSAndroid Build Coastguard Worker   assert(ctx == NULL || ctx->x509_method == &ssl_crypto_x509_method);
169*8fb009dcSAndroid Build Coastguard Worker }
170*8fb009dcSAndroid Build Coastguard Worker 
171*8fb009dcSAndroid Build Coastguard Worker // x509_to_buffer returns a |CRYPTO_BUFFER| that contains the serialised
172*8fb009dcSAndroid Build Coastguard Worker // contents of |x509|.
x509_to_buffer(X509 * x509)173*8fb009dcSAndroid Build Coastguard Worker static UniquePtr<CRYPTO_BUFFER> x509_to_buffer(X509 *x509) {
174*8fb009dcSAndroid Build Coastguard Worker   uint8_t *buf = NULL;
175*8fb009dcSAndroid Build Coastguard Worker   int cert_len = i2d_X509(x509, &buf);
176*8fb009dcSAndroid Build Coastguard Worker   if (cert_len <= 0) {
177*8fb009dcSAndroid Build Coastguard Worker     return 0;
178*8fb009dcSAndroid Build Coastguard Worker   }
179*8fb009dcSAndroid Build Coastguard Worker 
180*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(buf, cert_len, NULL));
181*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_free(buf);
182*8fb009dcSAndroid Build Coastguard Worker 
183*8fb009dcSAndroid Build Coastguard Worker   return buffer;
184*8fb009dcSAndroid Build Coastguard Worker }
185*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_cert_flush_cached_leaf(CERT * cert)186*8fb009dcSAndroid Build Coastguard Worker static void ssl_crypto_x509_cert_flush_cached_leaf(CERT *cert) {
187*8fb009dcSAndroid Build Coastguard Worker   X509_free(cert->x509_leaf);
188*8fb009dcSAndroid Build Coastguard Worker   cert->x509_leaf = nullptr;
189*8fb009dcSAndroid Build Coastguard Worker }
190*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_cert_flush_cached_chain(CERT * cert)191*8fb009dcSAndroid Build Coastguard Worker static void ssl_crypto_x509_cert_flush_cached_chain(CERT *cert) {
192*8fb009dcSAndroid Build Coastguard Worker   sk_X509_pop_free(cert->x509_chain, X509_free);
193*8fb009dcSAndroid Build Coastguard Worker   cert->x509_chain = nullptr;
194*8fb009dcSAndroid Build Coastguard Worker }
195*8fb009dcSAndroid Build Coastguard Worker 
196*8fb009dcSAndroid Build Coastguard Worker // ssl_cert_set1_chain sets elements 1.. of |cert->chain| to the serialised
197*8fb009dcSAndroid Build Coastguard Worker // forms of elements of |chain|. It returns one on success or zero on error, in
198*8fb009dcSAndroid Build Coastguard Worker // which case no change to |cert->chain| is made. It preverses the existing
199*8fb009dcSAndroid Build Coastguard Worker // leaf from |cert->chain|, if any.
ssl_cert_set1_chain(CERT * cert,STACK_OF (X509)* chain)200*8fb009dcSAndroid Build Coastguard Worker static bool ssl_cert_set1_chain(CERT *cert, STACK_OF(X509) *chain) {
201*8fb009dcSAndroid Build Coastguard Worker   cert->default_credential->ClearIntermediateCerts();
202*8fb009dcSAndroid Build Coastguard Worker   for (X509 *x509 : chain) {
203*8fb009dcSAndroid Build Coastguard Worker     UniquePtr<CRYPTO_BUFFER> buffer = x509_to_buffer(x509);
204*8fb009dcSAndroid Build Coastguard Worker     if (!buffer ||
205*8fb009dcSAndroid Build Coastguard Worker         !cert->default_credential->AppendIntermediateCert(std::move(buffer))) {
206*8fb009dcSAndroid Build Coastguard Worker       return false;
207*8fb009dcSAndroid Build Coastguard Worker     }
208*8fb009dcSAndroid Build Coastguard Worker   }
209*8fb009dcSAndroid Build Coastguard Worker 
210*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_cert_flush_cached_chain(cert);
211*8fb009dcSAndroid Build Coastguard Worker   return true;
212*8fb009dcSAndroid Build Coastguard Worker }
213*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_check_client_CA_list(STACK_OF (CRYPTO_BUFFER)* names)214*8fb009dcSAndroid Build Coastguard Worker static bool ssl_crypto_x509_check_client_CA_list(
215*8fb009dcSAndroid Build Coastguard Worker     STACK_OF(CRYPTO_BUFFER) *names) {
216*8fb009dcSAndroid Build Coastguard Worker   for (const CRYPTO_BUFFER *buffer : names) {
217*8fb009dcSAndroid Build Coastguard Worker     const uint8_t *inp = CRYPTO_BUFFER_data(buffer);
218*8fb009dcSAndroid Build Coastguard Worker     UniquePtr<X509_NAME> name(
219*8fb009dcSAndroid Build Coastguard Worker         d2i_X509_NAME(nullptr, &inp, CRYPTO_BUFFER_len(buffer)));
220*8fb009dcSAndroid Build Coastguard Worker     if (name == nullptr ||
221*8fb009dcSAndroid Build Coastguard Worker         inp != CRYPTO_BUFFER_data(buffer) + CRYPTO_BUFFER_len(buffer)) {
222*8fb009dcSAndroid Build Coastguard Worker       return false;
223*8fb009dcSAndroid Build Coastguard Worker     }
224*8fb009dcSAndroid Build Coastguard Worker   }
225*8fb009dcSAndroid Build Coastguard Worker 
226*8fb009dcSAndroid Build Coastguard Worker   return true;
227*8fb009dcSAndroid Build Coastguard Worker }
228*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_cert_clear(CERT * cert)229*8fb009dcSAndroid Build Coastguard Worker static void ssl_crypto_x509_cert_clear(CERT *cert) {
230*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_cert_flush_cached_leaf(cert);
231*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_cert_flush_cached_chain(cert);
232*8fb009dcSAndroid Build Coastguard Worker 
233*8fb009dcSAndroid Build Coastguard Worker   X509_free(cert->x509_stash);
234*8fb009dcSAndroid Build Coastguard Worker   cert->x509_stash = nullptr;
235*8fb009dcSAndroid Build Coastguard Worker }
236*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_cert_free(CERT * cert)237*8fb009dcSAndroid Build Coastguard Worker static void ssl_crypto_x509_cert_free(CERT *cert) {
238*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_cert_clear(cert);
239*8fb009dcSAndroid Build Coastguard Worker   X509_STORE_free(cert->verify_store);
240*8fb009dcSAndroid Build Coastguard Worker }
241*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_cert_dup(CERT * new_cert,const CERT * cert)242*8fb009dcSAndroid Build Coastguard Worker static void ssl_crypto_x509_cert_dup(CERT *new_cert, const CERT *cert) {
243*8fb009dcSAndroid Build Coastguard Worker   if (cert->verify_store != nullptr) {
244*8fb009dcSAndroid Build Coastguard Worker     X509_STORE_up_ref(cert->verify_store);
245*8fb009dcSAndroid Build Coastguard Worker     new_cert->verify_store = cert->verify_store;
246*8fb009dcSAndroid Build Coastguard Worker   }
247*8fb009dcSAndroid Build Coastguard Worker }
248*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_session_cache_objects(SSL_SESSION * sess)249*8fb009dcSAndroid Build Coastguard Worker static bool ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) {
250*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<STACK_OF(X509)> chain, chain_without_leaf;
251*8fb009dcSAndroid Build Coastguard Worker   if (sk_CRYPTO_BUFFER_num(sess->certs.get()) > 0) {
252*8fb009dcSAndroid Build Coastguard Worker     chain.reset(sk_X509_new_null());
253*8fb009dcSAndroid Build Coastguard Worker     if (!chain) {
254*8fb009dcSAndroid Build Coastguard Worker       return false;
255*8fb009dcSAndroid Build Coastguard Worker     }
256*8fb009dcSAndroid Build Coastguard Worker     if (sess->is_server) {
257*8fb009dcSAndroid Build Coastguard Worker       // chain_without_leaf is only needed for server sessions. See
258*8fb009dcSAndroid Build Coastguard Worker       // |SSL_get_peer_cert_chain|.
259*8fb009dcSAndroid Build Coastguard Worker       chain_without_leaf.reset(sk_X509_new_null());
260*8fb009dcSAndroid Build Coastguard Worker       if (!chain_without_leaf) {
261*8fb009dcSAndroid Build Coastguard Worker         return false;
262*8fb009dcSAndroid Build Coastguard Worker       }
263*8fb009dcSAndroid Build Coastguard Worker     }
264*8fb009dcSAndroid Build Coastguard Worker   }
265*8fb009dcSAndroid Build Coastguard Worker 
266*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> leaf;
267*8fb009dcSAndroid Build Coastguard Worker   for (CRYPTO_BUFFER *cert : sess->certs.get()) {
268*8fb009dcSAndroid Build Coastguard Worker     UniquePtr<X509> x509(X509_parse_from_buffer(cert));
269*8fb009dcSAndroid Build Coastguard Worker     if (!x509) {
270*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
271*8fb009dcSAndroid Build Coastguard Worker       return false;
272*8fb009dcSAndroid Build Coastguard Worker     }
273*8fb009dcSAndroid Build Coastguard Worker     if (leaf == nullptr) {
274*8fb009dcSAndroid Build Coastguard Worker       leaf = UpRef(x509);
275*8fb009dcSAndroid Build Coastguard Worker     } else if (chain_without_leaf &&
276*8fb009dcSAndroid Build Coastguard Worker                !PushToStack(chain_without_leaf.get(), UpRef(x509))) {
277*8fb009dcSAndroid Build Coastguard Worker       return false;
278*8fb009dcSAndroid Build Coastguard Worker     }
279*8fb009dcSAndroid Build Coastguard Worker     if (!PushToStack(chain.get(), std::move(x509))) {
280*8fb009dcSAndroid Build Coastguard Worker       return false;
281*8fb009dcSAndroid Build Coastguard Worker     }
282*8fb009dcSAndroid Build Coastguard Worker   }
283*8fb009dcSAndroid Build Coastguard Worker 
284*8fb009dcSAndroid Build Coastguard Worker   sk_X509_pop_free(sess->x509_chain, X509_free);
285*8fb009dcSAndroid Build Coastguard Worker   sess->x509_chain = chain.release();
286*8fb009dcSAndroid Build Coastguard Worker 
287*8fb009dcSAndroid Build Coastguard Worker   sk_X509_pop_free(sess->x509_chain_without_leaf, X509_free);
288*8fb009dcSAndroid Build Coastguard Worker   sess->x509_chain_without_leaf = chain_without_leaf.release();
289*8fb009dcSAndroid Build Coastguard Worker 
290*8fb009dcSAndroid Build Coastguard Worker   X509_free(sess->x509_peer);
291*8fb009dcSAndroid Build Coastguard Worker   sess->x509_peer = leaf.release();
292*8fb009dcSAndroid Build Coastguard Worker   return true;
293*8fb009dcSAndroid Build Coastguard Worker }
294*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_session_dup(SSL_SESSION * new_session,const SSL_SESSION * session)295*8fb009dcSAndroid Build Coastguard Worker static bool ssl_crypto_x509_session_dup(SSL_SESSION *new_session,
296*8fb009dcSAndroid Build Coastguard Worker                                         const SSL_SESSION *session) {
297*8fb009dcSAndroid Build Coastguard Worker   new_session->x509_peer = UpRef(session->x509_peer).release();
298*8fb009dcSAndroid Build Coastguard Worker   if (session->x509_chain != nullptr) {
299*8fb009dcSAndroid Build Coastguard Worker     new_session->x509_chain = X509_chain_up_ref(session->x509_chain);
300*8fb009dcSAndroid Build Coastguard Worker     if (new_session->x509_chain == nullptr) {
301*8fb009dcSAndroid Build Coastguard Worker       return false;
302*8fb009dcSAndroid Build Coastguard Worker     }
303*8fb009dcSAndroid Build Coastguard Worker   }
304*8fb009dcSAndroid Build Coastguard Worker   if (session->x509_chain_without_leaf != nullptr) {
305*8fb009dcSAndroid Build Coastguard Worker     new_session->x509_chain_without_leaf =
306*8fb009dcSAndroid Build Coastguard Worker         X509_chain_up_ref(session->x509_chain_without_leaf);
307*8fb009dcSAndroid Build Coastguard Worker     if (new_session->x509_chain_without_leaf == nullptr) {
308*8fb009dcSAndroid Build Coastguard Worker       return false;
309*8fb009dcSAndroid Build Coastguard Worker     }
310*8fb009dcSAndroid Build Coastguard Worker   }
311*8fb009dcSAndroid Build Coastguard Worker 
312*8fb009dcSAndroid Build Coastguard Worker   return true;
313*8fb009dcSAndroid Build Coastguard Worker }
314*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_session_clear(SSL_SESSION * session)315*8fb009dcSAndroid Build Coastguard Worker static void ssl_crypto_x509_session_clear(SSL_SESSION *session) {
316*8fb009dcSAndroid Build Coastguard Worker   X509_free(session->x509_peer);
317*8fb009dcSAndroid Build Coastguard Worker   session->x509_peer = nullptr;
318*8fb009dcSAndroid Build Coastguard Worker   sk_X509_pop_free(session->x509_chain, X509_free);
319*8fb009dcSAndroid Build Coastguard Worker   session->x509_chain = nullptr;
320*8fb009dcSAndroid Build Coastguard Worker   sk_X509_pop_free(session->x509_chain_without_leaf, X509_free);
321*8fb009dcSAndroid Build Coastguard Worker   session->x509_chain_without_leaf = nullptr;
322*8fb009dcSAndroid Build Coastguard Worker }
323*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_session_verify_cert_chain(SSL_SESSION * session,SSL_HANDSHAKE * hs,uint8_t * out_alert)324*8fb009dcSAndroid Build Coastguard Worker static bool ssl_crypto_x509_session_verify_cert_chain(SSL_SESSION *session,
325*8fb009dcSAndroid Build Coastguard Worker                                                       SSL_HANDSHAKE *hs,
326*8fb009dcSAndroid Build Coastguard Worker                                                       uint8_t *out_alert) {
327*8fb009dcSAndroid Build Coastguard Worker   *out_alert = SSL_AD_INTERNAL_ERROR;
328*8fb009dcSAndroid Build Coastguard Worker   STACK_OF(X509) *const cert_chain = session->x509_chain;
329*8fb009dcSAndroid Build Coastguard Worker   if (cert_chain == nullptr || sk_X509_num(cert_chain) == 0) {
330*8fb009dcSAndroid Build Coastguard Worker     return false;
331*8fb009dcSAndroid Build Coastguard Worker   }
332*8fb009dcSAndroid Build Coastguard Worker 
333*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
334*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX *ssl_ctx = ssl->ctx.get();
335*8fb009dcSAndroid Build Coastguard Worker   X509_STORE *verify_store = ssl_ctx->cert_store;
336*8fb009dcSAndroid Build Coastguard Worker   if (hs->config->cert->verify_store != nullptr) {
337*8fb009dcSAndroid Build Coastguard Worker     verify_store = hs->config->cert->verify_store;
338*8fb009dcSAndroid Build Coastguard Worker   }
339*8fb009dcSAndroid Build Coastguard Worker 
340*8fb009dcSAndroid Build Coastguard Worker   X509 *leaf = sk_X509_value(cert_chain, 0);
341*8fb009dcSAndroid Build Coastguard Worker   const char *name;
342*8fb009dcSAndroid Build Coastguard Worker   size_t name_len;
343*8fb009dcSAndroid Build Coastguard Worker   SSL_get0_ech_name_override(ssl, &name, &name_len);
344*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<X509_STORE_CTX> ctx(X509_STORE_CTX_new());
345*8fb009dcSAndroid Build Coastguard Worker   if (!ctx ||
346*8fb009dcSAndroid Build Coastguard Worker       !X509_STORE_CTX_init(ctx.get(), verify_store, leaf, cert_chain) ||
347*8fb009dcSAndroid Build Coastguard Worker       !X509_STORE_CTX_set_ex_data(ctx.get(),
348*8fb009dcSAndroid Build Coastguard Worker                                   SSL_get_ex_data_X509_STORE_CTX_idx(), ssl) ||
349*8fb009dcSAndroid Build Coastguard Worker       // We need to inherit the verify parameters. These can be determined by
350*8fb009dcSAndroid Build Coastguard Worker       // the context: if its a server it will verify SSL client certificates or
351*8fb009dcSAndroid Build Coastguard Worker       // vice versa.
352*8fb009dcSAndroid Build Coastguard Worker       !X509_STORE_CTX_set_default(ctx.get(),
353*8fb009dcSAndroid Build Coastguard Worker                                   ssl->server ? "ssl_client" : "ssl_server") ||
354*8fb009dcSAndroid Build Coastguard Worker       // Anything non-default in "param" should overwrite anything in the ctx.
355*8fb009dcSAndroid Build Coastguard Worker       !X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(ctx.get()),
356*8fb009dcSAndroid Build Coastguard Worker                               hs->config->param) ||
357*8fb009dcSAndroid Build Coastguard Worker       // ClientHelloOuter connections use a different name.
358*8fb009dcSAndroid Build Coastguard Worker       (name_len != 0 &&
359*8fb009dcSAndroid Build Coastguard Worker        !X509_VERIFY_PARAM_set1_host(X509_STORE_CTX_get0_param(ctx.get()), name,
360*8fb009dcSAndroid Build Coastguard Worker                                     name_len))) {
361*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
362*8fb009dcSAndroid Build Coastguard Worker     return false;
363*8fb009dcSAndroid Build Coastguard Worker   }
364*8fb009dcSAndroid Build Coastguard Worker 
365*8fb009dcSAndroid Build Coastguard Worker   if (hs->config->verify_callback) {
366*8fb009dcSAndroid Build Coastguard Worker     X509_STORE_CTX_set_verify_cb(ctx.get(), hs->config->verify_callback);
367*8fb009dcSAndroid Build Coastguard Worker   }
368*8fb009dcSAndroid Build Coastguard Worker 
369*8fb009dcSAndroid Build Coastguard Worker   int verify_ret;
370*8fb009dcSAndroid Build Coastguard Worker   if (ssl_ctx->app_verify_callback != nullptr) {
371*8fb009dcSAndroid Build Coastguard Worker     verify_ret =
372*8fb009dcSAndroid Build Coastguard Worker         ssl_ctx->app_verify_callback(ctx.get(), ssl_ctx->app_verify_arg);
373*8fb009dcSAndroid Build Coastguard Worker   } else {
374*8fb009dcSAndroid Build Coastguard Worker     verify_ret = X509_verify_cert(ctx.get());
375*8fb009dcSAndroid Build Coastguard Worker   }
376*8fb009dcSAndroid Build Coastguard Worker 
377*8fb009dcSAndroid Build Coastguard Worker   session->verify_result = X509_STORE_CTX_get_error(ctx.get());
378*8fb009dcSAndroid Build Coastguard Worker 
379*8fb009dcSAndroid Build Coastguard Worker   // If |SSL_VERIFY_NONE|, the error is non-fatal, but we keep the result.
380*8fb009dcSAndroid Build Coastguard Worker   if (verify_ret <= 0 && hs->config->verify_mode != SSL_VERIFY_NONE) {
381*8fb009dcSAndroid Build Coastguard Worker     *out_alert = SSL_alert_from_verify_result(session->verify_result);
382*8fb009dcSAndroid Build Coastguard Worker     return false;
383*8fb009dcSAndroid Build Coastguard Worker   }
384*8fb009dcSAndroid Build Coastguard Worker 
385*8fb009dcSAndroid Build Coastguard Worker   ERR_clear_error();
386*8fb009dcSAndroid Build Coastguard Worker   return true;
387*8fb009dcSAndroid Build Coastguard Worker }
388*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_hs_flush_cached_ca_names(SSL_HANDSHAKE * hs)389*8fb009dcSAndroid Build Coastguard Worker static void ssl_crypto_x509_hs_flush_cached_ca_names(SSL_HANDSHAKE *hs) {
390*8fb009dcSAndroid Build Coastguard Worker   sk_X509_NAME_pop_free(hs->cached_x509_ca_names, X509_NAME_free);
391*8fb009dcSAndroid Build Coastguard Worker   hs->cached_x509_ca_names = nullptr;
392*8fb009dcSAndroid Build Coastguard Worker }
393*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_ssl_new(SSL_HANDSHAKE * hs)394*8fb009dcSAndroid Build Coastguard Worker static bool ssl_crypto_x509_ssl_new(SSL_HANDSHAKE *hs) {
395*8fb009dcSAndroid Build Coastguard Worker   hs->config->param = X509_VERIFY_PARAM_new();
396*8fb009dcSAndroid Build Coastguard Worker   if (hs->config->param == nullptr) {
397*8fb009dcSAndroid Build Coastguard Worker     return false;
398*8fb009dcSAndroid Build Coastguard Worker   }
399*8fb009dcSAndroid Build Coastguard Worker   X509_VERIFY_PARAM_inherit(hs->config->param, hs->ssl->ctx->param);
400*8fb009dcSAndroid Build Coastguard Worker   return true;
401*8fb009dcSAndroid Build Coastguard Worker }
402*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_ssl_flush_cached_client_CA(SSL_CONFIG * cfg)403*8fb009dcSAndroid Build Coastguard Worker static void ssl_crypto_x509_ssl_flush_cached_client_CA(SSL_CONFIG *cfg) {
404*8fb009dcSAndroid Build Coastguard Worker   sk_X509_NAME_pop_free(cfg->cached_x509_client_CA, X509_NAME_free);
405*8fb009dcSAndroid Build Coastguard Worker   cfg->cached_x509_client_CA = nullptr;
406*8fb009dcSAndroid Build Coastguard Worker }
407*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_ssl_config_free(SSL_CONFIG * cfg)408*8fb009dcSAndroid Build Coastguard Worker static void ssl_crypto_x509_ssl_config_free(SSL_CONFIG *cfg) {
409*8fb009dcSAndroid Build Coastguard Worker   sk_X509_NAME_pop_free(cfg->cached_x509_client_CA, X509_NAME_free);
410*8fb009dcSAndroid Build Coastguard Worker   cfg->cached_x509_client_CA = nullptr;
411*8fb009dcSAndroid Build Coastguard Worker   X509_VERIFY_PARAM_free(cfg->param);
412*8fb009dcSAndroid Build Coastguard Worker }
413*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_ssl_auto_chain_if_needed(SSL_HANDSHAKE * hs)414*8fb009dcSAndroid Build Coastguard Worker static bool ssl_crypto_x509_ssl_auto_chain_if_needed(SSL_HANDSHAKE *hs) {
415*8fb009dcSAndroid Build Coastguard Worker   // Only build a chain if the feature isn't disabled, the default credential
416*8fb009dcSAndroid Build Coastguard Worker   // exists but has no intermediates configured.
417*8fb009dcSAndroid Build Coastguard Worker   SSL *ssl = hs->ssl;
418*8fb009dcSAndroid Build Coastguard Worker   SSL_CREDENTIAL *cred = hs->config->cert->default_credential.get();
419*8fb009dcSAndroid Build Coastguard Worker   if ((ssl->mode & SSL_MODE_NO_AUTO_CHAIN) || !cred->IsComplete() ||
420*8fb009dcSAndroid Build Coastguard Worker       sk_CRYPTO_BUFFER_num(cred->chain.get()) != 1) {
421*8fb009dcSAndroid Build Coastguard Worker     return true;
422*8fb009dcSAndroid Build Coastguard Worker   }
423*8fb009dcSAndroid Build Coastguard Worker 
424*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<X509> leaf(
425*8fb009dcSAndroid Build Coastguard Worker       X509_parse_from_buffer(sk_CRYPTO_BUFFER_value(cred->chain.get(), 0)));
426*8fb009dcSAndroid Build Coastguard Worker   if (!leaf) {
427*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
428*8fb009dcSAndroid Build Coastguard Worker     return false;
429*8fb009dcSAndroid Build Coastguard Worker   }
430*8fb009dcSAndroid Build Coastguard Worker 
431*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<X509_STORE_CTX> ctx(X509_STORE_CTX_new());
432*8fb009dcSAndroid Build Coastguard Worker   if (!ctx || !X509_STORE_CTX_init(ctx.get(), ssl->ctx->cert_store, leaf.get(),
433*8fb009dcSAndroid Build Coastguard Worker                                    nullptr)) {
434*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
435*8fb009dcSAndroid Build Coastguard Worker     return false;
436*8fb009dcSAndroid Build Coastguard Worker   }
437*8fb009dcSAndroid Build Coastguard Worker 
438*8fb009dcSAndroid Build Coastguard Worker   // Attempt to build a chain, ignoring the result.
439*8fb009dcSAndroid Build Coastguard Worker   X509_verify_cert(ctx.get());
440*8fb009dcSAndroid Build Coastguard Worker   ERR_clear_error();
441*8fb009dcSAndroid Build Coastguard Worker 
442*8fb009dcSAndroid Build Coastguard Worker   // Remove the leaf from the generated chain.
443*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<STACK_OF(X509)> chain(X509_STORE_CTX_get1_chain(ctx.get()));
444*8fb009dcSAndroid Build Coastguard Worker   if (!chain) {
445*8fb009dcSAndroid Build Coastguard Worker     return false;
446*8fb009dcSAndroid Build Coastguard Worker   }
447*8fb009dcSAndroid Build Coastguard Worker   X509_free(sk_X509_shift(chain.get()));
448*8fb009dcSAndroid Build Coastguard Worker 
449*8fb009dcSAndroid Build Coastguard Worker   return SSL_set1_chain(ssl, chain.get());
450*8fb009dcSAndroid Build Coastguard Worker }
451*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(SSL_CTX * ctx)452*8fb009dcSAndroid Build Coastguard Worker static void ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(SSL_CTX *ctx) {
453*8fb009dcSAndroid Build Coastguard Worker   sk_X509_NAME_pop_free(ctx->cached_x509_client_CA, X509_NAME_free);
454*8fb009dcSAndroid Build Coastguard Worker   ctx->cached_x509_client_CA = nullptr;
455*8fb009dcSAndroid Build Coastguard Worker }
456*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_ssl_ctx_new(SSL_CTX * ctx)457*8fb009dcSAndroid Build Coastguard Worker static bool ssl_crypto_x509_ssl_ctx_new(SSL_CTX *ctx) {
458*8fb009dcSAndroid Build Coastguard Worker   ctx->cert_store = X509_STORE_new();
459*8fb009dcSAndroid Build Coastguard Worker   ctx->param = X509_VERIFY_PARAM_new();
460*8fb009dcSAndroid Build Coastguard Worker   return (ctx->cert_store != nullptr && ctx->param != nullptr);
461*8fb009dcSAndroid Build Coastguard Worker }
462*8fb009dcSAndroid Build Coastguard Worker 
ssl_crypto_x509_ssl_ctx_free(SSL_CTX * ctx)463*8fb009dcSAndroid Build Coastguard Worker static void ssl_crypto_x509_ssl_ctx_free(SSL_CTX *ctx) {
464*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(ctx);
465*8fb009dcSAndroid Build Coastguard Worker   X509_VERIFY_PARAM_free(ctx->param);
466*8fb009dcSAndroid Build Coastguard Worker   X509_STORE_free(ctx->cert_store);
467*8fb009dcSAndroid Build Coastguard Worker }
468*8fb009dcSAndroid Build Coastguard Worker 
469*8fb009dcSAndroid Build Coastguard Worker const SSL_X509_METHOD ssl_crypto_x509_method = {
470*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_check_client_CA_list,
471*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_cert_clear,
472*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_cert_free,
473*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_cert_dup,
474*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_cert_flush_cached_chain,
475*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_cert_flush_cached_leaf,
476*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_session_cache_objects,
477*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_session_dup,
478*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_session_clear,
479*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_session_verify_cert_chain,
480*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_hs_flush_cached_ca_names,
481*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_ssl_new,
482*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_ssl_config_free,
483*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_ssl_flush_cached_client_CA,
484*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_ssl_auto_chain_if_needed,
485*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_ssl_ctx_new,
486*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_ssl_ctx_free,
487*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_ssl_ctx_flush_cached_client_CA,
488*8fb009dcSAndroid Build Coastguard Worker };
489*8fb009dcSAndroid Build Coastguard Worker 
490*8fb009dcSAndroid Build Coastguard Worker BSSL_NAMESPACE_END
491*8fb009dcSAndroid Build Coastguard Worker 
492*8fb009dcSAndroid Build Coastguard Worker using namespace bssl;
493*8fb009dcSAndroid Build Coastguard Worker 
SSL_get_peer_certificate(const SSL * ssl)494*8fb009dcSAndroid Build Coastguard Worker X509 *SSL_get_peer_certificate(const SSL *ssl) {
495*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
496*8fb009dcSAndroid Build Coastguard Worker   if (ssl == NULL) {
497*8fb009dcSAndroid Build Coastguard Worker     return NULL;
498*8fb009dcSAndroid Build Coastguard Worker   }
499*8fb009dcSAndroid Build Coastguard Worker   SSL_SESSION *session = SSL_get_session(ssl);
500*8fb009dcSAndroid Build Coastguard Worker   if (session == NULL || session->x509_peer == NULL) {
501*8fb009dcSAndroid Build Coastguard Worker     return NULL;
502*8fb009dcSAndroid Build Coastguard Worker   }
503*8fb009dcSAndroid Build Coastguard Worker   X509_up_ref(session->x509_peer);
504*8fb009dcSAndroid Build Coastguard Worker   return session->x509_peer;
505*8fb009dcSAndroid Build Coastguard Worker }
506*8fb009dcSAndroid Build Coastguard Worker 
STACK_OF(X509)507*8fb009dcSAndroid Build Coastguard Worker STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) {
508*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
509*8fb009dcSAndroid Build Coastguard Worker   if (ssl == nullptr) {
510*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
511*8fb009dcSAndroid Build Coastguard Worker   }
512*8fb009dcSAndroid Build Coastguard Worker   SSL_SESSION *session = SSL_get_session(ssl);
513*8fb009dcSAndroid Build Coastguard Worker   if (session == nullptr) {
514*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
515*8fb009dcSAndroid Build Coastguard Worker   }
516*8fb009dcSAndroid Build Coastguard Worker 
517*8fb009dcSAndroid Build Coastguard Worker   // OpenSSL historically didn't include the leaf certificate in the returned
518*8fb009dcSAndroid Build Coastguard Worker   // certificate chain, but only for servers.
519*8fb009dcSAndroid Build Coastguard Worker   return ssl->server ? session->x509_chain_without_leaf : session->x509_chain;
520*8fb009dcSAndroid Build Coastguard Worker }
521*8fb009dcSAndroid Build Coastguard Worker 
STACK_OF(X509)522*8fb009dcSAndroid Build Coastguard Worker STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl) {
523*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
524*8fb009dcSAndroid Build Coastguard Worker   SSL_SESSION *session = SSL_get_session(ssl);
525*8fb009dcSAndroid Build Coastguard Worker   if (session == NULL) {
526*8fb009dcSAndroid Build Coastguard Worker     return NULL;
527*8fb009dcSAndroid Build Coastguard Worker   }
528*8fb009dcSAndroid Build Coastguard Worker 
529*8fb009dcSAndroid Build Coastguard Worker   return session->x509_chain;
530*8fb009dcSAndroid Build Coastguard Worker }
531*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set_purpose(SSL_CTX * ctx,int purpose)532*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) {
533*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
534*8fb009dcSAndroid Build Coastguard Worker   return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
535*8fb009dcSAndroid Build Coastguard Worker }
536*8fb009dcSAndroid Build Coastguard Worker 
SSL_set_purpose(SSL * ssl,int purpose)537*8fb009dcSAndroid Build Coastguard Worker int SSL_set_purpose(SSL *ssl, int purpose) {
538*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
539*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
540*8fb009dcSAndroid Build Coastguard Worker     return 0;
541*8fb009dcSAndroid Build Coastguard Worker   }
542*8fb009dcSAndroid Build Coastguard Worker   return X509_VERIFY_PARAM_set_purpose(ssl->config->param, purpose);
543*8fb009dcSAndroid Build Coastguard Worker }
544*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set_trust(SSL_CTX * ctx,int trust)545*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) {
546*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
547*8fb009dcSAndroid Build Coastguard Worker   return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
548*8fb009dcSAndroid Build Coastguard Worker }
549*8fb009dcSAndroid Build Coastguard Worker 
SSL_set_trust(SSL * ssl,int trust)550*8fb009dcSAndroid Build Coastguard Worker int SSL_set_trust(SSL *ssl, int trust) {
551*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
552*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
553*8fb009dcSAndroid Build Coastguard Worker     return 0;
554*8fb009dcSAndroid Build Coastguard Worker   }
555*8fb009dcSAndroid Build Coastguard Worker   return X509_VERIFY_PARAM_set_trust(ssl->config->param, trust);
556*8fb009dcSAndroid Build Coastguard Worker }
557*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set1_param(SSL_CTX * ctx,const X509_VERIFY_PARAM * param)558*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) {
559*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
560*8fb009dcSAndroid Build Coastguard Worker   return X509_VERIFY_PARAM_set1(ctx->param, param);
561*8fb009dcSAndroid Build Coastguard Worker }
562*8fb009dcSAndroid Build Coastguard Worker 
SSL_set1_param(SSL * ssl,const X509_VERIFY_PARAM * param)563*8fb009dcSAndroid Build Coastguard Worker int SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) {
564*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
565*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
566*8fb009dcSAndroid Build Coastguard Worker     return 0;
567*8fb009dcSAndroid Build Coastguard Worker   }
568*8fb009dcSAndroid Build Coastguard Worker   return X509_VERIFY_PARAM_set1(ssl->config->param, param);
569*8fb009dcSAndroid Build Coastguard Worker }
570*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_get0_param(SSL_CTX * ctx)571*8fb009dcSAndroid Build Coastguard Worker X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) {
572*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
573*8fb009dcSAndroid Build Coastguard Worker   return ctx->param;
574*8fb009dcSAndroid Build Coastguard Worker }
575*8fb009dcSAndroid Build Coastguard Worker 
SSL_get0_param(SSL * ssl)576*8fb009dcSAndroid Build Coastguard Worker X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) {
577*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
578*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
579*8fb009dcSAndroid Build Coastguard Worker     assert(ssl->config);
580*8fb009dcSAndroid Build Coastguard Worker     return 0;
581*8fb009dcSAndroid Build Coastguard Worker   }
582*8fb009dcSAndroid Build Coastguard Worker   return ssl->config->param;
583*8fb009dcSAndroid Build Coastguard Worker }
584*8fb009dcSAndroid Build Coastguard Worker 
SSL_get_verify_depth(const SSL * ssl)585*8fb009dcSAndroid Build Coastguard Worker int SSL_get_verify_depth(const SSL *ssl) {
586*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
587*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
588*8fb009dcSAndroid Build Coastguard Worker     assert(ssl->config);
589*8fb009dcSAndroid Build Coastguard Worker     return 0;
590*8fb009dcSAndroid Build Coastguard Worker   }
591*8fb009dcSAndroid Build Coastguard Worker   return X509_VERIFY_PARAM_get_depth(ssl->config->param);
592*8fb009dcSAndroid Build Coastguard Worker }
593*8fb009dcSAndroid Build Coastguard Worker 
SSL_get_verify_callback(const SSL * ssl)594*8fb009dcSAndroid Build Coastguard Worker int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) {
595*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
596*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
597*8fb009dcSAndroid Build Coastguard Worker     assert(ssl->config);
598*8fb009dcSAndroid Build Coastguard Worker     return 0;
599*8fb009dcSAndroid Build Coastguard Worker   }
600*8fb009dcSAndroid Build Coastguard Worker   return ssl->config->verify_callback;
601*8fb009dcSAndroid Build Coastguard Worker }
602*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_get_verify_mode(const SSL_CTX * ctx)603*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) {
604*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
605*8fb009dcSAndroid Build Coastguard Worker   return ctx->verify_mode;
606*8fb009dcSAndroid Build Coastguard Worker }
607*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_get_verify_depth(const SSL_CTX * ctx)608*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) {
609*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
610*8fb009dcSAndroid Build Coastguard Worker   return X509_VERIFY_PARAM_get_depth(ctx->param);
611*8fb009dcSAndroid Build Coastguard Worker }
612*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_get_verify_callback(const SSL_CTX * ctx)613*8fb009dcSAndroid Build Coastguard Worker int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
614*8fb009dcSAndroid Build Coastguard Worker     int ok, X509_STORE_CTX *store_ctx) {
615*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
616*8fb009dcSAndroid Build Coastguard Worker   return ctx->default_verify_callback;
617*8fb009dcSAndroid Build Coastguard Worker }
618*8fb009dcSAndroid Build Coastguard Worker 
SSL_set_verify(SSL * ssl,int mode,int (* callback)(int ok,X509_STORE_CTX * store_ctx))619*8fb009dcSAndroid Build Coastguard Worker void SSL_set_verify(SSL *ssl, int mode,
620*8fb009dcSAndroid Build Coastguard Worker                     int (*callback)(int ok, X509_STORE_CTX *store_ctx)) {
621*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
622*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
623*8fb009dcSAndroid Build Coastguard Worker     return;
624*8fb009dcSAndroid Build Coastguard Worker   }
625*8fb009dcSAndroid Build Coastguard Worker   ssl->config->verify_mode = mode;
626*8fb009dcSAndroid Build Coastguard Worker   if (callback != NULL) {
627*8fb009dcSAndroid Build Coastguard Worker     ssl->config->verify_callback = callback;
628*8fb009dcSAndroid Build Coastguard Worker   }
629*8fb009dcSAndroid Build Coastguard Worker }
630*8fb009dcSAndroid Build Coastguard Worker 
SSL_set_verify_depth(SSL * ssl,int depth)631*8fb009dcSAndroid Build Coastguard Worker void SSL_set_verify_depth(SSL *ssl, int depth) {
632*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
633*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
634*8fb009dcSAndroid Build Coastguard Worker     return;
635*8fb009dcSAndroid Build Coastguard Worker   }
636*8fb009dcSAndroid Build Coastguard Worker   X509_VERIFY_PARAM_set_depth(ssl->config->param, depth);
637*8fb009dcSAndroid Build Coastguard Worker }
638*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set_cert_verify_callback(SSL_CTX * ctx,int (* cb)(X509_STORE_CTX * store_ctx,void * arg),void * arg)639*8fb009dcSAndroid Build Coastguard Worker void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
640*8fb009dcSAndroid Build Coastguard Worker                                       int (*cb)(X509_STORE_CTX *store_ctx,
641*8fb009dcSAndroid Build Coastguard Worker                                                 void *arg),
642*8fb009dcSAndroid Build Coastguard Worker                                       void *arg) {
643*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
644*8fb009dcSAndroid Build Coastguard Worker   ctx->app_verify_callback = cb;
645*8fb009dcSAndroid Build Coastguard Worker   ctx->app_verify_arg = arg;
646*8fb009dcSAndroid Build Coastguard Worker }
647*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set_verify(SSL_CTX * ctx,int mode,int (* cb)(int,X509_STORE_CTX *))648*8fb009dcSAndroid Build Coastguard Worker void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
649*8fb009dcSAndroid Build Coastguard Worker                         int (*cb)(int, X509_STORE_CTX *)) {
650*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
651*8fb009dcSAndroid Build Coastguard Worker   ctx->verify_mode = mode;
652*8fb009dcSAndroid Build Coastguard Worker   ctx->default_verify_callback = cb;
653*8fb009dcSAndroid Build Coastguard Worker }
654*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set_verify_depth(SSL_CTX * ctx,int depth)655*8fb009dcSAndroid Build Coastguard Worker void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) {
656*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
657*8fb009dcSAndroid Build Coastguard Worker   X509_VERIFY_PARAM_set_depth(ctx->param, depth);
658*8fb009dcSAndroid Build Coastguard Worker }
659*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set_default_verify_paths(SSL_CTX * ctx)660*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) {
661*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
662*8fb009dcSAndroid Build Coastguard Worker   return X509_STORE_set_default_paths(ctx->cert_store);
663*8fb009dcSAndroid Build Coastguard Worker }
664*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_load_verify_locations(SSL_CTX * ctx,const char * ca_file,const char * ca_dir)665*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file,
666*8fb009dcSAndroid Build Coastguard Worker                                   const char *ca_dir) {
667*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
668*8fb009dcSAndroid Build Coastguard Worker   return X509_STORE_load_locations(ctx->cert_store, ca_file, ca_dir);
669*8fb009dcSAndroid Build Coastguard Worker }
670*8fb009dcSAndroid Build Coastguard Worker 
SSL_get_verify_result(const SSL * ssl)671*8fb009dcSAndroid Build Coastguard Worker long SSL_get_verify_result(const SSL *ssl) {
672*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
673*8fb009dcSAndroid Build Coastguard Worker   SSL_SESSION *session = SSL_get_session(ssl);
674*8fb009dcSAndroid Build Coastguard Worker   if (session == NULL) {
675*8fb009dcSAndroid Build Coastguard Worker     return X509_V_ERR_INVALID_CALL;
676*8fb009dcSAndroid Build Coastguard Worker   }
677*8fb009dcSAndroid Build Coastguard Worker   return session->verify_result;
678*8fb009dcSAndroid Build Coastguard Worker }
679*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_get_cert_store(const SSL_CTX * ctx)680*8fb009dcSAndroid Build Coastguard Worker X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
681*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
682*8fb009dcSAndroid Build Coastguard Worker   return ctx->cert_store;
683*8fb009dcSAndroid Build Coastguard Worker }
684*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set_cert_store(SSL_CTX * ctx,X509_STORE * store)685*8fb009dcSAndroid Build Coastguard Worker void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) {
686*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
687*8fb009dcSAndroid Build Coastguard Worker   X509_STORE_free(ctx->cert_store);
688*8fb009dcSAndroid Build Coastguard Worker   ctx->cert_store = store;
689*8fb009dcSAndroid Build Coastguard Worker }
690*8fb009dcSAndroid Build Coastguard Worker 
ssl_use_certificate(CERT * cert,X509 * x)691*8fb009dcSAndroid Build Coastguard Worker static int ssl_use_certificate(CERT *cert, X509 *x) {
692*8fb009dcSAndroid Build Coastguard Worker   if (x == NULL) {
693*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
694*8fb009dcSAndroid Build Coastguard Worker     return 0;
695*8fb009dcSAndroid Build Coastguard Worker   }
696*8fb009dcSAndroid Build Coastguard Worker 
697*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<CRYPTO_BUFFER> buffer = x509_to_buffer(x);
698*8fb009dcSAndroid Build Coastguard Worker   if (!buffer) {
699*8fb009dcSAndroid Build Coastguard Worker     return 0;
700*8fb009dcSAndroid Build Coastguard Worker   }
701*8fb009dcSAndroid Build Coastguard Worker 
702*8fb009dcSAndroid Build Coastguard Worker   return ssl_set_cert(cert, std::move(buffer));
703*8fb009dcSAndroid Build Coastguard Worker }
704*8fb009dcSAndroid Build Coastguard Worker 
SSL_use_certificate(SSL * ssl,X509 * x)705*8fb009dcSAndroid Build Coastguard Worker int SSL_use_certificate(SSL *ssl, X509 *x) {
706*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
707*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
708*8fb009dcSAndroid Build Coastguard Worker     return 0;
709*8fb009dcSAndroid Build Coastguard Worker   }
710*8fb009dcSAndroid Build Coastguard Worker   return ssl_use_certificate(ssl->config->cert.get(), x);
711*8fb009dcSAndroid Build Coastguard Worker }
712*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_use_certificate(SSL_CTX * ctx,X509 * x)713*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) {
714*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
715*8fb009dcSAndroid Build Coastguard Worker   return ssl_use_certificate(ctx->cert.get(), x);
716*8fb009dcSAndroid Build Coastguard Worker }
717*8fb009dcSAndroid Build Coastguard Worker 
718*8fb009dcSAndroid Build Coastguard Worker // ssl_cert_cache_leaf_cert sets |cert->x509_leaf|, if currently NULL, from the
719*8fb009dcSAndroid Build Coastguard Worker // first element of |cert->chain|.
ssl_cert_cache_leaf_cert(CERT * cert)720*8fb009dcSAndroid Build Coastguard Worker static int ssl_cert_cache_leaf_cert(CERT *cert) {
721*8fb009dcSAndroid Build Coastguard Worker   assert(cert->x509_method);
722*8fb009dcSAndroid Build Coastguard Worker 
723*8fb009dcSAndroid Build Coastguard Worker   const SSL_CREDENTIAL *cred = cert->default_credential.get();
724*8fb009dcSAndroid Build Coastguard Worker   if (cert->x509_leaf != NULL ||
725*8fb009dcSAndroid Build Coastguard Worker       cred->chain == NULL) {
726*8fb009dcSAndroid Build Coastguard Worker     return 1;
727*8fb009dcSAndroid Build Coastguard Worker   }
728*8fb009dcSAndroid Build Coastguard Worker 
729*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_BUFFER *leaf = sk_CRYPTO_BUFFER_value(cred->chain.get(), 0);
730*8fb009dcSAndroid Build Coastguard Worker   if (!leaf) {
731*8fb009dcSAndroid Build Coastguard Worker     return 1;
732*8fb009dcSAndroid Build Coastguard Worker   }
733*8fb009dcSAndroid Build Coastguard Worker 
734*8fb009dcSAndroid Build Coastguard Worker   cert->x509_leaf = X509_parse_from_buffer(leaf);
735*8fb009dcSAndroid Build Coastguard Worker   return cert->x509_leaf != NULL;
736*8fb009dcSAndroid Build Coastguard Worker }
737*8fb009dcSAndroid Build Coastguard Worker 
ssl_cert_get0_leaf(CERT * cert)738*8fb009dcSAndroid Build Coastguard Worker static X509 *ssl_cert_get0_leaf(CERT *cert) {
739*8fb009dcSAndroid Build Coastguard Worker   if (cert->x509_leaf == NULL &&
740*8fb009dcSAndroid Build Coastguard Worker       !ssl_cert_cache_leaf_cert(cert)) {
741*8fb009dcSAndroid Build Coastguard Worker     return NULL;
742*8fb009dcSAndroid Build Coastguard Worker   }
743*8fb009dcSAndroid Build Coastguard Worker 
744*8fb009dcSAndroid Build Coastguard Worker   return cert->x509_leaf;
745*8fb009dcSAndroid Build Coastguard Worker }
746*8fb009dcSAndroid Build Coastguard Worker 
SSL_get_certificate(const SSL * ssl)747*8fb009dcSAndroid Build Coastguard Worker X509 *SSL_get_certificate(const SSL *ssl) {
748*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
749*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
750*8fb009dcSAndroid Build Coastguard Worker     assert(ssl->config);
751*8fb009dcSAndroid Build Coastguard Worker     return 0;
752*8fb009dcSAndroid Build Coastguard Worker   }
753*8fb009dcSAndroid Build Coastguard Worker   return ssl_cert_get0_leaf(ssl->config->cert.get());
754*8fb009dcSAndroid Build Coastguard Worker }
755*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_get0_certificate(const SSL_CTX * ctx)756*8fb009dcSAndroid Build Coastguard Worker X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
757*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
758*8fb009dcSAndroid Build Coastguard Worker   MutexWriteLock lock(const_cast<CRYPTO_MUTEX*>(&ctx->lock));
759*8fb009dcSAndroid Build Coastguard Worker   return ssl_cert_get0_leaf(ctx->cert.get());
760*8fb009dcSAndroid Build Coastguard Worker }
761*8fb009dcSAndroid Build Coastguard Worker 
ssl_cert_add1_chain_cert(CERT * cert,X509 * x509)762*8fb009dcSAndroid Build Coastguard Worker static int ssl_cert_add1_chain_cert(CERT *cert, X509 *x509) {
763*8fb009dcSAndroid Build Coastguard Worker   assert(cert->x509_method);
764*8fb009dcSAndroid Build Coastguard Worker 
765*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<CRYPTO_BUFFER> buffer = x509_to_buffer(x509);
766*8fb009dcSAndroid Build Coastguard Worker   if (!buffer ||
767*8fb009dcSAndroid Build Coastguard Worker       !cert->default_credential->AppendIntermediateCert(std::move(buffer))) {
768*8fb009dcSAndroid Build Coastguard Worker     return 0;
769*8fb009dcSAndroid Build Coastguard Worker   }
770*8fb009dcSAndroid Build Coastguard Worker 
771*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_cert_flush_cached_chain(cert);
772*8fb009dcSAndroid Build Coastguard Worker   return 1;
773*8fb009dcSAndroid Build Coastguard Worker }
774*8fb009dcSAndroid Build Coastguard Worker 
ssl_cert_add0_chain_cert(CERT * cert,X509 * x509)775*8fb009dcSAndroid Build Coastguard Worker static int ssl_cert_add0_chain_cert(CERT *cert, X509 *x509) {
776*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_cert_add1_chain_cert(cert, x509)) {
777*8fb009dcSAndroid Build Coastguard Worker     return 0;
778*8fb009dcSAndroid Build Coastguard Worker   }
779*8fb009dcSAndroid Build Coastguard Worker 
780*8fb009dcSAndroid Build Coastguard Worker   X509_free(cert->x509_stash);
781*8fb009dcSAndroid Build Coastguard Worker   cert->x509_stash = x509;
782*8fb009dcSAndroid Build Coastguard Worker   return 1;
783*8fb009dcSAndroid Build Coastguard Worker }
784*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set0_chain(SSL_CTX * ctx,STACK_OF (X509)* chain)785*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) {
786*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
787*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_cert_set1_chain(ctx->cert.get(), chain)) {
788*8fb009dcSAndroid Build Coastguard Worker     return 0;
789*8fb009dcSAndroid Build Coastguard Worker   }
790*8fb009dcSAndroid Build Coastguard Worker   sk_X509_pop_free(chain, X509_free);
791*8fb009dcSAndroid Build Coastguard Worker   return 1;
792*8fb009dcSAndroid Build Coastguard Worker }
793*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set1_chain(SSL_CTX * ctx,STACK_OF (X509)* chain)794*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) {
795*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
796*8fb009dcSAndroid Build Coastguard Worker   return ssl_cert_set1_chain(ctx->cert.get(), chain);
797*8fb009dcSAndroid Build Coastguard Worker }
798*8fb009dcSAndroid Build Coastguard Worker 
SSL_set0_chain(SSL * ssl,STACK_OF (X509)* chain)799*8fb009dcSAndroid Build Coastguard Worker int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain) {
800*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
801*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
802*8fb009dcSAndroid Build Coastguard Worker     return 0;
803*8fb009dcSAndroid Build Coastguard Worker   }
804*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_cert_set1_chain(ssl->config->cert.get(), chain)) {
805*8fb009dcSAndroid Build Coastguard Worker     return 0;
806*8fb009dcSAndroid Build Coastguard Worker   }
807*8fb009dcSAndroid Build Coastguard Worker   sk_X509_pop_free(chain, X509_free);
808*8fb009dcSAndroid Build Coastguard Worker   return 1;
809*8fb009dcSAndroid Build Coastguard Worker }
810*8fb009dcSAndroid Build Coastguard Worker 
SSL_set1_chain(SSL * ssl,STACK_OF (X509)* chain)811*8fb009dcSAndroid Build Coastguard Worker int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain) {
812*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
813*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
814*8fb009dcSAndroid Build Coastguard Worker     return 0;
815*8fb009dcSAndroid Build Coastguard Worker   }
816*8fb009dcSAndroid Build Coastguard Worker   return ssl_cert_set1_chain(ssl->config->cert.get(), chain);
817*8fb009dcSAndroid Build Coastguard Worker }
818*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_add0_chain_cert(SSL_CTX * ctx,X509 * x509)819*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509) {
820*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
821*8fb009dcSAndroid Build Coastguard Worker   return ssl_cert_add0_chain_cert(ctx->cert.get(), x509);
822*8fb009dcSAndroid Build Coastguard Worker }
823*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_add1_chain_cert(SSL_CTX * ctx,X509 * x509)824*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509) {
825*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
826*8fb009dcSAndroid Build Coastguard Worker   return ssl_cert_add1_chain_cert(ctx->cert.get(), x509);
827*8fb009dcSAndroid Build Coastguard Worker }
828*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_add_extra_chain_cert(SSL_CTX * ctx,X509 * x509)829*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509) {
830*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
831*8fb009dcSAndroid Build Coastguard Worker   return SSL_CTX_add0_chain_cert(ctx, x509);
832*8fb009dcSAndroid Build Coastguard Worker }
833*8fb009dcSAndroid Build Coastguard Worker 
SSL_add0_chain_cert(SSL * ssl,X509 * x509)834*8fb009dcSAndroid Build Coastguard Worker int SSL_add0_chain_cert(SSL *ssl, X509 *x509) {
835*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
836*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
837*8fb009dcSAndroid Build Coastguard Worker     return 0;
838*8fb009dcSAndroid Build Coastguard Worker   }
839*8fb009dcSAndroid Build Coastguard Worker   return ssl_cert_add0_chain_cert(ssl->config->cert.get(), x509);
840*8fb009dcSAndroid Build Coastguard Worker }
841*8fb009dcSAndroid Build Coastguard Worker 
SSL_add1_chain_cert(SSL * ssl,X509 * x509)842*8fb009dcSAndroid Build Coastguard Worker int SSL_add1_chain_cert(SSL *ssl, X509 *x509) {
843*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
844*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
845*8fb009dcSAndroid Build Coastguard Worker     return 0;
846*8fb009dcSAndroid Build Coastguard Worker   }
847*8fb009dcSAndroid Build Coastguard Worker   return ssl_cert_add1_chain_cert(ssl->config->cert.get(), x509);
848*8fb009dcSAndroid Build Coastguard Worker }
849*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_clear_chain_certs(SSL_CTX * ctx)850*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_clear_chain_certs(SSL_CTX *ctx) {
851*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
852*8fb009dcSAndroid Build Coastguard Worker   return SSL_CTX_set0_chain(ctx, NULL);
853*8fb009dcSAndroid Build Coastguard Worker }
854*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_clear_extra_chain_certs(SSL_CTX * ctx)855*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx) {
856*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
857*8fb009dcSAndroid Build Coastguard Worker   return SSL_CTX_clear_chain_certs(ctx);
858*8fb009dcSAndroid Build Coastguard Worker }
859*8fb009dcSAndroid Build Coastguard Worker 
SSL_clear_chain_certs(SSL * ssl)860*8fb009dcSAndroid Build Coastguard Worker int SSL_clear_chain_certs(SSL *ssl) {
861*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
862*8fb009dcSAndroid Build Coastguard Worker   return SSL_set0_chain(ssl, NULL);
863*8fb009dcSAndroid Build Coastguard Worker }
864*8fb009dcSAndroid Build Coastguard Worker 
865*8fb009dcSAndroid Build Coastguard Worker // ssl_cert_cache_chain_certs fills in |cert->x509_chain| from elements 1.. of
866*8fb009dcSAndroid Build Coastguard Worker // |cert->chain|.
ssl_cert_cache_chain_certs(CERT * cert)867*8fb009dcSAndroid Build Coastguard Worker static int ssl_cert_cache_chain_certs(CERT *cert) {
868*8fb009dcSAndroid Build Coastguard Worker   assert(cert->x509_method);
869*8fb009dcSAndroid Build Coastguard Worker 
870*8fb009dcSAndroid Build Coastguard Worker   const SSL_CREDENTIAL *cred = cert->default_credential.get();
871*8fb009dcSAndroid Build Coastguard Worker   if (cert->x509_chain != nullptr ||
872*8fb009dcSAndroid Build Coastguard Worker       cred->chain == nullptr ||
873*8fb009dcSAndroid Build Coastguard Worker       sk_CRYPTO_BUFFER_num(cred->chain.get()) < 2) {
874*8fb009dcSAndroid Build Coastguard Worker     return 1;
875*8fb009dcSAndroid Build Coastguard Worker   }
876*8fb009dcSAndroid Build Coastguard Worker 
877*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<STACK_OF(X509)> chain(sk_X509_new_null());
878*8fb009dcSAndroid Build Coastguard Worker   if (!chain) {
879*8fb009dcSAndroid Build Coastguard Worker     return 0;
880*8fb009dcSAndroid Build Coastguard Worker   }
881*8fb009dcSAndroid Build Coastguard Worker 
882*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cred->chain.get()); i++) {
883*8fb009dcSAndroid Build Coastguard Worker     CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(cred->chain.get(), i);
884*8fb009dcSAndroid Build Coastguard Worker     UniquePtr<X509> x509(X509_parse_from_buffer(buffer));
885*8fb009dcSAndroid Build Coastguard Worker     if (!x509 ||
886*8fb009dcSAndroid Build Coastguard Worker         !PushToStack(chain.get(), std::move(x509))) {
887*8fb009dcSAndroid Build Coastguard Worker       return 0;
888*8fb009dcSAndroid Build Coastguard Worker     }
889*8fb009dcSAndroid Build Coastguard Worker   }
890*8fb009dcSAndroid Build Coastguard Worker 
891*8fb009dcSAndroid Build Coastguard Worker   cert->x509_chain = chain.release();
892*8fb009dcSAndroid Build Coastguard Worker   return 1;
893*8fb009dcSAndroid Build Coastguard Worker }
894*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_get0_chain_certs(const SSL_CTX * ctx,STACK_OF (X509)** out_chain)895*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, STACK_OF(X509) **out_chain) {
896*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
897*8fb009dcSAndroid Build Coastguard Worker   MutexWriteLock lock(const_cast<CRYPTO_MUTEX*>(&ctx->lock));
898*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_cert_cache_chain_certs(ctx->cert.get())) {
899*8fb009dcSAndroid Build Coastguard Worker     *out_chain = NULL;
900*8fb009dcSAndroid Build Coastguard Worker     return 0;
901*8fb009dcSAndroid Build Coastguard Worker   }
902*8fb009dcSAndroid Build Coastguard Worker 
903*8fb009dcSAndroid Build Coastguard Worker   *out_chain = ctx->cert->x509_chain;
904*8fb009dcSAndroid Build Coastguard Worker   return 1;
905*8fb009dcSAndroid Build Coastguard Worker }
906*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_get_extra_chain_certs(const SSL_CTX * ctx,STACK_OF (X509)** out_chain)907*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx,
908*8fb009dcSAndroid Build Coastguard Worker                                   STACK_OF(X509) **out_chain) {
909*8fb009dcSAndroid Build Coastguard Worker   return SSL_CTX_get0_chain_certs(ctx, out_chain);
910*8fb009dcSAndroid Build Coastguard Worker }
911*8fb009dcSAndroid Build Coastguard Worker 
SSL_get0_chain_certs(const SSL * ssl,STACK_OF (X509)** out_chain)912*8fb009dcSAndroid Build Coastguard Worker int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) {
913*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
914*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
915*8fb009dcSAndroid Build Coastguard Worker     assert(ssl->config);
916*8fb009dcSAndroid Build Coastguard Worker     return 0;
917*8fb009dcSAndroid Build Coastguard Worker   }
918*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_cert_cache_chain_certs(ssl->config->cert.get())) {
919*8fb009dcSAndroid Build Coastguard Worker     *out_chain = NULL;
920*8fb009dcSAndroid Build Coastguard Worker     return 0;
921*8fb009dcSAndroid Build Coastguard Worker   }
922*8fb009dcSAndroid Build Coastguard Worker 
923*8fb009dcSAndroid Build Coastguard Worker   *out_chain = ssl->config->cert->x509_chain;
924*8fb009dcSAndroid Build Coastguard Worker   return 1;
925*8fb009dcSAndroid Build Coastguard Worker }
926*8fb009dcSAndroid Build Coastguard Worker 
d2i_SSL_SESSION_bio(BIO * bio,SSL_SESSION ** out)927*8fb009dcSAndroid Build Coastguard Worker SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out) {
928*8fb009dcSAndroid Build Coastguard Worker   uint8_t *data;
929*8fb009dcSAndroid Build Coastguard Worker   size_t len;
930*8fb009dcSAndroid Build Coastguard Worker   if (!BIO_read_asn1(bio, &data, &len, 1024 * 1024)) {
931*8fb009dcSAndroid Build Coastguard Worker     return 0;
932*8fb009dcSAndroid Build Coastguard Worker   }
933*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_data(data);
934*8fb009dcSAndroid Build Coastguard Worker   const uint8_t *ptr = data;
935*8fb009dcSAndroid Build Coastguard Worker   return d2i_SSL_SESSION(out, &ptr, static_cast<long>(len));
936*8fb009dcSAndroid Build Coastguard Worker }
937*8fb009dcSAndroid Build Coastguard Worker 
i2d_SSL_SESSION_bio(BIO * bio,const SSL_SESSION * session)938*8fb009dcSAndroid Build Coastguard Worker int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session) {
939*8fb009dcSAndroid Build Coastguard Worker   uint8_t *data;
940*8fb009dcSAndroid Build Coastguard Worker   size_t len;
941*8fb009dcSAndroid Build Coastguard Worker   if (!SSL_SESSION_to_bytes(session, &data, &len)) {
942*8fb009dcSAndroid Build Coastguard Worker     return 0;
943*8fb009dcSAndroid Build Coastguard Worker   }
944*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_data(data);
945*8fb009dcSAndroid Build Coastguard Worker   return BIO_write_all(bio, data, len);
946*8fb009dcSAndroid Build Coastguard Worker }
947*8fb009dcSAndroid Build Coastguard Worker 
IMPLEMENT_PEM_rw(SSL_SESSION,SSL_SESSION,PEM_STRING_SSL_SESSION,SSL_SESSION)948*8fb009dcSAndroid Build Coastguard Worker IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
949*8fb009dcSAndroid Build Coastguard Worker 
950*8fb009dcSAndroid Build Coastguard Worker SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) {
951*8fb009dcSAndroid Build Coastguard Worker   if (length < 0) {
952*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
953*8fb009dcSAndroid Build Coastguard Worker     return NULL;
954*8fb009dcSAndroid Build Coastguard Worker   }
955*8fb009dcSAndroid Build Coastguard Worker 
956*8fb009dcSAndroid Build Coastguard Worker   CBS cbs;
957*8fb009dcSAndroid Build Coastguard Worker   CBS_init(&cbs, *pp, length);
958*8fb009dcSAndroid Build Coastguard Worker 
959*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<SSL_SESSION> ret = SSL_SESSION_parse(&cbs, &ssl_crypto_x509_method,
960*8fb009dcSAndroid Build Coastguard Worker                                                  NULL /* no buffer pool */);
961*8fb009dcSAndroid Build Coastguard Worker   if (!ret) {
962*8fb009dcSAndroid Build Coastguard Worker     return NULL;
963*8fb009dcSAndroid Build Coastguard Worker   }
964*8fb009dcSAndroid Build Coastguard Worker 
965*8fb009dcSAndroid Build Coastguard Worker   if (a) {
966*8fb009dcSAndroid Build Coastguard Worker     SSL_SESSION_free(*a);
967*8fb009dcSAndroid Build Coastguard Worker     *a = ret.get();
968*8fb009dcSAndroid Build Coastguard Worker   }
969*8fb009dcSAndroid Build Coastguard Worker   *pp = CBS_data(&cbs);
970*8fb009dcSAndroid Build Coastguard Worker   return ret.release();
971*8fb009dcSAndroid Build Coastguard Worker }
972*8fb009dcSAndroid Build Coastguard Worker 
STACK_OF(X509_NAME)973*8fb009dcSAndroid Build Coastguard Worker STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list) {
974*8fb009dcSAndroid Build Coastguard Worker   // TODO(https://crbug.com/boringssl/407): |X509_NAME_dup| should be const.
975*8fb009dcSAndroid Build Coastguard Worker   auto name_dup = [](const X509_NAME *name) {
976*8fb009dcSAndroid Build Coastguard Worker     return X509_NAME_dup(const_cast<X509_NAME *>(name));
977*8fb009dcSAndroid Build Coastguard Worker   };
978*8fb009dcSAndroid Build Coastguard Worker   return sk_X509_NAME_deep_copy(list, name_dup, X509_NAME_free);
979*8fb009dcSAndroid Build Coastguard Worker }
980*8fb009dcSAndroid Build Coastguard Worker 
set_client_CA_list(UniquePtr<STACK_OF (CRYPTO_BUFFER)> * ca_list,const STACK_OF (X509_NAME)* name_list,CRYPTO_BUFFER_POOL * pool)981*8fb009dcSAndroid Build Coastguard Worker static void set_client_CA_list(UniquePtr<STACK_OF(CRYPTO_BUFFER)> *ca_list,
982*8fb009dcSAndroid Build Coastguard Worker                                const STACK_OF(X509_NAME) *name_list,
983*8fb009dcSAndroid Build Coastguard Worker                                CRYPTO_BUFFER_POOL *pool) {
984*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<STACK_OF(CRYPTO_BUFFER)> buffers(sk_CRYPTO_BUFFER_new_null());
985*8fb009dcSAndroid Build Coastguard Worker   if (!buffers) {
986*8fb009dcSAndroid Build Coastguard Worker     return;
987*8fb009dcSAndroid Build Coastguard Worker   }
988*8fb009dcSAndroid Build Coastguard Worker 
989*8fb009dcSAndroid Build Coastguard Worker   for (X509_NAME *name : name_list) {
990*8fb009dcSAndroid Build Coastguard Worker     uint8_t *outp = NULL;
991*8fb009dcSAndroid Build Coastguard Worker     int len = i2d_X509_NAME(name, &outp);
992*8fb009dcSAndroid Build Coastguard Worker     if (len < 0) {
993*8fb009dcSAndroid Build Coastguard Worker       return;
994*8fb009dcSAndroid Build Coastguard Worker     }
995*8fb009dcSAndroid Build Coastguard Worker 
996*8fb009dcSAndroid Build Coastguard Worker     UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(outp, len, pool));
997*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_free(outp);
998*8fb009dcSAndroid Build Coastguard Worker     if (!buffer ||
999*8fb009dcSAndroid Build Coastguard Worker         !PushToStack(buffers.get(), std::move(buffer))) {
1000*8fb009dcSAndroid Build Coastguard Worker       return;
1001*8fb009dcSAndroid Build Coastguard Worker     }
1002*8fb009dcSAndroid Build Coastguard Worker   }
1003*8fb009dcSAndroid Build Coastguard Worker 
1004*8fb009dcSAndroid Build Coastguard Worker   *ca_list = std::move(buffers);
1005*8fb009dcSAndroid Build Coastguard Worker }
1006*8fb009dcSAndroid Build Coastguard Worker 
SSL_set_client_CA_list(SSL * ssl,STACK_OF (X509_NAME)* name_list)1007*8fb009dcSAndroid Build Coastguard Worker void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list) {
1008*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
1009*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
1010*8fb009dcSAndroid Build Coastguard Worker     return;
1011*8fb009dcSAndroid Build Coastguard Worker   }
1012*8fb009dcSAndroid Build Coastguard Worker   ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl->config.get());
1013*8fb009dcSAndroid Build Coastguard Worker   set_client_CA_list(&ssl->config->client_CA, name_list, ssl->ctx->pool);
1014*8fb009dcSAndroid Build Coastguard Worker   sk_X509_NAME_pop_free(name_list, X509_NAME_free);
1015*8fb009dcSAndroid Build Coastguard Worker }
1016*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set_client_CA_list(SSL_CTX * ctx,STACK_OF (X509_NAME)* name_list)1017*8fb009dcSAndroid Build Coastguard Worker void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) {
1018*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
1019*8fb009dcSAndroid Build Coastguard Worker   ctx->x509_method->ssl_ctx_flush_cached_client_CA(ctx);
1020*8fb009dcSAndroid Build Coastguard Worker   set_client_CA_list(&ctx->client_CA, name_list, ctx->pool);
1021*8fb009dcSAndroid Build Coastguard Worker   sk_X509_NAME_pop_free(name_list, X509_NAME_free);
1022*8fb009dcSAndroid Build Coastguard Worker }
1023*8fb009dcSAndroid Build Coastguard Worker 
STACK_OF(X509_NAME)1024*8fb009dcSAndroid Build Coastguard Worker static STACK_OF(X509_NAME) *
1025*8fb009dcSAndroid Build Coastguard Worker     buffer_names_to_x509(const STACK_OF(CRYPTO_BUFFER) *names,
1026*8fb009dcSAndroid Build Coastguard Worker                          STACK_OF(X509_NAME) **cached) {
1027*8fb009dcSAndroid Build Coastguard Worker   if (names == NULL) {
1028*8fb009dcSAndroid Build Coastguard Worker     return NULL;
1029*8fb009dcSAndroid Build Coastguard Worker   }
1030*8fb009dcSAndroid Build Coastguard Worker 
1031*8fb009dcSAndroid Build Coastguard Worker   if (*cached != NULL) {
1032*8fb009dcSAndroid Build Coastguard Worker     return *cached;
1033*8fb009dcSAndroid Build Coastguard Worker   }
1034*8fb009dcSAndroid Build Coastguard Worker 
1035*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<STACK_OF(X509_NAME)> new_cache(sk_X509_NAME_new_null());
1036*8fb009dcSAndroid Build Coastguard Worker   if (!new_cache) {
1037*8fb009dcSAndroid Build Coastguard Worker     return NULL;
1038*8fb009dcSAndroid Build Coastguard Worker   }
1039*8fb009dcSAndroid Build Coastguard Worker 
1040*8fb009dcSAndroid Build Coastguard Worker   for (const CRYPTO_BUFFER *buffer : names) {
1041*8fb009dcSAndroid Build Coastguard Worker     const uint8_t *inp = CRYPTO_BUFFER_data(buffer);
1042*8fb009dcSAndroid Build Coastguard Worker     UniquePtr<X509_NAME> name(
1043*8fb009dcSAndroid Build Coastguard Worker         d2i_X509_NAME(nullptr, &inp, CRYPTO_BUFFER_len(buffer)));
1044*8fb009dcSAndroid Build Coastguard Worker     if (!name ||
1045*8fb009dcSAndroid Build Coastguard Worker         inp != CRYPTO_BUFFER_data(buffer) + CRYPTO_BUFFER_len(buffer) ||
1046*8fb009dcSAndroid Build Coastguard Worker         !PushToStack(new_cache.get(), std::move(name))) {
1047*8fb009dcSAndroid Build Coastguard Worker       return NULL;
1048*8fb009dcSAndroid Build Coastguard Worker     }
1049*8fb009dcSAndroid Build Coastguard Worker   }
1050*8fb009dcSAndroid Build Coastguard Worker 
1051*8fb009dcSAndroid Build Coastguard Worker   *cached = new_cache.release();
1052*8fb009dcSAndroid Build Coastguard Worker   return *cached;
1053*8fb009dcSAndroid Build Coastguard Worker }
1054*8fb009dcSAndroid Build Coastguard Worker 
STACK_OF(X509_NAME)1055*8fb009dcSAndroid Build Coastguard Worker STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl) {
1056*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
1057*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
1058*8fb009dcSAndroid Build Coastguard Worker     assert(ssl->config);
1059*8fb009dcSAndroid Build Coastguard Worker     return NULL;
1060*8fb009dcSAndroid Build Coastguard Worker   }
1061*8fb009dcSAndroid Build Coastguard Worker   // For historical reasons, this function is used both to query configuration
1062*8fb009dcSAndroid Build Coastguard Worker   // state on a server as well as handshake state on a client. However, whether
1063*8fb009dcSAndroid Build Coastguard Worker   // |ssl| is a client or server is not known until explicitly configured with
1064*8fb009dcSAndroid Build Coastguard Worker   // |SSL_set_connect_state|. If |do_handshake| is NULL, |ssl| is in an
1065*8fb009dcSAndroid Build Coastguard Worker   // indeterminate mode and |ssl->server| is unset.
1066*8fb009dcSAndroid Build Coastguard Worker   if (ssl->do_handshake != NULL && !ssl->server) {
1067*8fb009dcSAndroid Build Coastguard Worker     if (ssl->s3->hs != NULL) {
1068*8fb009dcSAndroid Build Coastguard Worker       return buffer_names_to_x509(ssl->s3->hs->ca_names.get(),
1069*8fb009dcSAndroid Build Coastguard Worker                                   &ssl->s3->hs->cached_x509_ca_names);
1070*8fb009dcSAndroid Build Coastguard Worker     }
1071*8fb009dcSAndroid Build Coastguard Worker 
1072*8fb009dcSAndroid Build Coastguard Worker     return NULL;
1073*8fb009dcSAndroid Build Coastguard Worker   }
1074*8fb009dcSAndroid Build Coastguard Worker 
1075*8fb009dcSAndroid Build Coastguard Worker   if (ssl->config->client_CA != NULL) {
1076*8fb009dcSAndroid Build Coastguard Worker     return buffer_names_to_x509(
1077*8fb009dcSAndroid Build Coastguard Worker         ssl->config->client_CA.get(),
1078*8fb009dcSAndroid Build Coastguard Worker         (STACK_OF(X509_NAME) **)&ssl->config->cached_x509_client_CA);
1079*8fb009dcSAndroid Build Coastguard Worker   }
1080*8fb009dcSAndroid Build Coastguard Worker   return SSL_CTX_get_client_CA_list(ssl->ctx.get());
1081*8fb009dcSAndroid Build Coastguard Worker }
1082*8fb009dcSAndroid Build Coastguard Worker 
STACK_OF(X509_NAME)1083*8fb009dcSAndroid Build Coastguard Worker STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) {
1084*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
1085*8fb009dcSAndroid Build Coastguard Worker   // This is a logically const operation that may be called on multiple threads,
1086*8fb009dcSAndroid Build Coastguard Worker   // so it needs to lock around updating |cached_x509_client_CA|.
1087*8fb009dcSAndroid Build Coastguard Worker   MutexWriteLock lock(const_cast<CRYPTO_MUTEX *>(&ctx->lock));
1088*8fb009dcSAndroid Build Coastguard Worker   return buffer_names_to_x509(
1089*8fb009dcSAndroid Build Coastguard Worker       ctx->client_CA.get(),
1090*8fb009dcSAndroid Build Coastguard Worker       const_cast<STACK_OF(X509_NAME) **>(&ctx->cached_x509_client_CA));
1091*8fb009dcSAndroid Build Coastguard Worker }
1092*8fb009dcSAndroid Build Coastguard Worker 
add_client_CA(UniquePtr<STACK_OF (CRYPTO_BUFFER)> * names,X509 * x509,CRYPTO_BUFFER_POOL * pool)1093*8fb009dcSAndroid Build Coastguard Worker static int add_client_CA(UniquePtr<STACK_OF(CRYPTO_BUFFER)> *names, X509 *x509,
1094*8fb009dcSAndroid Build Coastguard Worker                          CRYPTO_BUFFER_POOL *pool) {
1095*8fb009dcSAndroid Build Coastguard Worker   if (x509 == NULL) {
1096*8fb009dcSAndroid Build Coastguard Worker     return 0;
1097*8fb009dcSAndroid Build Coastguard Worker   }
1098*8fb009dcSAndroid Build Coastguard Worker 
1099*8fb009dcSAndroid Build Coastguard Worker   uint8_t *outp = NULL;
1100*8fb009dcSAndroid Build Coastguard Worker   int len = i2d_X509_NAME(X509_get_subject_name(x509), &outp);
1101*8fb009dcSAndroid Build Coastguard Worker   if (len < 0) {
1102*8fb009dcSAndroid Build Coastguard Worker     return 0;
1103*8fb009dcSAndroid Build Coastguard Worker   }
1104*8fb009dcSAndroid Build Coastguard Worker 
1105*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<CRYPTO_BUFFER> buffer(CRYPTO_BUFFER_new(outp, len, pool));
1106*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_free(outp);
1107*8fb009dcSAndroid Build Coastguard Worker   if (!buffer) {
1108*8fb009dcSAndroid Build Coastguard Worker     return 0;
1109*8fb009dcSAndroid Build Coastguard Worker   }
1110*8fb009dcSAndroid Build Coastguard Worker 
1111*8fb009dcSAndroid Build Coastguard Worker   int alloced = 0;
1112*8fb009dcSAndroid Build Coastguard Worker   if (*names == nullptr) {
1113*8fb009dcSAndroid Build Coastguard Worker     names->reset(sk_CRYPTO_BUFFER_new_null());
1114*8fb009dcSAndroid Build Coastguard Worker     alloced = 1;
1115*8fb009dcSAndroid Build Coastguard Worker 
1116*8fb009dcSAndroid Build Coastguard Worker     if (*names == NULL) {
1117*8fb009dcSAndroid Build Coastguard Worker       return 0;
1118*8fb009dcSAndroid Build Coastguard Worker     }
1119*8fb009dcSAndroid Build Coastguard Worker   }
1120*8fb009dcSAndroid Build Coastguard Worker 
1121*8fb009dcSAndroid Build Coastguard Worker   if (!PushToStack(names->get(), std::move(buffer))) {
1122*8fb009dcSAndroid Build Coastguard Worker     if (alloced) {
1123*8fb009dcSAndroid Build Coastguard Worker       names->reset();
1124*8fb009dcSAndroid Build Coastguard Worker     }
1125*8fb009dcSAndroid Build Coastguard Worker     return 0;
1126*8fb009dcSAndroid Build Coastguard Worker   }
1127*8fb009dcSAndroid Build Coastguard Worker 
1128*8fb009dcSAndroid Build Coastguard Worker   return 1;
1129*8fb009dcSAndroid Build Coastguard Worker }
1130*8fb009dcSAndroid Build Coastguard Worker 
SSL_add_client_CA(SSL * ssl,X509 * x509)1131*8fb009dcSAndroid Build Coastguard Worker int SSL_add_client_CA(SSL *ssl, X509 *x509) {
1132*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
1133*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
1134*8fb009dcSAndroid Build Coastguard Worker     return 0;
1135*8fb009dcSAndroid Build Coastguard Worker   }
1136*8fb009dcSAndroid Build Coastguard Worker   if (!add_client_CA(&ssl->config->client_CA, x509, ssl->ctx->pool)) {
1137*8fb009dcSAndroid Build Coastguard Worker     return 0;
1138*8fb009dcSAndroid Build Coastguard Worker   }
1139*8fb009dcSAndroid Build Coastguard Worker 
1140*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_ssl_flush_cached_client_CA(ssl->config.get());
1141*8fb009dcSAndroid Build Coastguard Worker   return 1;
1142*8fb009dcSAndroid Build Coastguard Worker }
1143*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_add_client_CA(SSL_CTX * ctx,X509 * x509)1144*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509) {
1145*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
1146*8fb009dcSAndroid Build Coastguard Worker   if (!add_client_CA(&ctx->client_CA, x509, ctx->pool)) {
1147*8fb009dcSAndroid Build Coastguard Worker     return 0;
1148*8fb009dcSAndroid Build Coastguard Worker   }
1149*8fb009dcSAndroid Build Coastguard Worker 
1150*8fb009dcSAndroid Build Coastguard Worker   ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(ctx);
1151*8fb009dcSAndroid Build Coastguard Worker   return 1;
1152*8fb009dcSAndroid Build Coastguard Worker }
1153*8fb009dcSAndroid Build Coastguard Worker 
do_client_cert_cb(SSL * ssl,void * arg)1154*8fb009dcSAndroid Build Coastguard Worker static int do_client_cert_cb(SSL *ssl, void *arg) {
1155*8fb009dcSAndroid Build Coastguard Worker   // Should only be called during handshake, but check to be sure.
1156*8fb009dcSAndroid Build Coastguard Worker   BSSL_CHECK(ssl->config);
1157*8fb009dcSAndroid Build Coastguard Worker 
1158*8fb009dcSAndroid Build Coastguard Worker   if (ssl->config->cert->default_credential->IsComplete() ||
1159*8fb009dcSAndroid Build Coastguard Worker       ssl->ctx->client_cert_cb == nullptr) {
1160*8fb009dcSAndroid Build Coastguard Worker     return 1;
1161*8fb009dcSAndroid Build Coastguard Worker   }
1162*8fb009dcSAndroid Build Coastguard Worker 
1163*8fb009dcSAndroid Build Coastguard Worker   X509 *x509 = NULL;
1164*8fb009dcSAndroid Build Coastguard Worker   EVP_PKEY *pkey = NULL;
1165*8fb009dcSAndroid Build Coastguard Worker   int ret = ssl->ctx->client_cert_cb(ssl, &x509, &pkey);
1166*8fb009dcSAndroid Build Coastguard Worker   if (ret < 0) {
1167*8fb009dcSAndroid Build Coastguard Worker     return -1;
1168*8fb009dcSAndroid Build Coastguard Worker   }
1169*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<X509> free_x509(x509);
1170*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<EVP_PKEY> free_pkey(pkey);
1171*8fb009dcSAndroid Build Coastguard Worker 
1172*8fb009dcSAndroid Build Coastguard Worker   if (ret != 0) {
1173*8fb009dcSAndroid Build Coastguard Worker     if (!SSL_use_certificate(ssl, x509) ||
1174*8fb009dcSAndroid Build Coastguard Worker         !SSL_use_PrivateKey(ssl, pkey)) {
1175*8fb009dcSAndroid Build Coastguard Worker       return 0;
1176*8fb009dcSAndroid Build Coastguard Worker     }
1177*8fb009dcSAndroid Build Coastguard Worker   }
1178*8fb009dcSAndroid Build Coastguard Worker 
1179*8fb009dcSAndroid Build Coastguard Worker   return 1;
1180*8fb009dcSAndroid Build Coastguard Worker }
1181*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set_client_cert_cb(SSL_CTX * ctx,int (* cb)(SSL * ssl,X509 ** out_x509,EVP_PKEY ** out_pkey))1182*8fb009dcSAndroid Build Coastguard Worker void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl,
1183*8fb009dcSAndroid Build Coastguard Worker                                                         X509 **out_x509,
1184*8fb009dcSAndroid Build Coastguard Worker                                                         EVP_PKEY **out_pkey)) {
1185*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
1186*8fb009dcSAndroid Build Coastguard Worker   // Emulate the old client certificate callback with the new one.
1187*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_cert_cb(ctx, do_client_cert_cb, NULL);
1188*8fb009dcSAndroid Build Coastguard Worker   ctx->client_cert_cb = cb;
1189*8fb009dcSAndroid Build Coastguard Worker }
1190*8fb009dcSAndroid Build Coastguard Worker 
set_cert_store(X509_STORE ** store_ptr,X509_STORE * new_store,int take_ref)1191*8fb009dcSAndroid Build Coastguard Worker static int set_cert_store(X509_STORE **store_ptr, X509_STORE *new_store,
1192*8fb009dcSAndroid Build Coastguard Worker                           int take_ref) {
1193*8fb009dcSAndroid Build Coastguard Worker   X509_STORE_free(*store_ptr);
1194*8fb009dcSAndroid Build Coastguard Worker   *store_ptr = new_store;
1195*8fb009dcSAndroid Build Coastguard Worker 
1196*8fb009dcSAndroid Build Coastguard Worker   if (new_store != NULL && take_ref) {
1197*8fb009dcSAndroid Build Coastguard Worker     X509_STORE_up_ref(new_store);
1198*8fb009dcSAndroid Build Coastguard Worker   }
1199*8fb009dcSAndroid Build Coastguard Worker 
1200*8fb009dcSAndroid Build Coastguard Worker   return 1;
1201*8fb009dcSAndroid Build Coastguard Worker }
1202*8fb009dcSAndroid Build Coastguard Worker 
SSL_get_ex_data_X509_STORE_CTX_idx(void)1203*8fb009dcSAndroid Build Coastguard Worker int SSL_get_ex_data_X509_STORE_CTX_idx(void) {
1204*8fb009dcSAndroid Build Coastguard Worker   // The ex_data index to go from |X509_STORE_CTX| to |SSL| always uses the
1205*8fb009dcSAndroid Build Coastguard Worker   // reserved app_data slot. Before ex_data was introduced, app_data was used.
1206*8fb009dcSAndroid Build Coastguard Worker   // Avoid breaking any software which assumes |X509_STORE_CTX_get_app_data|
1207*8fb009dcSAndroid Build Coastguard Worker   // works.
1208*8fb009dcSAndroid Build Coastguard Worker   return 0;
1209*8fb009dcSAndroid Build Coastguard Worker }
1210*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set0_verify_cert_store(SSL_CTX * ctx,X509_STORE * store)1211*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) {
1212*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
1213*8fb009dcSAndroid Build Coastguard Worker   return set_cert_store(&ctx->cert->verify_store, store, 0);
1214*8fb009dcSAndroid Build Coastguard Worker }
1215*8fb009dcSAndroid Build Coastguard Worker 
SSL_CTX_set1_verify_cert_store(SSL_CTX * ctx,X509_STORE * store)1216*8fb009dcSAndroid Build Coastguard Worker int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) {
1217*8fb009dcSAndroid Build Coastguard Worker   check_ssl_ctx_x509_method(ctx);
1218*8fb009dcSAndroid Build Coastguard Worker   return set_cert_store(&ctx->cert->verify_store, store, 1);
1219*8fb009dcSAndroid Build Coastguard Worker }
1220*8fb009dcSAndroid Build Coastguard Worker 
SSL_set0_verify_cert_store(SSL * ssl,X509_STORE * store)1221*8fb009dcSAndroid Build Coastguard Worker int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store) {
1222*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
1223*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
1224*8fb009dcSAndroid Build Coastguard Worker     return 0;
1225*8fb009dcSAndroid Build Coastguard Worker   }
1226*8fb009dcSAndroid Build Coastguard Worker   return set_cert_store(&ssl->config->cert->verify_store, store, 0);
1227*8fb009dcSAndroid Build Coastguard Worker }
1228*8fb009dcSAndroid Build Coastguard Worker 
SSL_set1_verify_cert_store(SSL * ssl,X509_STORE * store)1229*8fb009dcSAndroid Build Coastguard Worker int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store) {
1230*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
1231*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
1232*8fb009dcSAndroid Build Coastguard Worker     return 0;
1233*8fb009dcSAndroid Build Coastguard Worker   }
1234*8fb009dcSAndroid Build Coastguard Worker   return set_cert_store(&ssl->config->cert->verify_store, store, 1);
1235*8fb009dcSAndroid Build Coastguard Worker }
1236*8fb009dcSAndroid Build Coastguard Worker 
SSL_set1_host(SSL * ssl,const char * hostname)1237*8fb009dcSAndroid Build Coastguard Worker int SSL_set1_host(SSL *ssl, const char *hostname) {
1238*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
1239*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
1240*8fb009dcSAndroid Build Coastguard Worker     return 0;
1241*8fb009dcSAndroid Build Coastguard Worker   }
1242*8fb009dcSAndroid Build Coastguard Worker   return X509_VERIFY_PARAM_set1_host(ssl->config->param, hostname,
1243*8fb009dcSAndroid Build Coastguard Worker                                      strlen(hostname));
1244*8fb009dcSAndroid Build Coastguard Worker }
1245*8fb009dcSAndroid Build Coastguard Worker 
SSL_set_hostflags(SSL * ssl,unsigned flags)1246*8fb009dcSAndroid Build Coastguard Worker void SSL_set_hostflags(SSL *ssl, unsigned flags) {
1247*8fb009dcSAndroid Build Coastguard Worker   check_ssl_x509_method(ssl);
1248*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->config) {
1249*8fb009dcSAndroid Build Coastguard Worker     return;
1250*8fb009dcSAndroid Build Coastguard Worker   }
1251*8fb009dcSAndroid Build Coastguard Worker   X509_VERIFY_PARAM_set_hostflags(ssl->config->param, flags);
1252*8fb009dcSAndroid Build Coastguard Worker }
1253*8fb009dcSAndroid Build Coastguard Worker 
SSL_alert_from_verify_result(long result)1254*8fb009dcSAndroid Build Coastguard Worker int SSL_alert_from_verify_result(long result) {
1255*8fb009dcSAndroid Build Coastguard Worker   switch (result) {
1256*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_CERT_CHAIN_TOO_LONG:
1257*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1258*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_INVALID_CA:
1259*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1260*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1261*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_UNABLE_TO_GET_CRL:
1262*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
1263*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1264*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1265*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1266*8fb009dcSAndroid Build Coastguard Worker       return SSL_AD_UNKNOWN_CA;
1267*8fb009dcSAndroid Build Coastguard Worker 
1268*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1269*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
1270*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
1271*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1272*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
1273*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
1274*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
1275*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_CERT_UNTRUSTED:
1276*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_CERT_REJECTED:
1277*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_HOSTNAME_MISMATCH:
1278*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_EMAIL_MISMATCH:
1279*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_IP_ADDRESS_MISMATCH:
1280*8fb009dcSAndroid Build Coastguard Worker       return SSL_AD_BAD_CERTIFICATE;
1281*8fb009dcSAndroid Build Coastguard Worker 
1282*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_CERT_SIGNATURE_FAILURE:
1283*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_CRL_SIGNATURE_FAILURE:
1284*8fb009dcSAndroid Build Coastguard Worker       return SSL_AD_DECRYPT_ERROR;
1285*8fb009dcSAndroid Build Coastguard Worker 
1286*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_CERT_HAS_EXPIRED:
1287*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_CERT_NOT_YET_VALID:
1288*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_CRL_HAS_EXPIRED:
1289*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_CRL_NOT_YET_VALID:
1290*8fb009dcSAndroid Build Coastguard Worker       return SSL_AD_CERTIFICATE_EXPIRED;
1291*8fb009dcSAndroid Build Coastguard Worker 
1292*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_CERT_REVOKED:
1293*8fb009dcSAndroid Build Coastguard Worker       return SSL_AD_CERTIFICATE_REVOKED;
1294*8fb009dcSAndroid Build Coastguard Worker 
1295*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_UNSPECIFIED:
1296*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_OUT_OF_MEM:
1297*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_INVALID_CALL:
1298*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_STORE_LOOKUP:
1299*8fb009dcSAndroid Build Coastguard Worker       return SSL_AD_INTERNAL_ERROR;
1300*8fb009dcSAndroid Build Coastguard Worker 
1301*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_APPLICATION_VERIFICATION:
1302*8fb009dcSAndroid Build Coastguard Worker       return SSL_AD_HANDSHAKE_FAILURE;
1303*8fb009dcSAndroid Build Coastguard Worker 
1304*8fb009dcSAndroid Build Coastguard Worker     case X509_V_ERR_INVALID_PURPOSE:
1305*8fb009dcSAndroid Build Coastguard Worker       return SSL_AD_UNSUPPORTED_CERTIFICATE;
1306*8fb009dcSAndroid Build Coastguard Worker 
1307*8fb009dcSAndroid Build Coastguard Worker     default:
1308*8fb009dcSAndroid Build Coastguard Worker       return SSL_AD_CERTIFICATE_UNKNOWN;
1309*8fb009dcSAndroid Build Coastguard Worker   }
1310*8fb009dcSAndroid Build Coastguard Worker }
1311