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