Coverage Report

Created: 2026-10-19 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/ssl/handoff.cc
Line
Count
Source
1
// Copyright 2018 The BoringSSL Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <openssl/ssl.h>
16
17
#include <openssl/bytestring.h>
18
#include <openssl/err.h>
19
20
#include <algorithm>
21
#include <optional>
22
23
#include "../crypto/internal.h"
24
#include "internal.h"
25
26
27
BSSL_NAMESPACE_BEGIN
28
29
static const CBS_ASN1_TAG kFeatureTagALPS = CBS_ASN1_CONTEXT_SPECIFIC | 0;
30
31
// early_data_t represents the state of early data in a more compact way than
32
// the 3 bits used by the implementation.
33
enum early_data_t {
34
  early_data_not_offered = 0,
35
  early_data_accepted = 1,
36
  early_data_rejected_hrr = 2,
37
  early_data_skipped = 3,
38
39
  early_data_max_value = early_data_skipped,
40
};
41
42
// serialize_features adds a description of features supported by this binary to
43
// `out`.  Returns true on success and false on error.
44
0
static bool serialize_features(CBB *out) {
45
0
  CBB ciphers;
46
0
  if (!CBB_add_asn1(out, &ciphers, CBS_ASN1_OCTETSTRING)) {
47
0
    return false;
48
0
  }
49
0
  Span<const SSL_CIPHER> all_ciphers = AllCiphers();
50
0
  for (const SSL_CIPHER &cipher : all_ciphers) {
51
0
    if (!CBB_add_u16(&ciphers, cipher.protocol_id)) {
52
0
      return false;
53
0
    }
54
0
  }
55
0
  CBB groups;
56
0
  if (!CBB_add_asn1(out, &groups, CBS_ASN1_OCTETSTRING)) {
57
0
    return false;
58
0
  }
59
0
  for (const NamedGroup &g : NamedGroups()) {
60
0
    if (!CBB_add_u16(&groups, g.group_id)) {
61
0
      return false;
62
0
    }
63
0
  }
64
  // ALPS is a draft protocol and may change over time. The features structure
65
  // contains a [0] IMPLICIT OCTET STRING OPTIONAL, containing a list of u16
66
  // ALPS versions that the binary supports. For now we name them by codepoint.
67
  // Once ALPS is finalized and past the support horizon, this field can be
68
  // removed.
69
0
  CBB alps;
70
0
  if (!CBB_add_asn1(out, &alps, kFeatureTagALPS) ||
71
0
      !CBB_add_u16(&alps, TLSEXT_TYPE_application_settings_old) ||
72
0
      !CBB_add_u16(&alps, TLSEXT_TYPE_application_settings)) {
73
0
    return false;
74
0
  }
75
0
  return CBB_flush(out);
76
0
}
77
78
// apply_remote_features reads a list of supported features from `in` and
79
// (possibly) reconfigures `ssl` to disallow the negotiation of features whose
80
// support has not been indicated. (This prevents the hints from being generated
81
// based on features that are not supported on the actual server.)
82
0
static bool apply_remote_features(SSLImpl *ssl, CBS *in) {
83
0
  CBS ciphers;
84
0
  if (!CBS_get_asn1(in, &ciphers, CBS_ASN1_OCTETSTRING)) {
85
0
    return false;
86
0
  }
87
0
  bssl::UniquePtr<STACK_OF(SSL_CIPHER)> supported(sk_SSL_CIPHER_new_null());
88
0
  if (!supported) {
89
0
    return false;
90
0
  }
91
0
  while (CBS_len(&ciphers)) {
92
0
    uint16_t id;
93
0
    if (!CBS_get_u16(&ciphers, &id)) {
94
0
      return false;
95
0
    }
96
0
    const SSL_CIPHER *cipher = SSL_get_cipher_by_value(id);
97
0
    if (!cipher) {
98
0
      continue;
99
0
    }
100
0
    if (!sk_SSL_CIPHER_push(supported.get(), cipher)) {
101
0
      return false;
102
0
    }
103
0
  }
104
0
  const STACK_OF(SSL_CIPHER) *configured =
105
0
      ssl->config->cipher_list ? ssl->config->cipher_list->ciphers()
106
0
                               : ssl->ctx->cipher_list->ciphers();
107
0
  bssl::UniquePtr<STACK_OF(SSL_CIPHER)> unsupported(sk_SSL_CIPHER_new_null());
108
0
  if (!unsupported) {
109
0
    return false;
110
0
  }
111
0
  for (const SSL_CIPHER *configured_cipher : configured) {
112
0
    if (sk_SSL_CIPHER_find(supported.get(), nullptr, configured_cipher)) {
113
0
      continue;
114
0
    }
115
0
    if (!sk_SSL_CIPHER_push(unsupported.get(), configured_cipher)) {
116
0
      return false;
117
0
    }
118
0
  }
119
0
  if (sk_SSL_CIPHER_num(unsupported.get()) && !ssl->config->cipher_list) {
120
0
    ssl->config->cipher_list = bssl::MakeUnique<SSLCipherPreferenceList>();
121
0
    if (!ssl->config->cipher_list ||
122
0
        !ssl->config->cipher_list->CopyFrom(*ssl->ctx->cipher_list)) {
123
0
      return false;
124
0
    }
125
0
  }
126
0
  for (const SSL_CIPHER *unsupported_cipher : unsupported.get()) {
127
0
    ssl->config->cipher_list->Remove(unsupported_cipher);
128
0
  }
129
0
  if (sk_SSL_CIPHER_num(SSL_get_ciphers(ssl)) == 0) {
130
0
    return false;
131
0
  }
132
133
0
  CBS groups;
134
0
  if (!CBS_get_asn1(in, &groups, CBS_ASN1_OCTETSTRING)) {
135
0
    return false;
136
0
  }
137
0
  Array<uint16_t> supported_groups;
138
0
  if (!supported_groups.InitForOverwrite(CBS_len(&groups) / 2)) {
139
0
    return false;
140
0
  }
141
0
  size_t idx = 0;
142
0
  while (CBS_len(&groups)) {
143
0
    uint16_t group;
144
0
    if (!CBS_get_u16(&groups, &group)) {
145
0
      return false;
146
0
    }
147
0
    supported_groups[idx++] = group;
148
0
  }
149
0
  Span<const uint16_t> configured_groups =
150
0
      ssl->s3->hs->config->supported_group_list;
151
0
  Span<const uint32_t> configured_groups_flags =
152
0
      ssl->s3->hs->config->supported_group_list_flags;
153
0
  Array<uint16_t> new_configured_groups;
154
  // Temporary scratch space to keep track of consecutive runs of groups of
155
  // equal preference, so they can be relabeled after filtering for groups
156
  // present in the remote features and copying to the new configuration.
157
0
  Array<size_t> new_groups_preference_ranks;
158
0
  Array<uint32_t> new_groups_flags;
159
0
  if (!new_configured_groups.InitForOverwrite(configured_groups.size()) ||
160
0
      !new_groups_preference_ranks.Init(configured_groups.size()) ||
161
0
      !new_groups_flags.Init(configured_groups.size())) {
162
0
    return false;
163
0
  }
164
  // Populate temporary array containing "preference rank" of each group.
165
0
  for (size_t i = 1; i < configured_groups.size(); ++i) {
166
0
    new_groups_preference_ranks[i] = new_groups_preference_ranks[i - 1];
167
0
    if ((configured_groups_flags[i - 1] &
168
0
         SSL_GROUP_FLAG_EQUAL_PREFERENCE_WITH_NEXT) == 0) {
169
0
      ++new_groups_preference_ranks[i];
170
0
    }
171
0
  }
172
0
  idx = 0;
173
0
  std::optional<size_t> last_rank;
174
0
  for (size_t i = 0u; i < configured_groups.size(); ++i) {
175
0
    uint16_t configured_group = configured_groups[i];
176
0
    if (std::find(supported_groups.begin(), supported_groups.end(),
177
0
                  configured_group) == supported_groups.end()) {
178
0
      continue;
179
0
    }
180
0
    new_configured_groups[idx] = configured_group;
181
    // Set the "equal preference with next" flag on the previous group, if
182
    // appropriate.
183
0
    if (last_rank.has_value() && new_groups_preference_ranks[i] == *last_rank) {
184
0
      new_groups_flags[idx - 1] |= SSL_GROUP_FLAG_EQUAL_PREFERENCE_WITH_NEXT;
185
0
    }
186
0
    last_rank = new_groups_preference_ranks[i];
187
0
    ++idx;
188
0
  }
189
0
  if (idx == 0) {
190
0
    return false;
191
0
  }
192
0
  new_configured_groups.Shrink(idx);
193
0
  new_groups_flags.Shrink(idx);
194
0
  ssl->config->supported_group_list = std::move(new_configured_groups);
195
0
  ssl->config->supported_group_list_flags = std::move(new_groups_flags);
196
197
0
  CBS alps;
198
0
  CBS_init(&alps, nullptr, 0);
199
0
  if (!CBS_get_optional_asn1(in, &alps, /*out_present=*/nullptr,
200
0
                             kFeatureTagALPS)) {
201
0
    return false;
202
0
  }
203
0
  bool supports_alps = false;
204
0
  while (CBS_len(&alps) != 0) {
205
0
    uint16_t id;
206
0
    if (!CBS_get_u16(&alps, &id)) {
207
0
      return false;
208
0
    }
209
    // For now, we support two ALPS codepoints, so we need to extract both
210
    // codepoints, and then filter what the handshaker might try to send.
211
0
    if ((id == TLSEXT_TYPE_application_settings &&
212
0
         ssl->config->alps_use_new_codepoint) ||
213
0
        (id == TLSEXT_TYPE_application_settings_old &&
214
0
         !ssl->config->alps_use_new_codepoint)) {
215
0
      supports_alps = true;
216
0
      break;
217
0
    }
218
0
  }
219
0
  if (!supports_alps) {
220
0
    ssl->config->alps_configs.clear();
221
0
  }
222
223
0
  return true;
224
0
}
225
226
BSSL_NAMESPACE_END
227
228
using namespace bssl;
229
230
0
int SSL_serialize_capabilities(const SSL *ssl, CBB *out) {
231
0
  CBB seq;
232
0
  if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) ||
233
0
      !serialize_features(&seq) ||  //
234
0
      !CBB_flush(out)) {
235
0
    return 0;
236
0
  }
237
238
0
  return 1;
239
0
}
240
241
int SSL_request_handshake_hints(SSL *ssl, const uint8_t *client_hello,
242
                                size_t client_hello_len,
243
                                const uint8_t *capabilities,
244
0
                                size_t capabilities_len) {
245
0
  auto *ssl_impl = FromOpaque(ssl);
246
0
  if (SSL_is_dtls(ssl_impl) || ssl_impl->s3->hs == nullptr) {
247
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
248
0
    return 0;
249
0
  }
250
251
0
  CBS cbs, seq;
252
0
  CBS_init(&cbs, capabilities, capabilities_len);
253
0
  UniquePtr<SSL_HANDSHAKE_HINTS> pending_hints =
254
0
      MakeUnique<SSL_HANDSHAKE_HINTS>();
255
0
  if (pending_hints == nullptr ||
256
0
      !CBS_get_asn1(&cbs, &seq, CBS_ASN1_SEQUENCE) ||
257
0
      !apply_remote_features(ssl_impl, &seq)) {
258
0
    return 0;
259
0
  }
260
261
0
  SSL3_STATE *const s3 = ssl_impl->s3;
262
0
  s3->v2_hello_done = true;
263
0
  s3->has_message = true;
264
265
0
  Array<uint8_t> client_hello_msg;
266
0
  ScopedCBB client_hello_cbb;
267
0
  CBB client_hello_body;
268
0
  if (!ssl_impl->method->init_message(ssl_impl, client_hello_cbb.get(),
269
0
                                      &client_hello_body,
270
0
                                      SSL3_MT_CLIENT_HELLO) ||
271
0
      !CBB_add_bytes(&client_hello_body, client_hello, client_hello_len) ||
272
0
      !ssl_impl->method->finish_message(ssl_impl, client_hello_cbb.get(),
273
0
                                        &client_hello_msg)) {
274
0
    return 0;
275
0
  }
276
277
0
  s3->hs_buf.reset(BUF_MEM_new());
278
0
  if (!s3->hs_buf || !BUF_MEM_append(s3->hs_buf.get(), client_hello_msg.data(),
279
0
                                     client_hello_msg.size())) {
280
0
    return 0;
281
0
  }
282
283
0
  s3->hs->pending_hints = std::move(pending_hints);
284
0
  return 1;
285
0
}
286
287
// `SSL_HANDSHAKE_HINTS` is serialized as the following ASN.1 structure. We use
288
// implicit tagging to make it a little more compact.
289
//
290
// HandshakeHints ::= SEQUENCE {
291
//     serverRandomTLS13       [0] IMPLICIT OCTET STRING OPTIONAL,
292
//     keyShareHint            [1] IMPLICIT KeyShareHint OPTIONAL,
293
//     signatureHint           [2] IMPLICIT SignatureHint OPTIONAL,
294
//     -- At most one of decryptedPSKHint or ignorePSKHint may be present. It
295
//     -- corresponds to the first entry in pre_shared_keys. TLS 1.2 session
296
//     -- tickets use a separate hint, to ensure the caller does not apply the
297
//     -- hint to the wrong field.
298
//     decryptedPSKHint        [3] IMPLICIT OCTET STRING OPTIONAL,
299
//     ignorePSKHint           [4] IMPLICIT NULL OPTIONAL,
300
//     -- Due to a historical typo, compressCertificateHint's tag is primitive
301
//     -- instead of constructed.
302
//     compressCertificateHint [5 PRIMITIVE] IMPLICIT CompressCertificateHint
303
//                                 OPTIONAL,
304
//     -- TLS 1.2 and 1.3 use different server random hints because one contains
305
//     -- a timestamp while the other doesn't. If the hint was generated
306
//     -- assuming TLS 1.3 but we actually negotiate TLS 1.2, mixing the two
307
//     -- will break this.
308
//     serverRandomTLS12       [6] IMPLICIT OCTET STRING OPTIONAL,
309
//     -- Due to a historical typo, ecdheHint tag has universal class instead of
310
//     -- context-specific.
311
//     ecdheHint               [UNIVERSAL 7] IMPLICIT ECDHEHint OPTIONAL
312
//     -- At most one of decryptedTicketHint or ignoreTicketHint may be present.
313
//     -- renewTicketHint requires decryptedTicketHint.
314
//     decryptedTicketHint     [8] IMPLICIT OCTET STRING OPTIONAL,
315
//     renewTicketHint         [9] IMPLICIT NULL OPTIONAL,
316
//     ignoreTicketHint       [10] IMPLICIT NULL OPTIONAL,
317
//     -- Unlike a usual ASN.1 structure, trailing data is ignored.
318
// }
319
//
320
// KeyShareHint ::= SEQUENCE {
321
//     groupId                 INTEGER,
322
//     ciphertext              OCTET STRING,
323
//     secret                  OCTET STRING,
324
// }
325
//
326
// SignatureHint ::= SEQUENCE {
327
//     algorithm               INTEGER,
328
//     input                   OCTET STRING,
329
//     subjectPublicKeyInfo    OCTET STRING,
330
//     signature               OCTET STRING,
331
// }
332
//
333
// CompressCertificateHint ::= SEQUENCE {
334
//     algorithm               INTEGER,
335
//     input                   OCTET STRING,
336
//     compressed              OCTET STRING,
337
// }
338
//
339
// ECDHEHint ::= SEQUENCE {
340
//     groupId                 INTEGER,
341
//     publicKey               OCTET STRING,
342
//     privateKey              OCTET STRING,
343
// }
344
345
// HandshakeHints tags.
346
static const CBS_ASN1_TAG kServerRandomTLS13Tag = CBS_ASN1_CONTEXT_SPECIFIC | 0;
347
static const CBS_ASN1_TAG kKeyShareHintTag =
348
    CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;
349
static const CBS_ASN1_TAG kSignatureHintTag =
350
    CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2;
351
static const CBS_ASN1_TAG kDecryptedPSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 3;
352
static const CBS_ASN1_TAG kIgnorePSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 4;
353
static const CBS_ASN1_TAG kCompressCertificateTag =
354
    CBS_ASN1_CONTEXT_SPECIFIC | 5;
355
static const CBS_ASN1_TAG kServerRandomTLS12Tag = CBS_ASN1_CONTEXT_SPECIFIC | 6;
356
static const CBS_ASN1_TAG kECDHEHintTag = CBS_ASN1_CONSTRUCTED | 7;
357
static const CBS_ASN1_TAG kDecryptedTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 8;
358
static const CBS_ASN1_TAG kRenewTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 9;
359
static const CBS_ASN1_TAG kIgnoreTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 10;
360
361
0
int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) {
362
0
  const auto *ssl_impl = FromOpaque(ssl);
363
0
  const SSL_HANDSHAKE *hs = ssl_impl->s3->hs.get();
364
0
  if (!ssl_impl->server || hs == nullptr || hs->pending_hints == nullptr) {
365
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
366
0
    return 0;
367
0
  }
368
369
0
  const SSL_HANDSHAKE_HINTS *const hints = hs->pending_hints.get();
370
0
  CBB seq, child;
371
0
  if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE)) {
372
0
    return 0;
373
0
  }
374
375
0
  if (!hints->server_random_tls13.empty()) {
376
0
    if (!CBB_add_asn1_element(&seq, kServerRandomTLS13Tag,
377
0
                              hints->server_random_tls13.data(),
378
0
                              hints->server_random_tls13.size())) {
379
0
      return 0;
380
0
    }
381
0
  }
382
383
0
  if (hints->key_share_group_id != 0 && !hints->key_share_ciphertext.empty() &&
384
0
      !hints->key_share_secret.empty()) {
385
0
    if (!CBB_add_asn1(&seq, &child, kKeyShareHintTag) ||
386
0
        !CBB_add_asn1_uint64(&child, hints->key_share_group_id) ||
387
0
        !CBB_add_asn1_octet_string(&child, hints->key_share_ciphertext.data(),
388
0
                                   hints->key_share_ciphertext.size()) ||
389
0
        !CBB_add_asn1_octet_string(&child, hints->key_share_secret.data(),
390
0
                                   hints->key_share_secret.size())) {
391
0
      return 0;
392
0
    }
393
0
  }
394
395
0
  if (hints->signature_algorithm != 0 && !hints->signature_input.empty() &&
396
0
      !hints->signature.empty()) {
397
0
    if (!CBB_add_asn1(&seq, &child, kSignatureHintTag) ||
398
0
        !CBB_add_asn1_uint64(&child, hints->signature_algorithm) ||
399
0
        !CBB_add_asn1_octet_string(&child, hints->signature_input.data(),
400
0
                                   hints->signature_input.size()) ||
401
0
        !CBB_add_asn1_octet_string(&child, hints->signature_spki.data(),
402
0
                                   hints->signature_spki.size()) ||
403
0
        !CBB_add_asn1_octet_string(&child, hints->signature.data(),
404
0
                                   hints->signature.size())) {
405
0
      return 0;
406
0
    }
407
0
  }
408
409
0
  if (!hints->decrypted_psk.empty()) {
410
0
    if (!CBB_add_asn1_element(&seq, kDecryptedPSKTag,
411
0
                              hints->decrypted_psk.data(),
412
0
                              hints->decrypted_psk.size())) {
413
0
      return 0;
414
0
    }
415
0
  }
416
417
0
  if (hints->ignore_psk &&  //
418
0
      !CBB_add_asn1(&seq, &child, kIgnorePSKTag)) {
419
0
    return 0;
420
0
  }
421
422
0
  if (hints->cert_compression_alg_id != 0 &&
423
0
      !hints->cert_compression_input.empty() &&
424
0
      !hints->cert_compression_output.empty()) {
425
0
    if (!CBB_add_asn1(&seq, &child, kCompressCertificateTag) ||
426
0
        !CBB_add_asn1_uint64(&child, hints->cert_compression_alg_id) ||
427
0
        !CBB_add_asn1_octet_string(&child, hints->cert_compression_input.data(),
428
0
                                   hints->cert_compression_input.size()) ||
429
0
        !CBB_add_asn1_octet_string(&child,
430
0
                                   hints->cert_compression_output.data(),
431
0
                                   hints->cert_compression_output.size())) {
432
0
      return 0;
433
0
    }
434
0
  }
435
436
0
  if (!hints->server_random_tls12.empty()) {
437
0
    if (!CBB_add_asn1_element(&seq, kServerRandomTLS12Tag,
438
0
                              hints->server_random_tls12.data(),
439
0
                              hints->server_random_tls12.size())) {
440
0
      return 0;
441
0
    }
442
0
  }
443
444
0
  if (hints->ecdhe_group_id != 0 && !hints->ecdhe_public_key.empty() &&
445
0
      !hints->ecdhe_private_key.empty()) {
446
0
    if (!CBB_add_asn1(&seq, &child, kECDHEHintTag) ||
447
0
        !CBB_add_asn1_uint64(&child, hints->ecdhe_group_id) ||
448
0
        !CBB_add_asn1_octet_string(&child, hints->ecdhe_public_key.data(),
449
0
                                   hints->ecdhe_public_key.size()) ||
450
0
        !CBB_add_asn1_octet_string(&child, hints->ecdhe_private_key.data(),
451
0
                                   hints->ecdhe_private_key.size())) {
452
0
      return 0;
453
0
    }
454
0
  }
455
456
457
0
  if (!hints->decrypted_ticket.empty()) {
458
0
    if (!CBB_add_asn1_element(&seq, kDecryptedTicketTag,
459
0
                              hints->decrypted_ticket.data(),
460
0
                              hints->decrypted_ticket.size())) {
461
0
      return 0;
462
0
    }
463
0
  }
464
465
0
  if (hints->renew_ticket &&  //
466
0
      !CBB_add_asn1(&seq, &child, kRenewTicketTag)) {
467
0
    return 0;
468
0
  }
469
470
0
  if (hints->ignore_ticket &&  //
471
0
      !CBB_add_asn1(&seq, &child, kIgnoreTicketTag)) {
472
0
    return 0;
473
0
  }
474
475
0
  return CBB_flush(out);
476
0
}
477
478
static bool get_optional_implicit_null(CBS *cbs, bool *out_present,
479
153k
                                       CBS_ASN1_TAG tag) {
480
153k
  CBS value;
481
153k
  int present;
482
153k
  if (!CBS_get_optional_asn1(cbs, &value, &present, tag) ||
483
151k
      (present && CBS_len(&value) != 0)) {
484
3.16k
    return false;
485
3.16k
  }
486
150k
  *out_present = present;
487
150k
  return true;
488
153k
}
489
490
78.5k
int SSL_set_handshake_hints(SSL *ssl, const uint8_t *hints, size_t hints_len) {
491
78.5k
  auto *ssl_impl = FromOpaque(ssl);
492
78.5k
  if (SSL_is_dtls(ssl_impl) || ssl_impl->s3->hs == nullptr) {
493
1.10k
    OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
494
1.10k
    return 0;
495
1.10k
  }
496
497
77.4k
  UniquePtr<SSL_HANDSHAKE_HINTS> hints_obj = MakeUnique<SSL_HANDSHAKE_HINTS>();
498
77.4k
  if (hints_obj == nullptr) {
499
0
    return 0;
500
0
  }
501
502
77.4k
  CBS cbs, seq, server_random_tls13, key_share, signature_hint, psk,
503
77.4k
      cert_compression, server_random_tls12, ecdhe, ticket;
504
77.4k
  int has_server_random_tls13, has_key_share, has_signature_hint, has_psk,
505
77.4k
      has_cert_compression, has_server_random_tls12, has_ecdhe, has_ticket;
506
77.4k
  CBS_init(&cbs, hints, hints_len);
507
77.4k
  if (!CBS_get_asn1(&cbs, &seq, CBS_ASN1_SEQUENCE) ||
508
58.3k
      !CBS_get_optional_asn1(&seq, &server_random_tls13,
509
58.3k
                             &has_server_random_tls13, kServerRandomTLS13Tag) ||
510
57.5k
      !CBS_get_optional_asn1(&seq, &key_share, &has_key_share,
511
57.5k
                             kKeyShareHintTag) ||
512
56.6k
      !CBS_get_optional_asn1(&seq, &signature_hint, &has_signature_hint,
513
56.6k
                             kSignatureHintTag) ||
514
55.6k
      !CBS_get_optional_asn1(&seq, &psk, &has_psk, kDecryptedPSKTag) ||
515
54.7k
      !get_optional_implicit_null(&seq, &hints_obj->ignore_psk,
516
54.7k
                                  kIgnorePSKTag) ||
517
53.4k
      !CBS_get_optional_asn1(&seq, &cert_compression, &has_cert_compression,
518
53.4k
                             kCompressCertificateTag) ||
519
52.5k
      !CBS_get_optional_asn1(&seq, &server_random_tls12,
520
52.5k
                             &has_server_random_tls12, kServerRandomTLS12Tag) ||
521
51.7k
      !CBS_get_optional_asn1(&seq, &ecdhe, &has_ecdhe, kECDHEHintTag) ||
522
50.8k
      !CBS_get_optional_asn1(&seq, &ticket, &has_ticket, kDecryptedTicketTag) ||
523
49.9k
      !get_optional_implicit_null(&seq, &hints_obj->renew_ticket,
524
49.9k
                                  kRenewTicketTag) ||
525
49.1k
      !get_optional_implicit_null(&seq, &hints_obj->ignore_ticket,
526
49.1k
                                  kIgnoreTicketTag)) {
527
29.3k
    OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
528
29.3k
    return 0;
529
29.3k
  }
530
531
48.1k
  if (has_server_random_tls13 &&
532
1.83k
      !hints_obj->server_random_tls13.CopyFrom(server_random_tls13)) {
533
0
    return 0;
534
0
  }
535
536
48.1k
  if (has_key_share) {
537
7.10k
    uint64_t group_id;
538
7.10k
    CBS ciphertext, secret;
539
7.10k
    if (!CBS_get_asn1_uint64(&key_share, &group_id) ||  //
540
5.20k
        group_id == 0 || group_id > 0xffff ||
541
3.29k
        !CBS_get_asn1(&key_share, &ciphertext, CBS_ASN1_OCTETSTRING) ||
542
2.22k
        !hints_obj->key_share_ciphertext.CopyFrom(ciphertext) ||
543
2.22k
        !CBS_get_asn1(&key_share, &secret, CBS_ASN1_OCTETSTRING) ||
544
5.99k
        !hints_obj->key_share_secret.CopyFrom(secret)) {
545
5.99k
      OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
546
5.99k
      return 0;
547
5.99k
    }
548
1.11k
    hints_obj->key_share_group_id = static_cast<uint16_t>(group_id);
549
1.11k
  }
550
551
42.1k
  if (has_signature_hint) {
552
9.15k
    uint64_t sig_alg;
553
9.15k
    CBS input, spki, signature;
554
9.15k
    if (!CBS_get_asn1_uint64(&signature_hint, &sig_alg) ||  //
555
7.00k
        sig_alg == 0 || sig_alg > 0xffff ||
556
4.58k
        !CBS_get_asn1(&signature_hint, &input, CBS_ASN1_OCTETSTRING) ||
557
3.40k
        !hints_obj->signature_input.CopyFrom(input) ||
558
3.40k
        !CBS_get_asn1(&signature_hint, &spki, CBS_ASN1_OCTETSTRING) ||
559
2.39k
        !hints_obj->signature_spki.CopyFrom(spki) ||
560
2.39k
        !CBS_get_asn1(&signature_hint, &signature, CBS_ASN1_OCTETSTRING) ||
561
7.69k
        !hints_obj->signature.CopyFrom(signature)) {
562
7.69k
      OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
563
7.69k
      return 0;
564
7.69k
    }
565
1.46k
    hints_obj->signature_algorithm = static_cast<uint16_t>(sig_alg);
566
1.46k
  }
567
568
34.4k
  if (has_psk && !hints_obj->decrypted_psk.CopyFrom(psk)) {
569
0
    return 0;
570
0
  }
571
34.4k
  if (has_psk && hints_obj->ignore_psk) {
572
1.40k
    OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
573
1.40k
    return 0;
574
1.40k
  }
575
576
33.0k
  if (has_cert_compression) {
577
11.6k
    uint64_t alg;
578
11.6k
    CBS input, output;
579
11.6k
    if (!CBS_get_asn1_uint64(&cert_compression, &alg) ||  //
580
8.28k
        alg == 0 || alg > 0xffff ||
581
5.86k
        !CBS_get_asn1(&cert_compression, &input, CBS_ASN1_OCTETSTRING) ||
582
4.53k
        !hints_obj->cert_compression_input.CopyFrom(input) ||
583
4.53k
        !CBS_get_asn1(&cert_compression, &output, CBS_ASN1_OCTETSTRING) ||
584
8.65k
        !hints_obj->cert_compression_output.CopyFrom(output)) {
585
8.65k
      OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
586
8.65k
      return 0;
587
8.65k
    }
588
2.98k
    hints_obj->cert_compression_alg_id = static_cast<uint16_t>(alg);
589
2.98k
  }
590
591
24.3k
  if (has_server_random_tls12 &&
592
2.19k
      !hints_obj->server_random_tls12.CopyFrom(server_random_tls12)) {
593
0
    return 0;
594
0
  }
595
596
24.3k
  if (has_ecdhe) {
597
8.92k
    uint64_t group_id;
598
8.92k
    CBS public_key, private_key;
599
8.92k
    if (!CBS_get_asn1_uint64(&ecdhe, &group_id) ||  //
600
5.91k
        group_id == 0 || group_id > 0xffff ||
601
4.01k
        !CBS_get_asn1(&ecdhe, &public_key, CBS_ASN1_OCTETSTRING) ||
602
2.97k
        !hints_obj->ecdhe_public_key.CopyFrom(public_key) ||
603
2.97k
        !CBS_get_asn1(&ecdhe, &private_key, CBS_ASN1_OCTETSTRING) ||
604
6.82k
        !hints_obj->ecdhe_private_key.CopyFrom(private_key)) {
605
6.82k
      OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
606
6.82k
      return 0;
607
6.82k
    }
608
2.10k
    hints_obj->ecdhe_group_id = static_cast<uint16_t>(group_id);
609
2.10k
  }
610
611
17.5k
  if (has_ticket && !hints_obj->decrypted_ticket.CopyFrom(ticket)) {
612
0
    return 0;
613
0
  }
614
17.5k
  if (has_ticket && hints_obj->ignore_ticket) {
615
979
    OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
616
979
    return 0;
617
979
  }
618
16.5k
  if (!has_ticket && hints_obj->renew_ticket) {
619
850
    OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
620
850
    return 0;
621
850
  }
622
623
15.7k
  ssl_impl->s3->hs->provided_hints = std::move(hints_obj);
624
15.7k
  return 1;
625
16.5k
}