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