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