xref: /aosp_15_r20/external/boringssl/src/ssl/tls13_both.cc (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1*8fb009dcSAndroid Build Coastguard Worker /* Copyright (c) 2016, Google Inc.
2*8fb009dcSAndroid Build Coastguard Worker  *
3*8fb009dcSAndroid Build Coastguard Worker  * Permission to use, copy, modify, and/or distribute this software for any
4*8fb009dcSAndroid Build Coastguard Worker  * purpose with or without fee is hereby granted, provided that the above
5*8fb009dcSAndroid Build Coastguard Worker  * copyright notice and this permission notice appear in all copies.
6*8fb009dcSAndroid Build Coastguard Worker  *
7*8fb009dcSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8*8fb009dcSAndroid Build Coastguard Worker  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9*8fb009dcSAndroid Build Coastguard Worker  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10*8fb009dcSAndroid Build Coastguard Worker  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11*8fb009dcSAndroid Build Coastguard Worker  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12*8fb009dcSAndroid Build Coastguard Worker  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13*8fb009dcSAndroid Build Coastguard Worker  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14*8fb009dcSAndroid Build Coastguard Worker 
15*8fb009dcSAndroid Build Coastguard Worker #include <openssl/ssl.h>
16*8fb009dcSAndroid Build Coastguard Worker 
17*8fb009dcSAndroid Build Coastguard Worker #include <assert.h>
18*8fb009dcSAndroid Build Coastguard Worker #include <string.h>
19*8fb009dcSAndroid Build Coastguard Worker 
20*8fb009dcSAndroid Build Coastguard Worker #include <utility>
21*8fb009dcSAndroid Build Coastguard Worker 
22*8fb009dcSAndroid Build Coastguard Worker #include <openssl/bytestring.h>
23*8fb009dcSAndroid Build Coastguard Worker #include <openssl/err.h>
24*8fb009dcSAndroid Build Coastguard Worker #include <openssl/hkdf.h>
25*8fb009dcSAndroid Build Coastguard Worker #include <openssl/mem.h>
26*8fb009dcSAndroid Build Coastguard Worker #include <openssl/stack.h>
27*8fb009dcSAndroid Build Coastguard Worker #include <openssl/x509.h>
28*8fb009dcSAndroid Build Coastguard Worker 
29*8fb009dcSAndroid Build Coastguard Worker #include "../crypto/internal.h"
30*8fb009dcSAndroid Build Coastguard Worker #include "internal.h"
31*8fb009dcSAndroid Build Coastguard Worker 
32*8fb009dcSAndroid Build Coastguard Worker 
33*8fb009dcSAndroid Build Coastguard Worker BSSL_NAMESPACE_BEGIN
34*8fb009dcSAndroid Build Coastguard Worker 
35*8fb009dcSAndroid Build Coastguard Worker // kMaxKeyUpdates is the number of consecutive KeyUpdates that will be
36*8fb009dcSAndroid Build Coastguard Worker // processed. Without this limit an attacker could force unbounded processing
37*8fb009dcSAndroid Build Coastguard Worker // without being able to return application data.
38*8fb009dcSAndroid Build Coastguard Worker static const uint8_t kMaxKeyUpdates = 32;
39*8fb009dcSAndroid Build Coastguard Worker 
40*8fb009dcSAndroid Build Coastguard Worker const uint8_t kHelloRetryRequest[SSL3_RANDOM_SIZE] = {
41*8fb009dcSAndroid Build Coastguard Worker     0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c,
42*8fb009dcSAndroid Build Coastguard Worker     0x02, 0x1e, 0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb,
43*8fb009dcSAndroid Build Coastguard Worker     0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c,
44*8fb009dcSAndroid Build Coastguard Worker };
45*8fb009dcSAndroid Build Coastguard Worker 
46*8fb009dcSAndroid Build Coastguard Worker // See RFC 8446, section 4.1.3.
47*8fb009dcSAndroid Build Coastguard Worker const uint8_t kTLS12DowngradeRandom[8] = {0x44, 0x4f, 0x57, 0x4e,
48*8fb009dcSAndroid Build Coastguard Worker                                           0x47, 0x52, 0x44, 0x00};
49*8fb009dcSAndroid Build Coastguard Worker const uint8_t kTLS13DowngradeRandom[8] = {0x44, 0x4f, 0x57, 0x4e,
50*8fb009dcSAndroid Build Coastguard Worker                                           0x47, 0x52, 0x44, 0x01};
51*8fb009dcSAndroid Build Coastguard Worker 
52*8fb009dcSAndroid Build Coastguard Worker // This is a non-standard randomly-generated value.
53*8fb009dcSAndroid Build Coastguard Worker const uint8_t kJDK11DowngradeRandom[8] = {0xed, 0xbf, 0xb4, 0xa8,
54*8fb009dcSAndroid Build Coastguard Worker                                           0xc2, 0x47, 0x10, 0xff};
55*8fb009dcSAndroid Build Coastguard Worker 
tls13_get_cert_verify_signature_input(SSL_HANDSHAKE * hs,Array<uint8_t> * out,enum ssl_cert_verify_context_t cert_verify_context)56*8fb009dcSAndroid Build Coastguard Worker bool tls13_get_cert_verify_signature_input(
57*8fb009dcSAndroid Build Coastguard Worker     SSL_HANDSHAKE *hs, Array<uint8_t> *out,
58*8fb009dcSAndroid Build Coastguard Worker     enum ssl_cert_verify_context_t cert_verify_context) {
59*8fb009dcSAndroid Build Coastguard Worker   ScopedCBB cbb;
60*8fb009dcSAndroid Build Coastguard Worker   if (!CBB_init(cbb.get(), 64 + 33 + 1 + 2 * EVP_MAX_MD_SIZE)) {
61*8fb009dcSAndroid Build Coastguard Worker     return false;
62*8fb009dcSAndroid Build Coastguard Worker   }
63*8fb009dcSAndroid Build Coastguard Worker 
64*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < 64; i++) {
65*8fb009dcSAndroid Build Coastguard Worker     if (!CBB_add_u8(cbb.get(), 0x20)) {
66*8fb009dcSAndroid Build Coastguard Worker       return false;
67*8fb009dcSAndroid Build Coastguard Worker     }
68*8fb009dcSAndroid Build Coastguard Worker   }
69*8fb009dcSAndroid Build Coastguard Worker 
70*8fb009dcSAndroid Build Coastguard Worker   Span<const char> context;
71*8fb009dcSAndroid Build Coastguard Worker   if (cert_verify_context == ssl_cert_verify_server) {
72*8fb009dcSAndroid Build Coastguard Worker     static const char kContext[] = "TLS 1.3, server CertificateVerify";
73*8fb009dcSAndroid Build Coastguard Worker     context = kContext;
74*8fb009dcSAndroid Build Coastguard Worker   } else if (cert_verify_context == ssl_cert_verify_client) {
75*8fb009dcSAndroid Build Coastguard Worker     static const char kContext[] = "TLS 1.3, client CertificateVerify";
76*8fb009dcSAndroid Build Coastguard Worker     context = kContext;
77*8fb009dcSAndroid Build Coastguard Worker   } else if (cert_verify_context == ssl_cert_verify_channel_id) {
78*8fb009dcSAndroid Build Coastguard Worker     static const char kContext[] = "TLS 1.3, Channel ID";
79*8fb009dcSAndroid Build Coastguard Worker     context = kContext;
80*8fb009dcSAndroid Build Coastguard Worker   } else {
81*8fb009dcSAndroid Build Coastguard Worker     return false;
82*8fb009dcSAndroid Build Coastguard Worker   }
83*8fb009dcSAndroid Build Coastguard Worker 
84*8fb009dcSAndroid Build Coastguard Worker   // Note |context| includes the NUL byte separator.
85*8fb009dcSAndroid Build Coastguard Worker   if (!CBB_add_bytes(cbb.get(),
86*8fb009dcSAndroid Build Coastguard Worker                      reinterpret_cast<const uint8_t *>(context.data()),
87*8fb009dcSAndroid Build Coastguard Worker                      context.size())) {
88*8fb009dcSAndroid Build Coastguard Worker     return false;
89*8fb009dcSAndroid Build Coastguard Worker   }
90*8fb009dcSAndroid Build Coastguard Worker 
91*8fb009dcSAndroid Build Coastguard Worker   uint8_t context_hash[EVP_MAX_MD_SIZE];
92*8fb009dcSAndroid Build Coastguard Worker   size_t context_hash_len;
93*8fb009dcSAndroid Build Coastguard Worker   if (!hs->transcript.GetHash(context_hash, &context_hash_len) ||
94*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_bytes(cbb.get(), context_hash, context_hash_len) ||
95*8fb009dcSAndroid Build Coastguard Worker       !CBBFinishArray(cbb.get(), out)) {
96*8fb009dcSAndroid Build Coastguard Worker     return false;
97*8fb009dcSAndroid Build Coastguard Worker   }
98*8fb009dcSAndroid Build Coastguard Worker 
99*8fb009dcSAndroid Build Coastguard Worker   return true;
100*8fb009dcSAndroid Build Coastguard Worker }
101*8fb009dcSAndroid Build Coastguard Worker 
tls13_process_certificate(SSL_HANDSHAKE * hs,const SSLMessage & msg,bool allow_anonymous)102*8fb009dcSAndroid Build Coastguard Worker bool tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg,
103*8fb009dcSAndroid Build Coastguard Worker                                bool allow_anonymous) {
104*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
105*8fb009dcSAndroid Build Coastguard Worker   CBS body = msg.body;
106*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> decompressed;
107*8fb009dcSAndroid Build Coastguard Worker 
108*8fb009dcSAndroid Build Coastguard Worker   if (msg.type == SSL3_MT_COMPRESSED_CERTIFICATE) {
109*8fb009dcSAndroid Build Coastguard Worker     CBS compressed;
110*8fb009dcSAndroid Build Coastguard Worker     uint16_t alg_id;
111*8fb009dcSAndroid Build Coastguard Worker     uint32_t uncompressed_len;
112*8fb009dcSAndroid Build Coastguard Worker 
113*8fb009dcSAndroid Build Coastguard Worker     if (!CBS_get_u16(&body, &alg_id) ||
114*8fb009dcSAndroid Build Coastguard Worker         !CBS_get_u24(&body, &uncompressed_len) ||
115*8fb009dcSAndroid Build Coastguard Worker         !CBS_get_u24_length_prefixed(&body, &compressed) ||
116*8fb009dcSAndroid Build Coastguard Worker         CBS_len(&body) != 0) {
117*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
118*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
119*8fb009dcSAndroid Build Coastguard Worker       return false;
120*8fb009dcSAndroid Build Coastguard Worker     }
121*8fb009dcSAndroid Build Coastguard Worker 
122*8fb009dcSAndroid Build Coastguard Worker     if (uncompressed_len > ssl->max_cert_list) {
123*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
124*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_UNCOMPRESSED_CERT_TOO_LARGE);
125*8fb009dcSAndroid Build Coastguard Worker       ERR_add_error_dataf("requested=%u",
126*8fb009dcSAndroid Build Coastguard Worker                           static_cast<unsigned>(uncompressed_len));
127*8fb009dcSAndroid Build Coastguard Worker       return false;
128*8fb009dcSAndroid Build Coastguard Worker     }
129*8fb009dcSAndroid Build Coastguard Worker 
130*8fb009dcSAndroid Build Coastguard Worker     ssl_cert_decompression_func_t decompress = nullptr;
131*8fb009dcSAndroid Build Coastguard Worker     for (const auto &alg : ssl->ctx->cert_compression_algs) {
132*8fb009dcSAndroid Build Coastguard Worker       if (alg.alg_id == alg_id) {
133*8fb009dcSAndroid Build Coastguard Worker         decompress = alg.decompress;
134*8fb009dcSAndroid Build Coastguard Worker         break;
135*8fb009dcSAndroid Build Coastguard Worker       }
136*8fb009dcSAndroid Build Coastguard Worker     }
137*8fb009dcSAndroid Build Coastguard Worker 
138*8fb009dcSAndroid Build Coastguard Worker     if (decompress == nullptr) {
139*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
140*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERT_COMPRESSION_ALG);
141*8fb009dcSAndroid Build Coastguard Worker       ERR_add_error_dataf("alg=%d", static_cast<int>(alg_id));
142*8fb009dcSAndroid Build Coastguard Worker       return false;
143*8fb009dcSAndroid Build Coastguard Worker     }
144*8fb009dcSAndroid Build Coastguard Worker 
145*8fb009dcSAndroid Build Coastguard Worker     CRYPTO_BUFFER *decompressed_ptr = nullptr;
146*8fb009dcSAndroid Build Coastguard Worker     if (!decompress(ssl, &decompressed_ptr, uncompressed_len,
147*8fb009dcSAndroid Build Coastguard Worker                     CBS_data(&compressed), CBS_len(&compressed))) {
148*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
149*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_DECOMPRESSION_FAILED);
150*8fb009dcSAndroid Build Coastguard Worker       ERR_add_error_dataf("alg=%d", static_cast<int>(alg_id));
151*8fb009dcSAndroid Build Coastguard Worker       return false;
152*8fb009dcSAndroid Build Coastguard Worker     }
153*8fb009dcSAndroid Build Coastguard Worker     decompressed.reset(decompressed_ptr);
154*8fb009dcSAndroid Build Coastguard Worker 
155*8fb009dcSAndroid Build Coastguard Worker     if (CRYPTO_BUFFER_len(decompressed_ptr) != uncompressed_len) {
156*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
157*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_DECOMPRESSION_FAILED);
158*8fb009dcSAndroid Build Coastguard Worker       ERR_add_error_dataf(
159*8fb009dcSAndroid Build Coastguard Worker           "alg=%d got=%u expected=%u", static_cast<int>(alg_id),
160*8fb009dcSAndroid Build Coastguard Worker           static_cast<unsigned>(CRYPTO_BUFFER_len(decompressed_ptr)),
161*8fb009dcSAndroid Build Coastguard Worker           static_cast<unsigned>(uncompressed_len));
162*8fb009dcSAndroid Build Coastguard Worker       return false;
163*8fb009dcSAndroid Build Coastguard Worker     }
164*8fb009dcSAndroid Build Coastguard Worker 
165*8fb009dcSAndroid Build Coastguard Worker     CBS_init(&body, CRYPTO_BUFFER_data(decompressed_ptr),
166*8fb009dcSAndroid Build Coastguard Worker              CRYPTO_BUFFER_len(decompressed_ptr));
167*8fb009dcSAndroid Build Coastguard Worker   } else {
168*8fb009dcSAndroid Build Coastguard Worker     assert(msg.type == SSL3_MT_CERTIFICATE);
169*8fb009dcSAndroid Build Coastguard Worker   }
170*8fb009dcSAndroid Build Coastguard Worker 
171*8fb009dcSAndroid Build Coastguard Worker   CBS context, certificate_list;
172*8fb009dcSAndroid Build Coastguard Worker   if (!CBS_get_u8_length_prefixed(&body, &context) ||
173*8fb009dcSAndroid Build Coastguard Worker       CBS_len(&context) != 0 ||
174*8fb009dcSAndroid Build Coastguard Worker       !CBS_get_u24_length_prefixed(&body, &certificate_list) ||
175*8fb009dcSAndroid Build Coastguard Worker       CBS_len(&body) != 0) {
176*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
177*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
178*8fb009dcSAndroid Build Coastguard Worker     return false;
179*8fb009dcSAndroid Build Coastguard Worker   }
180*8fb009dcSAndroid Build Coastguard Worker 
181*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<STACK_OF(CRYPTO_BUFFER)> certs(sk_CRYPTO_BUFFER_new_null());
182*8fb009dcSAndroid Build Coastguard Worker   if (!certs) {
183*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
184*8fb009dcSAndroid Build Coastguard Worker     return false;
185*8fb009dcSAndroid Build Coastguard Worker   }
186*8fb009dcSAndroid Build Coastguard Worker 
187*8fb009dcSAndroid Build Coastguard Worker   const bool retain_sha256 =
188*8fb009dcSAndroid Build Coastguard Worker       ssl->server && hs->config->retain_only_sha256_of_client_certs;
189*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<EVP_PKEY> pkey;
190*8fb009dcSAndroid Build Coastguard Worker   while (CBS_len(&certificate_list) > 0) {
191*8fb009dcSAndroid Build Coastguard Worker     CBS certificate, extensions;
192*8fb009dcSAndroid Build Coastguard Worker     if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) ||
193*8fb009dcSAndroid Build Coastguard Worker         !CBS_get_u16_length_prefixed(&certificate_list, &extensions) ||
194*8fb009dcSAndroid Build Coastguard Worker         CBS_len(&certificate) == 0) {
195*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
196*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
197*8fb009dcSAndroid Build Coastguard Worker       return false;
198*8fb009dcSAndroid Build Coastguard Worker     }
199*8fb009dcSAndroid Build Coastguard Worker 
200*8fb009dcSAndroid Build Coastguard Worker     if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) {
201*8fb009dcSAndroid Build Coastguard Worker       pkey = ssl_cert_parse_pubkey(&certificate);
202*8fb009dcSAndroid Build Coastguard Worker       if (!pkey) {
203*8fb009dcSAndroid Build Coastguard Worker         ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
204*8fb009dcSAndroid Build Coastguard Worker         OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
205*8fb009dcSAndroid Build Coastguard Worker         return false;
206*8fb009dcSAndroid Build Coastguard Worker       }
207*8fb009dcSAndroid Build Coastguard Worker       // TLS 1.3 always uses certificate keys for signing thus the correct
208*8fb009dcSAndroid Build Coastguard Worker       // keyUsage is enforced.
209*8fb009dcSAndroid Build Coastguard Worker       if (!ssl_cert_check_key_usage(&certificate,
210*8fb009dcSAndroid Build Coastguard Worker                                     key_usage_digital_signature)) {
211*8fb009dcSAndroid Build Coastguard Worker         ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
212*8fb009dcSAndroid Build Coastguard Worker         return false;
213*8fb009dcSAndroid Build Coastguard Worker       }
214*8fb009dcSAndroid Build Coastguard Worker 
215*8fb009dcSAndroid Build Coastguard Worker       if (retain_sha256) {
216*8fb009dcSAndroid Build Coastguard Worker         // Retain the hash of the leaf certificate if requested.
217*8fb009dcSAndroid Build Coastguard Worker         SHA256(CBS_data(&certificate), CBS_len(&certificate),
218*8fb009dcSAndroid Build Coastguard Worker                hs->new_session->peer_sha256);
219*8fb009dcSAndroid Build Coastguard Worker       }
220*8fb009dcSAndroid Build Coastguard Worker     }
221*8fb009dcSAndroid Build Coastguard Worker 
222*8fb009dcSAndroid Build Coastguard Worker     UniquePtr<CRYPTO_BUFFER> buf(
223*8fb009dcSAndroid Build Coastguard Worker         CRYPTO_BUFFER_new_from_CBS(&certificate, ssl->ctx->pool));
224*8fb009dcSAndroid Build Coastguard Worker     if (!buf ||
225*8fb009dcSAndroid Build Coastguard Worker         !PushToStack(certs.get(), std::move(buf))) {
226*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
227*8fb009dcSAndroid Build Coastguard Worker       return false;
228*8fb009dcSAndroid Build Coastguard Worker     }
229*8fb009dcSAndroid Build Coastguard Worker 
230*8fb009dcSAndroid Build Coastguard Worker     // Parse out the extensions.
231*8fb009dcSAndroid Build Coastguard Worker     SSLExtension status_request(
232*8fb009dcSAndroid Build Coastguard Worker         TLSEXT_TYPE_status_request,
233*8fb009dcSAndroid Build Coastguard Worker         !ssl->server && hs->config->ocsp_stapling_enabled);
234*8fb009dcSAndroid Build Coastguard Worker     SSLExtension sct(
235*8fb009dcSAndroid Build Coastguard Worker         TLSEXT_TYPE_certificate_timestamp,
236*8fb009dcSAndroid Build Coastguard Worker         !ssl->server && hs->config->signed_cert_timestamps_enabled);
237*8fb009dcSAndroid Build Coastguard Worker     uint8_t alert = SSL_AD_DECODE_ERROR;
238*8fb009dcSAndroid Build Coastguard Worker     if (!ssl_parse_extensions(&extensions, &alert, {&status_request, &sct},
239*8fb009dcSAndroid Build Coastguard Worker                               /*ignore_unknown=*/false)) {
240*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
241*8fb009dcSAndroid Build Coastguard Worker       return false;
242*8fb009dcSAndroid Build Coastguard Worker     }
243*8fb009dcSAndroid Build Coastguard Worker 
244*8fb009dcSAndroid Build Coastguard Worker     // All Certificate extensions are parsed, but only the leaf extensions are
245*8fb009dcSAndroid Build Coastguard Worker     // stored.
246*8fb009dcSAndroid Build Coastguard Worker     if (status_request.present) {
247*8fb009dcSAndroid Build Coastguard Worker       uint8_t status_type;
248*8fb009dcSAndroid Build Coastguard Worker       CBS ocsp_response;
249*8fb009dcSAndroid Build Coastguard Worker       if (!CBS_get_u8(&status_request.data, &status_type) ||
250*8fb009dcSAndroid Build Coastguard Worker           status_type != TLSEXT_STATUSTYPE_ocsp ||
251*8fb009dcSAndroid Build Coastguard Worker           !CBS_get_u24_length_prefixed(&status_request.data, &ocsp_response) ||
252*8fb009dcSAndroid Build Coastguard Worker           CBS_len(&ocsp_response) == 0 ||
253*8fb009dcSAndroid Build Coastguard Worker           CBS_len(&status_request.data) != 0) {
254*8fb009dcSAndroid Build Coastguard Worker         ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
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(certs.get()) == 1) {
259*8fb009dcSAndroid Build Coastguard Worker         hs->new_session->ocsp_response.reset(
260*8fb009dcSAndroid Build Coastguard Worker             CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool));
261*8fb009dcSAndroid Build Coastguard Worker         if (hs->new_session->ocsp_response == nullptr) {
262*8fb009dcSAndroid Build Coastguard Worker           ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
263*8fb009dcSAndroid Build Coastguard Worker           return false;
264*8fb009dcSAndroid Build Coastguard Worker         }
265*8fb009dcSAndroid Build Coastguard Worker       }
266*8fb009dcSAndroid Build Coastguard Worker     }
267*8fb009dcSAndroid Build Coastguard Worker 
268*8fb009dcSAndroid Build Coastguard Worker     if (sct.present) {
269*8fb009dcSAndroid Build Coastguard Worker       if (!ssl_is_sct_list_valid(&sct.data)) {
270*8fb009dcSAndroid Build Coastguard Worker         OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
271*8fb009dcSAndroid Build Coastguard Worker         ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
272*8fb009dcSAndroid Build Coastguard Worker         return false;
273*8fb009dcSAndroid Build Coastguard Worker       }
274*8fb009dcSAndroid Build Coastguard Worker 
275*8fb009dcSAndroid Build Coastguard Worker       if (sk_CRYPTO_BUFFER_num(certs.get()) == 1) {
276*8fb009dcSAndroid Build Coastguard Worker         hs->new_session->signed_cert_timestamp_list.reset(
277*8fb009dcSAndroid Build Coastguard Worker             CRYPTO_BUFFER_new_from_CBS(&sct.data, ssl->ctx->pool));
278*8fb009dcSAndroid Build Coastguard Worker         if (hs->new_session->signed_cert_timestamp_list == nullptr) {
279*8fb009dcSAndroid Build Coastguard Worker           ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
280*8fb009dcSAndroid Build Coastguard Worker           return false;
281*8fb009dcSAndroid Build Coastguard Worker         }
282*8fb009dcSAndroid Build Coastguard Worker       }
283*8fb009dcSAndroid Build Coastguard Worker     }
284*8fb009dcSAndroid Build Coastguard Worker   }
285*8fb009dcSAndroid Build Coastguard Worker 
286*8fb009dcSAndroid Build Coastguard Worker   // Store a null certificate list rather than an empty one if the peer didn't
287*8fb009dcSAndroid Build Coastguard Worker   // send certificates.
288*8fb009dcSAndroid Build Coastguard Worker   if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) {
289*8fb009dcSAndroid Build Coastguard Worker     certs.reset();
290*8fb009dcSAndroid Build Coastguard Worker   }
291*8fb009dcSAndroid Build Coastguard Worker 
292*8fb009dcSAndroid Build Coastguard Worker   hs->peer_pubkey = std::move(pkey);
293*8fb009dcSAndroid Build Coastguard Worker   hs->new_session->certs = std::move(certs);
294*8fb009dcSAndroid Build Coastguard Worker 
295*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) {
296*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
297*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
298*8fb009dcSAndroid Build Coastguard Worker     return false;
299*8fb009dcSAndroid Build Coastguard Worker   }
300*8fb009dcSAndroid Build Coastguard Worker 
301*8fb009dcSAndroid Build Coastguard Worker   if (sk_CRYPTO_BUFFER_num(hs->new_session->certs.get()) == 0) {
302*8fb009dcSAndroid Build Coastguard Worker     if (!allow_anonymous) {
303*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
304*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED);
305*8fb009dcSAndroid Build Coastguard Worker       return false;
306*8fb009dcSAndroid Build Coastguard Worker     }
307*8fb009dcSAndroid Build Coastguard Worker 
308*8fb009dcSAndroid Build Coastguard Worker     // OpenSSL returns X509_V_OK when no certificates are requested. This is
309*8fb009dcSAndroid Build Coastguard Worker     // classed by them as a bug, but it's assumed by at least NGINX.
310*8fb009dcSAndroid Build Coastguard Worker     hs->new_session->verify_result = X509_V_OK;
311*8fb009dcSAndroid Build Coastguard Worker 
312*8fb009dcSAndroid Build Coastguard Worker     // No certificate, so nothing more to do.
313*8fb009dcSAndroid Build Coastguard Worker     return true;
314*8fb009dcSAndroid Build Coastguard Worker   }
315*8fb009dcSAndroid Build Coastguard Worker 
316*8fb009dcSAndroid Build Coastguard Worker   hs->new_session->peer_sha256_valid = retain_sha256;
317*8fb009dcSAndroid Build Coastguard Worker   return true;
318*8fb009dcSAndroid Build Coastguard Worker }
319*8fb009dcSAndroid Build Coastguard Worker 
tls13_process_certificate_verify(SSL_HANDSHAKE * hs,const SSLMessage & msg)320*8fb009dcSAndroid Build Coastguard Worker bool tls13_process_certificate_verify(SSL_HANDSHAKE *hs, const SSLMessage &msg) {
321*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
322*8fb009dcSAndroid Build Coastguard Worker   if (hs->peer_pubkey == NULL) {
323*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
324*8fb009dcSAndroid Build Coastguard Worker     return false;
325*8fb009dcSAndroid Build Coastguard Worker   }
326*8fb009dcSAndroid Build Coastguard Worker 
327*8fb009dcSAndroid Build Coastguard Worker   CBS body = msg.body, signature;
328*8fb009dcSAndroid Build Coastguard Worker   uint16_t signature_algorithm;
329*8fb009dcSAndroid Build Coastguard Worker   if (!CBS_get_u16(&body, &signature_algorithm) ||
330*8fb009dcSAndroid Build Coastguard Worker       !CBS_get_u16_length_prefixed(&body, &signature) ||
331*8fb009dcSAndroid Build Coastguard Worker       CBS_len(&body) != 0) {
332*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
333*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
334*8fb009dcSAndroid Build Coastguard Worker     return false;
335*8fb009dcSAndroid Build Coastguard Worker   }
336*8fb009dcSAndroid Build Coastguard Worker 
337*8fb009dcSAndroid Build Coastguard Worker   uint8_t alert = SSL_AD_DECODE_ERROR;
338*8fb009dcSAndroid Build Coastguard Worker   if (!tls12_check_peer_sigalg(hs, &alert, signature_algorithm,
339*8fb009dcSAndroid Build Coastguard Worker                                hs->peer_pubkey.get())) {
340*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
341*8fb009dcSAndroid Build Coastguard Worker     return false;
342*8fb009dcSAndroid Build Coastguard Worker   }
343*8fb009dcSAndroid Build Coastguard Worker   hs->new_session->peer_signature_algorithm = signature_algorithm;
344*8fb009dcSAndroid Build Coastguard Worker 
345*8fb009dcSAndroid Build Coastguard Worker   Array<uint8_t> input;
346*8fb009dcSAndroid Build Coastguard Worker   if (!tls13_get_cert_verify_signature_input(
347*8fb009dcSAndroid Build Coastguard Worker           hs, &input,
348*8fb009dcSAndroid Build Coastguard Worker           ssl->server ? ssl_cert_verify_client : ssl_cert_verify_server)) {
349*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
350*8fb009dcSAndroid Build Coastguard Worker     return false;
351*8fb009dcSAndroid Build Coastguard Worker   }
352*8fb009dcSAndroid Build Coastguard Worker 
353*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_public_key_verify(ssl, signature, signature_algorithm,
354*8fb009dcSAndroid Build Coastguard Worker                              hs->peer_pubkey.get(), input)) {
355*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
356*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
357*8fb009dcSAndroid Build Coastguard Worker     return false;
358*8fb009dcSAndroid Build Coastguard Worker   }
359*8fb009dcSAndroid Build Coastguard Worker 
360*8fb009dcSAndroid Build Coastguard Worker   return true;
361*8fb009dcSAndroid Build Coastguard Worker }
362*8fb009dcSAndroid Build Coastguard Worker 
tls13_process_finished(SSL_HANDSHAKE * hs,const SSLMessage & msg,bool use_saved_value)363*8fb009dcSAndroid Build Coastguard Worker bool tls13_process_finished(SSL_HANDSHAKE *hs, const SSLMessage &msg,
364*8fb009dcSAndroid Build Coastguard Worker                             bool use_saved_value) {
365*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
366*8fb009dcSAndroid Build Coastguard Worker   uint8_t verify_data_buf[EVP_MAX_MD_SIZE];
367*8fb009dcSAndroid Build Coastguard Worker   Span<const uint8_t> verify_data;
368*8fb009dcSAndroid Build Coastguard Worker   if (use_saved_value) {
369*8fb009dcSAndroid Build Coastguard Worker     assert(ssl->server);
370*8fb009dcSAndroid Build Coastguard Worker     verify_data = hs->expected_client_finished();
371*8fb009dcSAndroid Build Coastguard Worker   } else {
372*8fb009dcSAndroid Build Coastguard Worker     size_t len;
373*8fb009dcSAndroid Build Coastguard Worker     if (!tls13_finished_mac(hs, verify_data_buf, &len, !ssl->server)) {
374*8fb009dcSAndroid Build Coastguard Worker       return false;
375*8fb009dcSAndroid Build Coastguard Worker     }
376*8fb009dcSAndroid Build Coastguard Worker     verify_data = MakeConstSpan(verify_data_buf, len);
377*8fb009dcSAndroid Build Coastguard Worker   }
378*8fb009dcSAndroid Build Coastguard Worker 
379*8fb009dcSAndroid Build Coastguard Worker   bool finished_ok =
380*8fb009dcSAndroid Build Coastguard Worker       CBS_mem_equal(&msg.body, verify_data.data(), verify_data.size());
381*8fb009dcSAndroid Build Coastguard Worker #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
382*8fb009dcSAndroid Build Coastguard Worker   finished_ok = true;
383*8fb009dcSAndroid Build Coastguard Worker #endif
384*8fb009dcSAndroid Build Coastguard Worker   if (!finished_ok) {
385*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
386*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
387*8fb009dcSAndroid Build Coastguard Worker     return false;
388*8fb009dcSAndroid Build Coastguard Worker   }
389*8fb009dcSAndroid Build Coastguard Worker 
390*8fb009dcSAndroid Build Coastguard Worker   return true;
391*8fb009dcSAndroid Build Coastguard Worker }
392*8fb009dcSAndroid Build Coastguard Worker 
tls13_add_certificate(SSL_HANDSHAKE * hs)393*8fb009dcSAndroid Build Coastguard Worker bool tls13_add_certificate(SSL_HANDSHAKE *hs) {
394*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
395*8fb009dcSAndroid Build Coastguard Worker   const SSL_CREDENTIAL *cred = hs->credential.get();
396*8fb009dcSAndroid Build Coastguard Worker 
397*8fb009dcSAndroid Build Coastguard Worker   ScopedCBB cbb;
398*8fb009dcSAndroid Build Coastguard Worker   CBB *body, body_storage, certificate_list;
399*8fb009dcSAndroid Build Coastguard Worker 
400*8fb009dcSAndroid Build Coastguard Worker   if (hs->cert_compression_negotiated) {
401*8fb009dcSAndroid Build Coastguard Worker     if (!CBB_init(cbb.get(), 1024)) {
402*8fb009dcSAndroid Build Coastguard Worker       return false;
403*8fb009dcSAndroid Build Coastguard Worker     }
404*8fb009dcSAndroid Build Coastguard Worker     body = cbb.get();
405*8fb009dcSAndroid Build Coastguard Worker   } else {
406*8fb009dcSAndroid Build Coastguard Worker     body = &body_storage;
407*8fb009dcSAndroid Build Coastguard Worker     if (!ssl->method->init_message(ssl, cbb.get(), body, SSL3_MT_CERTIFICATE)) {
408*8fb009dcSAndroid Build Coastguard Worker       return false;
409*8fb009dcSAndroid Build Coastguard Worker     }
410*8fb009dcSAndroid Build Coastguard Worker   }
411*8fb009dcSAndroid Build Coastguard Worker 
412*8fb009dcSAndroid Build Coastguard Worker   if (// The request context is always empty in the handshake.
413*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u8(body, 0) ||
414*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u24_length_prefixed(body, &certificate_list)) {
415*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
416*8fb009dcSAndroid Build Coastguard Worker     return false;
417*8fb009dcSAndroid Build Coastguard Worker   }
418*8fb009dcSAndroid Build Coastguard Worker 
419*8fb009dcSAndroid Build Coastguard Worker   if (hs->credential == nullptr) {
420*8fb009dcSAndroid Build Coastguard Worker     return ssl_add_message_cbb(ssl, cbb.get());
421*8fb009dcSAndroid Build Coastguard Worker   }
422*8fb009dcSAndroid Build Coastguard Worker 
423*8fb009dcSAndroid Build Coastguard Worker   assert(hs->credential->UsesX509());
424*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_BUFFER *leaf_buf = sk_CRYPTO_BUFFER_value(cred->chain.get(), 0);
425*8fb009dcSAndroid Build Coastguard Worker   CBB leaf, extensions;
426*8fb009dcSAndroid Build Coastguard Worker   if (!CBB_add_u24_length_prefixed(&certificate_list, &leaf) ||
427*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_bytes(&leaf, CRYPTO_BUFFER_data(leaf_buf),
428*8fb009dcSAndroid Build Coastguard Worker                      CRYPTO_BUFFER_len(leaf_buf)) ||
429*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16_length_prefixed(&certificate_list, &extensions)) {
430*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
431*8fb009dcSAndroid Build Coastguard Worker     return false;
432*8fb009dcSAndroid Build Coastguard Worker   }
433*8fb009dcSAndroid Build Coastguard Worker 
434*8fb009dcSAndroid Build Coastguard Worker   if (hs->scts_requested && cred->signed_cert_timestamp_list != nullptr) {
435*8fb009dcSAndroid Build Coastguard Worker     CBB contents;
436*8fb009dcSAndroid Build Coastguard Worker     if (!CBB_add_u16(&extensions, TLSEXT_TYPE_certificate_timestamp) ||
437*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u16_length_prefixed(&extensions, &contents) ||
438*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_bytes(
439*8fb009dcSAndroid Build Coastguard Worker             &contents,
440*8fb009dcSAndroid Build Coastguard Worker             CRYPTO_BUFFER_data(cred->signed_cert_timestamp_list.get()),
441*8fb009dcSAndroid Build Coastguard Worker             CRYPTO_BUFFER_len(cred->signed_cert_timestamp_list.get())) ||
442*8fb009dcSAndroid Build Coastguard Worker         !CBB_flush(&extensions)) {
443*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
444*8fb009dcSAndroid Build Coastguard Worker       return false;
445*8fb009dcSAndroid Build Coastguard Worker     }
446*8fb009dcSAndroid Build Coastguard Worker   }
447*8fb009dcSAndroid Build Coastguard Worker 
448*8fb009dcSAndroid Build Coastguard Worker   if (hs->ocsp_stapling_requested && cred->ocsp_response != NULL) {
449*8fb009dcSAndroid Build Coastguard Worker     CBB contents, ocsp_response;
450*8fb009dcSAndroid Build Coastguard Worker     if (!CBB_add_u16(&extensions, TLSEXT_TYPE_status_request) ||
451*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u16_length_prefixed(&extensions, &contents) ||
452*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) ||
453*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u24_length_prefixed(&contents, &ocsp_response) ||
454*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_bytes(&ocsp_response,
455*8fb009dcSAndroid Build Coastguard Worker                        CRYPTO_BUFFER_data(cred->ocsp_response.get()),
456*8fb009dcSAndroid Build Coastguard Worker                        CRYPTO_BUFFER_len(cred->ocsp_response.get())) ||
457*8fb009dcSAndroid Build Coastguard Worker         !CBB_flush(&extensions)) {
458*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
459*8fb009dcSAndroid Build Coastguard Worker       return false;
460*8fb009dcSAndroid Build Coastguard Worker     }
461*8fb009dcSAndroid Build Coastguard Worker   }
462*8fb009dcSAndroid Build Coastguard Worker 
463*8fb009dcSAndroid Build Coastguard Worker   if (cred->type == SSLCredentialType::kDelegated) {
464*8fb009dcSAndroid Build Coastguard Worker     CBB child;
465*8fb009dcSAndroid Build Coastguard Worker     if (!CBB_add_u16(&extensions, TLSEXT_TYPE_delegated_credential) ||
466*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u16_length_prefixed(&extensions, &child) ||
467*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_bytes(&child, CRYPTO_BUFFER_data(cred->dc.get()),
468*8fb009dcSAndroid Build Coastguard Worker                        CRYPTO_BUFFER_len(cred->dc.get())) ||
469*8fb009dcSAndroid Build Coastguard Worker         !CBB_flush(&extensions)) {
470*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
471*8fb009dcSAndroid Build Coastguard Worker       return false;
472*8fb009dcSAndroid Build Coastguard Worker     }
473*8fb009dcSAndroid Build Coastguard Worker   }
474*8fb009dcSAndroid Build Coastguard Worker 
475*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cred->chain.get()); i++) {
476*8fb009dcSAndroid Build Coastguard Worker     CRYPTO_BUFFER *cert_buf = sk_CRYPTO_BUFFER_value(cred->chain.get(), i);
477*8fb009dcSAndroid Build Coastguard Worker     CBB child;
478*8fb009dcSAndroid Build Coastguard Worker     if (!CBB_add_u24_length_prefixed(&certificate_list, &child) ||
479*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_bytes(&child, CRYPTO_BUFFER_data(cert_buf),
480*8fb009dcSAndroid Build Coastguard Worker                        CRYPTO_BUFFER_len(cert_buf)) ||
481*8fb009dcSAndroid Build Coastguard Worker         !CBB_add_u16(&certificate_list, 0 /* no extensions */)) {
482*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
483*8fb009dcSAndroid Build Coastguard Worker       return false;
484*8fb009dcSAndroid Build Coastguard Worker     }
485*8fb009dcSAndroid Build Coastguard Worker   }
486*8fb009dcSAndroid Build Coastguard Worker 
487*8fb009dcSAndroid Build Coastguard Worker   if (!hs->cert_compression_negotiated) {
488*8fb009dcSAndroid Build Coastguard Worker     return ssl_add_message_cbb(ssl, cbb.get());
489*8fb009dcSAndroid Build Coastguard Worker   }
490*8fb009dcSAndroid Build Coastguard Worker 
491*8fb009dcSAndroid Build Coastguard Worker   Array<uint8_t> msg;
492*8fb009dcSAndroid Build Coastguard Worker   if (!CBBFinishArray(cbb.get(), &msg)) {
493*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
494*8fb009dcSAndroid Build Coastguard Worker     return false;
495*8fb009dcSAndroid Build Coastguard Worker   }
496*8fb009dcSAndroid Build Coastguard Worker 
497*8fb009dcSAndroid Build Coastguard Worker   const CertCompressionAlg *alg = nullptr;
498*8fb009dcSAndroid Build Coastguard Worker   for (const auto &candidate : ssl->ctx->cert_compression_algs) {
499*8fb009dcSAndroid Build Coastguard Worker     if (candidate.alg_id == hs->cert_compression_alg_id) {
500*8fb009dcSAndroid Build Coastguard Worker       alg = &candidate;
501*8fb009dcSAndroid Build Coastguard Worker       break;
502*8fb009dcSAndroid Build Coastguard Worker     }
503*8fb009dcSAndroid Build Coastguard Worker   }
504*8fb009dcSAndroid Build Coastguard Worker 
505*8fb009dcSAndroid Build Coastguard Worker   if (alg == nullptr || alg->compress == nullptr) {
506*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
507*8fb009dcSAndroid Build Coastguard Worker     return false;
508*8fb009dcSAndroid Build Coastguard Worker   }
509*8fb009dcSAndroid Build Coastguard Worker 
510*8fb009dcSAndroid Build Coastguard Worker   CBB compressed;
511*8fb009dcSAndroid Build Coastguard Worker   body = &body_storage;
512*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->init_message(ssl, cbb.get(), body,
513*8fb009dcSAndroid Build Coastguard Worker                                  SSL3_MT_COMPRESSED_CERTIFICATE) ||
514*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(body, hs->cert_compression_alg_id) ||
515*8fb009dcSAndroid Build Coastguard Worker       msg.size() > (1u << 24) - 1 ||  //
516*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u24(body, static_cast<uint32_t>(msg.size())) ||
517*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u24_length_prefixed(body, &compressed)) {
518*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
519*8fb009dcSAndroid Build Coastguard Worker     return false;
520*8fb009dcSAndroid Build Coastguard Worker   }
521*8fb009dcSAndroid Build Coastguard Worker 
522*8fb009dcSAndroid Build Coastguard Worker   SSL_HANDSHAKE_HINTS *const hints = hs->hints.get();
523*8fb009dcSAndroid Build Coastguard Worker   if (hints && !hs->hints_requested &&
524*8fb009dcSAndroid Build Coastguard Worker       hints->cert_compression_alg_id == hs->cert_compression_alg_id &&
525*8fb009dcSAndroid Build Coastguard Worker       hints->cert_compression_input == MakeConstSpan(msg) &&
526*8fb009dcSAndroid Build Coastguard Worker       !hints->cert_compression_output.empty()) {
527*8fb009dcSAndroid Build Coastguard Worker     if (!CBB_add_bytes(&compressed, hints->cert_compression_output.data(),
528*8fb009dcSAndroid Build Coastguard Worker                        hints->cert_compression_output.size())) {
529*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
530*8fb009dcSAndroid Build Coastguard Worker       return false;
531*8fb009dcSAndroid Build Coastguard Worker     }
532*8fb009dcSAndroid Build Coastguard Worker   } else {
533*8fb009dcSAndroid Build Coastguard Worker     if (!alg->compress(ssl, &compressed, msg.data(), msg.size())) {
534*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
535*8fb009dcSAndroid Build Coastguard Worker       return false;
536*8fb009dcSAndroid Build Coastguard Worker     }
537*8fb009dcSAndroid Build Coastguard Worker     if (hints && hs->hints_requested) {
538*8fb009dcSAndroid Build Coastguard Worker       hints->cert_compression_alg_id = hs->cert_compression_alg_id;
539*8fb009dcSAndroid Build Coastguard Worker       if (!hints->cert_compression_input.CopyFrom(msg) ||
540*8fb009dcSAndroid Build Coastguard Worker           !hints->cert_compression_output.CopyFrom(
541*8fb009dcSAndroid Build Coastguard Worker               MakeConstSpan(CBB_data(&compressed), CBB_len(&compressed)))) {
542*8fb009dcSAndroid Build Coastguard Worker         return false;
543*8fb009dcSAndroid Build Coastguard Worker       }
544*8fb009dcSAndroid Build Coastguard Worker     }
545*8fb009dcSAndroid Build Coastguard Worker   }
546*8fb009dcSAndroid Build Coastguard Worker 
547*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_add_message_cbb(ssl, cbb.get())) {
548*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
549*8fb009dcSAndroid Build Coastguard Worker     return false;
550*8fb009dcSAndroid Build Coastguard Worker   }
551*8fb009dcSAndroid Build Coastguard Worker 
552*8fb009dcSAndroid Build Coastguard Worker   return true;
553*8fb009dcSAndroid Build Coastguard Worker }
554*8fb009dcSAndroid Build Coastguard Worker 
tls13_add_certificate_verify(SSL_HANDSHAKE * hs)555*8fb009dcSAndroid Build Coastguard Worker enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) {
556*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
557*8fb009dcSAndroid Build Coastguard Worker   assert(hs->signature_algorithm != 0);
558*8fb009dcSAndroid Build Coastguard Worker   ScopedCBB cbb;
559*8fb009dcSAndroid Build Coastguard Worker   CBB body;
560*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->init_message(ssl, cbb.get(), &body,
561*8fb009dcSAndroid Build Coastguard Worker                                  SSL3_MT_CERTIFICATE_VERIFY) ||
562*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(&body, hs->signature_algorithm)) {
563*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
564*8fb009dcSAndroid Build Coastguard Worker     return ssl_private_key_failure;
565*8fb009dcSAndroid Build Coastguard Worker   }
566*8fb009dcSAndroid Build Coastguard Worker 
567*8fb009dcSAndroid Build Coastguard Worker   CBB child;
568*8fb009dcSAndroid Build Coastguard Worker   const size_t max_sig_len = EVP_PKEY_size(hs->credential->pubkey.get());
569*8fb009dcSAndroid Build Coastguard Worker   uint8_t *sig;
570*8fb009dcSAndroid Build Coastguard Worker   size_t sig_len;
571*8fb009dcSAndroid Build Coastguard Worker   if (!CBB_add_u16_length_prefixed(&body, &child) ||
572*8fb009dcSAndroid Build Coastguard Worker       !CBB_reserve(&child, &sig, max_sig_len)) {
573*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
574*8fb009dcSAndroid Build Coastguard Worker     return ssl_private_key_failure;
575*8fb009dcSAndroid Build Coastguard Worker   }
576*8fb009dcSAndroid Build Coastguard Worker 
577*8fb009dcSAndroid Build Coastguard Worker   Array<uint8_t> msg;
578*8fb009dcSAndroid Build Coastguard Worker   if (!tls13_get_cert_verify_signature_input(
579*8fb009dcSAndroid Build Coastguard Worker           hs, &msg,
580*8fb009dcSAndroid Build Coastguard Worker           ssl->server ? ssl_cert_verify_server : ssl_cert_verify_client)) {
581*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
582*8fb009dcSAndroid Build Coastguard Worker     return ssl_private_key_failure;
583*8fb009dcSAndroid Build Coastguard Worker   }
584*8fb009dcSAndroid Build Coastguard Worker 
585*8fb009dcSAndroid Build Coastguard Worker   enum ssl_private_key_result_t sign_result = ssl_private_key_sign(
586*8fb009dcSAndroid Build Coastguard Worker       hs, sig, &sig_len, max_sig_len, hs->signature_algorithm, msg);
587*8fb009dcSAndroid Build Coastguard Worker   if (sign_result != ssl_private_key_success) {
588*8fb009dcSAndroid Build Coastguard Worker     return sign_result;
589*8fb009dcSAndroid Build Coastguard Worker   }
590*8fb009dcSAndroid Build Coastguard Worker 
591*8fb009dcSAndroid Build Coastguard Worker   if (!CBB_did_write(&child, sig_len) ||
592*8fb009dcSAndroid Build Coastguard Worker       !ssl_add_message_cbb(ssl, cbb.get())) {
593*8fb009dcSAndroid Build Coastguard Worker     return ssl_private_key_failure;
594*8fb009dcSAndroid Build Coastguard Worker   }
595*8fb009dcSAndroid Build Coastguard Worker 
596*8fb009dcSAndroid Build Coastguard Worker   return ssl_private_key_success;
597*8fb009dcSAndroid Build Coastguard Worker }
598*8fb009dcSAndroid Build Coastguard Worker 
tls13_add_finished(SSL_HANDSHAKE * hs)599*8fb009dcSAndroid Build Coastguard Worker bool tls13_add_finished(SSL_HANDSHAKE *hs) {
600*8fb009dcSAndroid Build Coastguard Worker   SSL *const ssl = hs->ssl;
601*8fb009dcSAndroid Build Coastguard Worker   size_t verify_data_len;
602*8fb009dcSAndroid Build Coastguard Worker   uint8_t verify_data[EVP_MAX_MD_SIZE];
603*8fb009dcSAndroid Build Coastguard Worker 
604*8fb009dcSAndroid Build Coastguard Worker   if (!tls13_finished_mac(hs, verify_data, &verify_data_len, ssl->server)) {
605*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
606*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
607*8fb009dcSAndroid Build Coastguard Worker     return false;
608*8fb009dcSAndroid Build Coastguard Worker   }
609*8fb009dcSAndroid Build Coastguard Worker 
610*8fb009dcSAndroid Build Coastguard Worker   ScopedCBB cbb;
611*8fb009dcSAndroid Build Coastguard Worker   CBB body;
612*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_FINISHED) ||
613*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_bytes(&body, verify_data, verify_data_len) ||
614*8fb009dcSAndroid Build Coastguard Worker       !ssl_add_message_cbb(ssl, cbb.get())) {
615*8fb009dcSAndroid Build Coastguard Worker     return false;
616*8fb009dcSAndroid Build Coastguard Worker   }
617*8fb009dcSAndroid Build Coastguard Worker 
618*8fb009dcSAndroid Build Coastguard Worker   return true;
619*8fb009dcSAndroid Build Coastguard Worker }
620*8fb009dcSAndroid Build Coastguard Worker 
tls13_add_key_update(SSL * ssl,int update_requested)621*8fb009dcSAndroid Build Coastguard Worker bool tls13_add_key_update(SSL *ssl, int update_requested) {
622*8fb009dcSAndroid Build Coastguard Worker   ScopedCBB cbb;
623*8fb009dcSAndroid Build Coastguard Worker   CBB body_cbb;
624*8fb009dcSAndroid Build Coastguard Worker   if (!ssl->method->init_message(ssl, cbb.get(), &body_cbb,
625*8fb009dcSAndroid Build Coastguard Worker                                  SSL3_MT_KEY_UPDATE) ||
626*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u8(&body_cbb, update_requested) ||
627*8fb009dcSAndroid Build Coastguard Worker       !ssl_add_message_cbb(ssl, cbb.get()) ||
628*8fb009dcSAndroid Build Coastguard Worker       !tls13_rotate_traffic_key(ssl, evp_aead_seal)) {
629*8fb009dcSAndroid Build Coastguard Worker     return false;
630*8fb009dcSAndroid Build Coastguard Worker   }
631*8fb009dcSAndroid Build Coastguard Worker 
632*8fb009dcSAndroid Build Coastguard Worker   // Suppress KeyUpdate acknowledgments until this change is written to the
633*8fb009dcSAndroid Build Coastguard Worker   // wire. This prevents us from accumulating write obligations when read and
634*8fb009dcSAndroid Build Coastguard Worker   // write progress at different rates. See RFC 8446, section 4.6.3.
635*8fb009dcSAndroid Build Coastguard Worker   ssl->s3->key_update_pending = true;
636*8fb009dcSAndroid Build Coastguard Worker 
637*8fb009dcSAndroid Build Coastguard Worker   return true;
638*8fb009dcSAndroid Build Coastguard Worker }
639*8fb009dcSAndroid Build Coastguard Worker 
tls13_receive_key_update(SSL * ssl,const SSLMessage & msg)640*8fb009dcSAndroid Build Coastguard Worker static bool tls13_receive_key_update(SSL *ssl, const SSLMessage &msg) {
641*8fb009dcSAndroid Build Coastguard Worker   CBS body = msg.body;
642*8fb009dcSAndroid Build Coastguard Worker   uint8_t key_update_request;
643*8fb009dcSAndroid Build Coastguard Worker   if (!CBS_get_u8(&body, &key_update_request) ||
644*8fb009dcSAndroid Build Coastguard Worker       CBS_len(&body) != 0 ||
645*8fb009dcSAndroid Build Coastguard Worker       (key_update_request != SSL_KEY_UPDATE_NOT_REQUESTED &&
646*8fb009dcSAndroid Build Coastguard Worker        key_update_request != SSL_KEY_UPDATE_REQUESTED)) {
647*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
648*8fb009dcSAndroid Build Coastguard Worker     ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
649*8fb009dcSAndroid Build Coastguard Worker     return false;
650*8fb009dcSAndroid Build Coastguard Worker   }
651*8fb009dcSAndroid Build Coastguard Worker 
652*8fb009dcSAndroid Build Coastguard Worker   if (!tls13_rotate_traffic_key(ssl, evp_aead_open)) {
653*8fb009dcSAndroid Build Coastguard Worker     return false;
654*8fb009dcSAndroid Build Coastguard Worker   }
655*8fb009dcSAndroid Build Coastguard Worker 
656*8fb009dcSAndroid Build Coastguard Worker   // Acknowledge the KeyUpdate
657*8fb009dcSAndroid Build Coastguard Worker   if (key_update_request == SSL_KEY_UPDATE_REQUESTED &&
658*8fb009dcSAndroid Build Coastguard Worker       !ssl->s3->key_update_pending &&
659*8fb009dcSAndroid Build Coastguard Worker       !tls13_add_key_update(ssl, SSL_KEY_UPDATE_NOT_REQUESTED)) {
660*8fb009dcSAndroid Build Coastguard Worker     return false;
661*8fb009dcSAndroid Build Coastguard Worker   }
662*8fb009dcSAndroid Build Coastguard Worker 
663*8fb009dcSAndroid Build Coastguard Worker   return true;
664*8fb009dcSAndroid Build Coastguard Worker }
665*8fb009dcSAndroid Build Coastguard Worker 
tls13_post_handshake(SSL * ssl,const SSLMessage & msg)666*8fb009dcSAndroid Build Coastguard Worker bool tls13_post_handshake(SSL *ssl, const SSLMessage &msg) {
667*8fb009dcSAndroid Build Coastguard Worker   if (msg.type == SSL3_MT_KEY_UPDATE) {
668*8fb009dcSAndroid Build Coastguard Worker     ssl->s3->key_update_count++;
669*8fb009dcSAndroid Build Coastguard Worker     if (ssl->quic_method != nullptr ||
670*8fb009dcSAndroid Build Coastguard Worker         ssl->s3->key_update_count > kMaxKeyUpdates) {
671*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_KEY_UPDATES);
672*8fb009dcSAndroid Build Coastguard Worker       ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
673*8fb009dcSAndroid Build Coastguard Worker       return false;
674*8fb009dcSAndroid Build Coastguard Worker     }
675*8fb009dcSAndroid Build Coastguard Worker 
676*8fb009dcSAndroid Build Coastguard Worker     return tls13_receive_key_update(ssl, msg);
677*8fb009dcSAndroid Build Coastguard Worker   }
678*8fb009dcSAndroid Build Coastguard Worker 
679*8fb009dcSAndroid Build Coastguard Worker   ssl->s3->key_update_count = 0;
680*8fb009dcSAndroid Build Coastguard Worker 
681*8fb009dcSAndroid Build Coastguard Worker   if (msg.type == SSL3_MT_NEW_SESSION_TICKET && !ssl->server) {
682*8fb009dcSAndroid Build Coastguard Worker     return tls13_process_new_session_ticket(ssl, msg);
683*8fb009dcSAndroid Build Coastguard Worker   }
684*8fb009dcSAndroid Build Coastguard Worker 
685*8fb009dcSAndroid Build Coastguard Worker   ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
686*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
687*8fb009dcSAndroid Build Coastguard Worker   return false;
688*8fb009dcSAndroid Build Coastguard Worker }
689*8fb009dcSAndroid Build Coastguard Worker 
690*8fb009dcSAndroid Build Coastguard Worker BSSL_NAMESPACE_END
691