Coverage Report

Created: 2025-06-11 06:40

/src/boringssl/ssl/handoff.cc
Line
Count
Source (jump to first uncovered line)
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 "../crypto/internal.h"
21
#include "internal.h"
22
23
24
BSSL_NAMESPACE_BEGIN
25
26
constexpr int kHandoffVersion = 0;
27
constexpr int kHandbackVersion = 0;
28
29
static const CBS_ASN1_TAG kHandoffTagALPS = 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, static_cast<uint16_t>(cipher.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 handoff 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, kHandoffTagALPS) ||
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
bool SSL_serialize_handoff(const SSL *ssl, CBB *out,
79
0
                           SSL_CLIENT_HELLO *out_hello) {
80
0
  const SSL3_STATE *const s3 = ssl->s3;
81
0
  if (!ssl->server ||       //
82
0
      s3->hs == nullptr ||  //
83
0
      s3->rwstate != SSL_ERROR_HANDOFF) {
84
0
    return false;
85
0
  }
86
87
0
  CBB seq;
88
0
  SSLMessage msg;
89
0
  Span<const uint8_t> transcript = s3->hs->transcript.buffer();
90
91
0
  if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) ||
92
0
      !CBB_add_asn1_uint64(&seq, kHandoffVersion) ||
93
0
      !CBB_add_asn1_octet_string(&seq, transcript.data(), transcript.size()) ||
94
0
      !CBB_add_asn1_octet_string(&seq,
95
0
                                 reinterpret_cast<uint8_t *>(s3->hs_buf->data),
96
0
                                 s3->hs_buf->length) ||
97
0
      !serialize_features(&seq) || !CBB_flush(out) ||
98
0
      !ssl->method->get_message(ssl, &msg) ||
99
0
      !SSL_parse_client_hello(ssl, out_hello, CBS_data(&msg.body),
100
0
                              CBS_len(&msg.body))) {
101
0
    return false;
102
0
  }
103
104
0
  return true;
105
0
}
106
107
0
bool SSL_decline_handoff(SSL *ssl) {
108
0
  const SSL3_STATE *const s3 = ssl->s3;
109
0
  if (!ssl->server || s3->hs == nullptr || s3->rwstate != SSL_ERROR_HANDOFF) {
110
0
    return false;
111
0
  }
112
113
0
  s3->hs->config->handoff = false;
114
0
  return true;
115
0
}
116
117
// apply_remote_features reads a list of supported features from |in| and
118
// (possibly) reconfigures |ssl| to disallow the negotation of features whose
119
// support has not been indicated.  (This prevents the the handshake from
120
// committing to features that are not supported on the handoff/handback side.)
121
0
static bool apply_remote_features(SSL *ssl, CBS *in) {
122
0
  CBS ciphers;
123
0
  if (!CBS_get_asn1(in, &ciphers, CBS_ASN1_OCTETSTRING)) {
124
0
    return false;
125
0
  }
126
0
  bssl::UniquePtr<STACK_OF(SSL_CIPHER)> supported(sk_SSL_CIPHER_new_null());
127
0
  if (!supported) {
128
0
    return false;
129
0
  }
130
0
  while (CBS_len(&ciphers)) {
131
0
    uint16_t id;
132
0
    if (!CBS_get_u16(&ciphers, &id)) {
133
0
      return false;
134
0
    }
135
0
    const SSL_CIPHER *cipher = SSL_get_cipher_by_value(id);
136
0
    if (!cipher) {
137
0
      continue;
138
0
    }
139
0
    if (!sk_SSL_CIPHER_push(supported.get(), cipher)) {
140
0
      return false;
141
0
    }
142
0
  }
143
0
  STACK_OF(SSL_CIPHER) *configured =
144
0
      ssl->config->cipher_list ? ssl->config->cipher_list->ciphers.get()
145
0
                               : ssl->ctx->cipher_list->ciphers.get();
146
0
  bssl::UniquePtr<STACK_OF(SSL_CIPHER)> unsupported(sk_SSL_CIPHER_new_null());
147
0
  if (!unsupported) {
148
0
    return false;
149
0
  }
150
0
  for (const SSL_CIPHER *configured_cipher : configured) {
151
0
    if (sk_SSL_CIPHER_find(supported.get(), nullptr, configured_cipher)) {
152
0
      continue;
153
0
    }
154
0
    if (!sk_SSL_CIPHER_push(unsupported.get(), configured_cipher)) {
155
0
      return false;
156
0
    }
157
0
  }
158
0
  if (sk_SSL_CIPHER_num(unsupported.get()) && !ssl->config->cipher_list) {
159
0
    ssl->config->cipher_list = bssl::MakeUnique<SSLCipherPreferenceList>();
160
0
    if (!ssl->config->cipher_list ||
161
0
        !ssl->config->cipher_list->Init(*ssl->ctx->cipher_list)) {
162
0
      return false;
163
0
    }
164
0
  }
165
0
  for (const SSL_CIPHER *unsupported_cipher : unsupported.get()) {
166
0
    ssl->config->cipher_list->Remove(unsupported_cipher);
167
0
  }
168
0
  if (sk_SSL_CIPHER_num(SSL_get_ciphers(ssl)) == 0) {
169
0
    return false;
170
0
  }
171
172
0
  CBS groups;
173
0
  if (!CBS_get_asn1(in, &groups, CBS_ASN1_OCTETSTRING)) {
174
0
    return false;
175
0
  }
176
0
  Array<uint16_t> supported_groups;
177
0
  if (!supported_groups.InitForOverwrite(CBS_len(&groups) / 2)) {
178
0
    return false;
179
0
  }
180
0
  size_t idx = 0;
181
0
  while (CBS_len(&groups)) {
182
0
    uint16_t group;
183
0
    if (!CBS_get_u16(&groups, &group)) {
184
0
      return false;
185
0
    }
186
0
    supported_groups[idx++] = group;
187
0
  }
188
0
  Span<const uint16_t> configured_groups =
189
0
      tls1_get_grouplist(ssl->s3->hs.get());
190
0
  Array<uint16_t> new_configured_groups;
191
0
  if (!new_configured_groups.InitForOverwrite(configured_groups.size())) {
192
0
    return false;
193
0
  }
194
0
  idx = 0;
195
0
  for (uint16_t configured_group : configured_groups) {
196
0
    bool ok = false;
197
0
    for (uint16_t supported_group : supported_groups) {
198
0
      if (supported_group == configured_group) {
199
0
        ok = true;
200
0
        break;
201
0
      }
202
0
    }
203
0
    if (ok) {
204
0
      new_configured_groups[idx++] = configured_group;
205
0
    }
206
0
  }
207
0
  if (idx == 0) {
208
0
    return false;
209
0
  }
210
0
  new_configured_groups.Shrink(idx);
211
0
  ssl->config->supported_group_list = std::move(new_configured_groups);
212
213
0
  CBS alps;
214
0
  CBS_init(&alps, nullptr, 0);
215
0
  if (!CBS_get_optional_asn1(in, &alps, /*out_present=*/nullptr,
216
0
                             kHandoffTagALPS)) {
217
0
    return false;
218
0
  }
219
0
  bool supports_alps = false;
220
0
  while (CBS_len(&alps) != 0) {
221
0
    uint16_t id;
222
0
    if (!CBS_get_u16(&alps, &id)) {
223
0
      return false;
224
0
    }
225
    // For now, we support two ALPS codepoints, so we need to extract both
226
    // codepoints, and then filter what the handshaker might try to send.
227
0
    if ((id == TLSEXT_TYPE_application_settings &&
228
0
         ssl->config->alps_use_new_codepoint) ||
229
0
        (id == TLSEXT_TYPE_application_settings_old &&
230
0
         !ssl->config->alps_use_new_codepoint)) {
231
0
      supports_alps = true;
232
0
      break;
233
0
    }
234
0
  }
235
0
  if (!supports_alps) {
236
0
    ssl->config->alps_configs.clear();
237
0
  }
238
239
0
  return true;
240
0
}
241
242
// uses_disallowed_feature returns true iff |ssl| enables a feature that
243
// disqualifies it for split handshakes.
244
1
static bool uses_disallowed_feature(const SSL *ssl) {
245
1
  return ssl->method->is_dtls || !ssl->config->cert->credentials.empty() ||
246
1
         ssl->config->quic_transport_params.size() > 0 || ssl->ctx->ech_keys;
247
1
}
248
249
1
bool SSL_apply_handoff(SSL *ssl, Span<const uint8_t> handoff) {
250
1
  if (uses_disallowed_feature(ssl)) {
251
1
    return false;
252
1
  }
253
254
0
  CBS seq, handoff_cbs(handoff);
255
0
  uint64_t handoff_version;
256
0
  if (!CBS_get_asn1(&handoff_cbs, &seq, CBS_ASN1_SEQUENCE) ||
257
0
      !CBS_get_asn1_uint64(&seq, &handoff_version) ||
258
0
      handoff_version != kHandoffVersion) {
259
0
    return false;
260
0
  }
261
262
0
  CBS transcript, hs_buf;
263
0
  if (!CBS_get_asn1(&seq, &transcript, CBS_ASN1_OCTETSTRING) ||
264
0
      !CBS_get_asn1(&seq, &hs_buf, CBS_ASN1_OCTETSTRING) ||
265
0
      !apply_remote_features(ssl, &seq)) {
266
0
    return false;
267
0
  }
268
269
0
  SSL_set_accept_state(ssl);
270
271
0
  SSL3_STATE *const s3 = ssl->s3;
272
0
  s3->v2_hello_done = true;
273
0
  s3->has_message = true;
274
275
0
  s3->hs_buf.reset(BUF_MEM_new());
276
0
  if (!s3->hs_buf ||
277
0
      !BUF_MEM_append(s3->hs_buf.get(), CBS_data(&hs_buf), CBS_len(&hs_buf))) {
278
0
    return false;
279
0
  }
280
281
0
  if (CBS_len(&transcript) != 0) {
282
0
    s3->hs->transcript.Update(transcript);
283
0
    s3->is_v2_hello = true;
284
0
  }
285
0
  s3->hs->handback = true;
286
287
0
  return true;
288
0
}
289
290
0
bool SSL_serialize_handback(const SSL *ssl, CBB *out) {
291
0
  if (!ssl->server || uses_disallowed_feature(ssl)) {
292
0
    return false;
293
0
  }
294
0
  const SSL3_STATE *const s3 = ssl->s3;
295
0
  SSL_HANDSHAKE *const hs = s3->hs.get();
296
0
  handback_t type;
297
0
  switch (hs->state) {
298
0
    case state12_read_change_cipher_spec:
299
0
      type = handback_after_session_resumption;
300
0
      break;
301
0
    case state12_read_client_certificate:
302
0
      type = handback_after_ecdhe;
303
0
      break;
304
0
    case state12_finish_server_handshake:
305
0
      type = handback_after_handshake;
306
0
      break;
307
0
    case state12_tls13:
308
0
      if (hs->tls13_state != state13_send_half_rtt_ticket) {
309
0
        return false;
310
0
      }
311
0
      type = handback_tls13;
312
0
      break;
313
0
    default:
314
0
      return false;
315
0
  }
316
317
0
  size_t hostname_len = 0;
318
0
  if (s3->hostname) {
319
0
    hostname_len = strlen(s3->hostname.get());
320
0
  }
321
322
0
  Span<const uint8_t> transcript;
323
0
  if (type != handback_after_handshake) {
324
0
    transcript = s3->hs->transcript.buffer();
325
0
  }
326
0
  size_t write_iv_len = 0;
327
0
  const uint8_t *write_iv = nullptr;
328
0
  if ((type == handback_after_session_resumption ||
329
0
       type == handback_after_handshake) &&
330
0
      ssl->s3->version == TLS1_VERSION &&
331
0
      SSL_CIPHER_is_block_cipher(s3->aead_write_ctx->cipher()) &&
332
0
      !s3->aead_write_ctx->GetIV(&write_iv, &write_iv_len)) {
333
0
    return false;
334
0
  }
335
0
  size_t read_iv_len = 0;
336
0
  const uint8_t *read_iv = nullptr;
337
0
  if (type == handback_after_handshake &&                         //
338
0
      ssl->s3->version == TLS1_VERSION &&                         //
339
0
      SSL_CIPHER_is_block_cipher(s3->aead_read_ctx->cipher()) &&  //
340
0
      !s3->aead_read_ctx->GetIV(&read_iv, &read_iv_len)) {
341
0
    return false;
342
0
  }
343
344
  // TODO(mab): make sure everything is serialized.
345
0
  CBB seq, key_share;
346
0
  const SSL_SESSION *session;
347
0
  if (type == handback_tls13) {
348
0
    session = hs->new_session.get();
349
0
  } else {
350
0
    session = s3->session_reused ? ssl->session.get() : hs->new_session.get();
351
0
  }
352
0
  uint8_t read_sequence[8], write_sequence[8];
353
0
  CRYPTO_store_u64_be(read_sequence, s3->read_sequence);
354
0
  CRYPTO_store_u64_be(write_sequence, s3->write_sequence);
355
0
  static const uint8_t kUnusedChannelID[64] = {0};
356
0
  if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) ||
357
0
      !CBB_add_asn1_uint64(&seq, kHandbackVersion) ||
358
0
      !CBB_add_asn1_uint64(&seq, type) ||
359
0
      !CBB_add_asn1_octet_string(&seq, read_sequence, sizeof(read_sequence)) ||
360
0
      !CBB_add_asn1_octet_string(&seq, write_sequence,
361
0
                                 sizeof(write_sequence)) ||
362
0
      !CBB_add_asn1_octet_string(&seq, s3->server_random,
363
0
                                 sizeof(s3->server_random)) ||
364
0
      !CBB_add_asn1_octet_string(&seq, s3->client_random,
365
0
                                 sizeof(s3->client_random)) ||
366
0
      !CBB_add_asn1_octet_string(&seq, read_iv, read_iv_len) ||
367
0
      !CBB_add_asn1_octet_string(&seq, write_iv, write_iv_len) ||
368
0
      !CBB_add_asn1_bool(&seq, s3->session_reused) ||
369
0
      !CBB_add_asn1_bool(&seq, hs->channel_id_negotiated) ||
370
0
      !ssl_session_serialize(session, &seq) ||
371
0
      !CBB_add_asn1_octet_string(&seq, s3->next_proto_negotiated.data(),
372
0
                                 s3->next_proto_negotiated.size()) ||
373
0
      !CBB_add_asn1_octet_string(&seq, s3->alpn_selected.data(),
374
0
                                 s3->alpn_selected.size()) ||
375
0
      !CBB_add_asn1_octet_string(
376
0
          &seq, reinterpret_cast<uint8_t *>(s3->hostname.get()),
377
0
          hostname_len) ||
378
0
      !CBB_add_asn1_octet_string(&seq, kUnusedChannelID,
379
0
                                 sizeof(kUnusedChannelID)) ||
380
      // These two fields were historically |token_binding_negotiated| and
381
      // |negotiated_token_binding_param|.
382
0
      !CBB_add_asn1_bool(&seq, 0) ||  //
383
0
      !CBB_add_asn1_uint64(&seq, 0) ||
384
0
      !CBB_add_asn1_bool(&seq, s3->hs->next_proto_neg_seen) ||
385
0
      !CBB_add_asn1_bool(&seq, s3->hs->cert_request) ||
386
0
      !CBB_add_asn1_bool(&seq, s3->hs->extended_master_secret) ||
387
0
      !CBB_add_asn1_bool(&seq, s3->hs->ticket_expected) ||
388
0
      !CBB_add_asn1_uint64(&seq, SSL_CIPHER_get_id(s3->hs->new_cipher)) ||
389
0
      !CBB_add_asn1_octet_string(&seq, transcript.data(), transcript.size()) ||
390
0
      !CBB_add_asn1(&seq, &key_share, CBS_ASN1_SEQUENCE)) {
391
0
    return false;
392
0
  }
393
0
  if (type == handback_after_ecdhe) {
394
0
    CBB private_key;
395
0
    if (!CBB_add_asn1_uint64(&key_share, s3->hs->key_shares[0]->GroupID()) ||
396
0
        !CBB_add_asn1(&key_share, &private_key, CBS_ASN1_OCTETSTRING) ||
397
0
        !s3->hs->key_shares[0]->SerializePrivateKey(&private_key) ||
398
0
        !CBB_flush(&key_share)) {
399
0
      return false;
400
0
    }
401
0
  }
402
0
  if (type == handback_tls13) {
403
0
    early_data_t early_data;
404
    // Check early data invariants.
405
0
    if (ssl->enable_early_data ==
406
0
        (s3->early_data_reason == ssl_early_data_disabled)) {
407
0
      return false;
408
0
    }
409
0
    if (hs->early_data_offered) {
410
0
      if (s3->early_data_accepted && !s3->skip_early_data) {
411
0
        early_data = early_data_accepted;
412
0
      } else if (!s3->early_data_accepted && !s3->skip_early_data) {
413
0
        early_data = early_data_rejected_hrr;
414
0
      } else if (!s3->early_data_accepted && s3->skip_early_data) {
415
0
        early_data = early_data_skipped;
416
0
      } else {
417
0
        return false;
418
0
      }
419
0
    } else if (!s3->early_data_accepted && !s3->skip_early_data) {
420
0
      early_data = early_data_not_offered;
421
0
    } else {
422
0
      return false;
423
0
    }
424
0
    if (!CBB_add_asn1_octet_string(&seq, hs->client_traffic_secret_0.data(),
425
0
                                   hs->client_traffic_secret_0.size()) ||
426
0
        !CBB_add_asn1_octet_string(&seq, hs->server_traffic_secret_0.data(),
427
0
                                   hs->server_traffic_secret_0.size()) ||
428
0
        !CBB_add_asn1_octet_string(&seq, hs->client_handshake_secret.data(),
429
0
                                   hs->client_handshake_secret.size()) ||
430
0
        !CBB_add_asn1_octet_string(&seq, hs->server_handshake_secret.data(),
431
0
                                   hs->server_handshake_secret.size()) ||
432
0
        !CBB_add_asn1_octet_string(&seq, hs->secret.data(),
433
0
                                   hs->secret.size()) ||
434
0
        !CBB_add_asn1_octet_string(&seq, s3->exporter_secret.data(),
435
0
                                   s3->exporter_secret.size()) ||
436
0
        !CBB_add_asn1_bool(&seq, s3->used_hello_retry_request) ||
437
0
        !CBB_add_asn1_bool(&seq, hs->accept_psk_mode) ||
438
0
        !CBB_add_asn1_int64(&seq, s3->ticket_age_skew) ||
439
0
        !CBB_add_asn1_uint64(&seq, s3->early_data_reason) ||
440
0
        !CBB_add_asn1_uint64(&seq, early_data)) {
441
0
      return false;
442
0
    }
443
0
    if (early_data == early_data_accepted &&
444
0
        !CBB_add_asn1_octet_string(&seq, hs->early_traffic_secret.data(),
445
0
                                   hs->early_traffic_secret.size())) {
446
0
      return false;
447
0
    }
448
449
0
    if (session->has_application_settings) {
450
0
      uint16_t alps_codepoint = TLSEXT_TYPE_application_settings_old;
451
0
      if (hs->config->alps_use_new_codepoint) {
452
0
        alps_codepoint = TLSEXT_TYPE_application_settings;
453
0
      }
454
0
      if (!CBB_add_asn1_uint64(&seq, alps_codepoint)) {
455
0
        return false;
456
0
      }
457
0
    }
458
0
  }
459
0
  return CBB_flush(out);
460
0
}
461
462
0
static bool CopyExact(Span<uint8_t> out, const CBS *in) {
463
0
  if (CBS_len(in) != out.size()) {
464
0
    return false;
465
0
  }
466
0
  OPENSSL_memcpy(out.data(), CBS_data(in), out.size());
467
0
  return true;
468
0
}
469
470
0
bool SSL_apply_handback(SSL *ssl, Span<const uint8_t> handback) {
471
0
  if (ssl->do_handshake != nullptr ||  //
472
0
      ssl->method->is_dtls) {
473
0
    return false;
474
0
  }
475
476
0
  SSL3_STATE *const s3 = ssl->s3;
477
0
  uint64_t handback_version, unused_token_binding_param, cipher, type_u64,
478
0
      alps_codepoint;
479
480
0
  CBS seq, read_seq, write_seq, server_rand, client_rand, read_iv, write_iv,
481
0
      next_proto, alpn, hostname, unused_channel_id, transcript, key_share;
482
0
  int session_reused, channel_id_negotiated, cert_request,
483
0
      extended_master_secret, ticket_expected, unused_token_binding,
484
0
      next_proto_neg_seen;
485
0
  SSL_SESSION *session = nullptr;
486
487
0
  CBS handback_cbs(handback);
488
0
  if (!CBS_get_asn1(&handback_cbs, &seq, CBS_ASN1_SEQUENCE) ||  //
489
0
      !CBS_get_asn1_uint64(&seq, &handback_version) ||          //
490
0
      handback_version != kHandbackVersion ||                   //
491
0
      !CBS_get_asn1_uint64(&seq, &type_u64) ||                  //
492
0
      type_u64 > handback_max_value) {
493
0
    return false;
494
0
  }
495
496
0
  handback_t type = static_cast<handback_t>(type_u64);
497
0
  if (!CBS_get_asn1(&seq, &read_seq, CBS_ASN1_OCTETSTRING) ||
498
0
      CBS_len(&read_seq) != sizeof(s3->read_sequence) ||
499
0
      !CBS_get_asn1(&seq, &write_seq, CBS_ASN1_OCTETSTRING) ||
500
0
      CBS_len(&write_seq) != sizeof(s3->write_sequence) ||
501
0
      !CBS_get_asn1(&seq, &server_rand, CBS_ASN1_OCTETSTRING) ||
502
0
      CBS_len(&server_rand) != sizeof(s3->server_random) ||
503
0
      !CBS_copy_bytes(&server_rand, s3->server_random,
504
0
                      sizeof(s3->server_random)) ||
505
0
      !CBS_get_asn1(&seq, &client_rand, CBS_ASN1_OCTETSTRING) ||
506
0
      CBS_len(&client_rand) != sizeof(s3->client_random) ||
507
0
      !CBS_copy_bytes(&client_rand, s3->client_random,
508
0
                      sizeof(s3->client_random)) ||
509
0
      !CBS_get_asn1(&seq, &read_iv, CBS_ASN1_OCTETSTRING) ||
510
0
      !CBS_get_asn1(&seq, &write_iv, CBS_ASN1_OCTETSTRING) ||
511
0
      !CBS_get_asn1_bool(&seq, &session_reused) ||
512
0
      !CBS_get_asn1_bool(&seq, &channel_id_negotiated)) {
513
0
    return false;
514
0
  }
515
516
0
  s3->hs = ssl_handshake_new(ssl);
517
0
  if (!s3->hs) {
518
0
    return false;
519
0
  }
520
0
  SSL_HANDSHAKE *const hs = s3->hs.get();
521
0
  if (!session_reused || type == handback_tls13) {
522
0
    hs->new_session =
523
0
        SSL_SESSION_parse(&seq, ssl->ctx->x509_method, ssl->ctx->pool);
524
0
    session = hs->new_session.get();
525
0
  } else {
526
0
    ssl->session =
527
0
        SSL_SESSION_parse(&seq, ssl->ctx->x509_method, ssl->ctx->pool);
528
0
    session = ssl->session.get();
529
0
  }
530
531
0
  if (!session || !CBS_get_asn1(&seq, &next_proto, CBS_ASN1_OCTETSTRING) ||
532
0
      !CBS_get_asn1(&seq, &alpn, CBS_ASN1_OCTETSTRING) ||
533
0
      !CBS_get_asn1(&seq, &hostname, CBS_ASN1_OCTETSTRING) ||
534
0
      !CBS_get_asn1(&seq, &unused_channel_id, CBS_ASN1_OCTETSTRING) ||
535
0
      !CBS_get_asn1_bool(&seq, &unused_token_binding) ||
536
0
      !CBS_get_asn1_uint64(&seq, &unused_token_binding_param) ||
537
0
      !CBS_get_asn1_bool(&seq, &next_proto_neg_seen) ||
538
0
      !CBS_get_asn1_bool(&seq, &cert_request) ||
539
0
      !CBS_get_asn1_bool(&seq, &extended_master_secret) ||
540
0
      !CBS_get_asn1_bool(&seq, &ticket_expected) ||
541
0
      !CBS_get_asn1_uint64(&seq, &cipher)) {
542
0
    return false;
543
0
  }
544
0
  if ((hs->new_cipher =
545
0
           SSL_get_cipher_by_value(static_cast<uint16_t>(cipher))) == nullptr) {
546
0
    return false;
547
0
  }
548
0
  if (!CBS_get_asn1(&seq, &transcript, CBS_ASN1_OCTETSTRING) ||
549
0
      !CBS_get_asn1(&seq, &key_share, CBS_ASN1_SEQUENCE)) {
550
0
    return false;
551
0
  }
552
0
  CBS client_handshake_secret, server_handshake_secret, client_traffic_secret_0,
553
0
      server_traffic_secret_0, secret, exporter_secret, early_traffic_secret;
554
0
  if (type == handback_tls13) {
555
0
    int used_hello_retry_request, accept_psk_mode;
556
0
    uint64_t early_data, early_data_reason;
557
0
    int64_t ticket_age_skew;
558
0
    if (!CBS_get_asn1(&seq, &client_traffic_secret_0, CBS_ASN1_OCTETSTRING) ||
559
0
        !CBS_get_asn1(&seq, &server_traffic_secret_0, CBS_ASN1_OCTETSTRING) ||
560
0
        !CBS_get_asn1(&seq, &client_handshake_secret, CBS_ASN1_OCTETSTRING) ||
561
0
        !CBS_get_asn1(&seq, &server_handshake_secret, CBS_ASN1_OCTETSTRING) ||
562
0
        !CBS_get_asn1(&seq, &secret, CBS_ASN1_OCTETSTRING) ||
563
0
        !CBS_get_asn1(&seq, &exporter_secret, CBS_ASN1_OCTETSTRING) ||
564
0
        !CBS_get_asn1_bool(&seq, &used_hello_retry_request) ||
565
0
        !CBS_get_asn1_bool(&seq, &accept_psk_mode) ||
566
0
        !CBS_get_asn1_int64(&seq, &ticket_age_skew) ||
567
0
        !CBS_get_asn1_uint64(&seq, &early_data_reason) ||
568
0
        early_data_reason > ssl_early_data_reason_max_value ||
569
0
        !CBS_get_asn1_uint64(&seq, &early_data) ||
570
0
        early_data > early_data_max_value) {
571
0
      return false;
572
0
    }
573
0
    early_data_t early_data_type = static_cast<early_data_t>(early_data);
574
0
    if (early_data_type == early_data_accepted &&
575
0
        !CBS_get_asn1(&seq, &early_traffic_secret, CBS_ASN1_OCTETSTRING)) {
576
0
      return false;
577
0
    }
578
579
0
    if (session->has_application_settings) {
580
      // Making it optional to keep compatibility with older handshakers.
581
      // Older handshakers won't send the field.
582
0
      if (CBS_len(&seq) == 0) {
583
0
        hs->config->alps_use_new_codepoint = false;
584
0
      } else {
585
0
        if (!CBS_get_asn1_uint64(&seq, &alps_codepoint)) {
586
0
          return false;
587
0
        }
588
589
0
        if (alps_codepoint == TLSEXT_TYPE_application_settings) {
590
0
          hs->config->alps_use_new_codepoint = true;
591
0
        } else if (alps_codepoint == TLSEXT_TYPE_application_settings_old) {
592
0
          hs->config->alps_use_new_codepoint = false;
593
0
        } else {
594
0
          OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPS_CODEPOINT);
595
0
          return false;
596
0
        }
597
0
      }
598
0
    }
599
600
0
    if (ticket_age_skew > std::numeric_limits<int32_t>::max() ||
601
0
        ticket_age_skew < std::numeric_limits<int32_t>::min()) {
602
0
      return false;
603
0
    }
604
0
    s3->ticket_age_skew = static_cast<int32_t>(ticket_age_skew);
605
0
    s3->used_hello_retry_request = used_hello_retry_request;
606
0
    hs->accept_psk_mode = accept_psk_mode;
607
608
0
    s3->early_data_reason =
609
0
        static_cast<ssl_early_data_reason_t>(early_data_reason);
610
0
    ssl->enable_early_data = s3->early_data_reason != ssl_early_data_disabled;
611
0
    s3->skip_early_data = false;
612
0
    s3->early_data_accepted = false;
613
0
    hs->early_data_offered = false;
614
0
    switch (early_data_type) {
615
0
      case early_data_not_offered:
616
0
        break;
617
0
      case early_data_accepted:
618
0
        s3->early_data_accepted = true;
619
0
        hs->early_data_offered = true;
620
0
        hs->can_early_write = true;
621
0
        hs->can_early_read = true;
622
0
        hs->in_early_data = true;
623
0
        break;
624
0
      case early_data_rejected_hrr:
625
0
        hs->early_data_offered = true;
626
0
        break;
627
0
      case early_data_skipped:
628
0
        s3->skip_early_data = true;
629
0
        hs->early_data_offered = true;
630
0
        break;
631
0
      default:
632
0
        return false;
633
0
    }
634
0
  } else {
635
0
    s3->early_data_reason = ssl_early_data_protocol_version;
636
0
  }
637
638
0
  ssl->s3->version = session->ssl_version;
639
0
  if (!ssl_method_supports_version(ssl->method, ssl->s3->version) ||
640
0
      session->cipher != hs->new_cipher ||
641
0
      ssl_protocol_version(ssl) < SSL_CIPHER_get_min_version(session->cipher) ||
642
0
      SSL_CIPHER_get_max_version(session->cipher) < ssl_protocol_version(ssl)) {
643
0
    return false;
644
0
  }
645
0
  ssl->do_handshake = ssl_server_handshake;
646
0
  ssl->server = true;
647
0
  switch (type) {
648
0
    case handback_after_session_resumption:
649
0
      hs->state = state12_read_change_cipher_spec;
650
0
      if (!session_reused) {
651
0
        return false;
652
0
      }
653
0
      break;
654
0
    case handback_after_ecdhe:
655
0
      hs->state = state12_read_client_certificate;
656
0
      if (session_reused) {
657
0
        return false;
658
0
      }
659
0
      break;
660
0
    case handback_after_handshake:
661
0
      hs->state = state12_finish_server_handshake;
662
0
      break;
663
0
    case handback_tls13:
664
0
      hs->state = state12_tls13;
665
0
      hs->tls13_state = state13_send_half_rtt_ticket;
666
0
      break;
667
0
    default:
668
0
      return false;
669
0
  }
670
0
  s3->session_reused = session_reused;
671
0
  hs->channel_id_negotiated = channel_id_negotiated;
672
0
  if (!s3->next_proto_negotiated.CopyFrom(next_proto) ||
673
0
      !s3->alpn_selected.CopyFrom(alpn)) {
674
0
    return false;
675
0
  }
676
677
0
  const size_t hostname_len = CBS_len(&hostname);
678
0
  if (hostname_len == 0) {
679
0
    s3->hostname.reset();
680
0
  } else {
681
0
    char *hostname_str = nullptr;
682
0
    if (!CBS_strdup(&hostname, &hostname_str)) {
683
0
      return false;
684
0
    }
685
0
    s3->hostname.reset(hostname_str);
686
0
  }
687
688
0
  hs->next_proto_neg_seen = next_proto_neg_seen;
689
0
  hs->wait = ssl_hs_flush;
690
0
  hs->extended_master_secret = extended_master_secret;
691
0
  hs->ticket_expected = ticket_expected;
692
0
  hs->cert_request = cert_request;
693
694
0
  if (type != handback_after_handshake &&
695
0
      (!hs->transcript.Init() ||
696
0
       !hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) ||
697
0
       !hs->transcript.Update(transcript))) {
698
0
    return false;
699
0
  }
700
0
  if (type == handback_tls13) {
701
0
    if (!hs->client_traffic_secret_0.TryCopyFrom(client_traffic_secret_0) ||
702
0
        !hs->server_traffic_secret_0.TryCopyFrom(server_traffic_secret_0) ||
703
0
        !hs->client_handshake_secret.TryCopyFrom(client_handshake_secret) ||
704
0
        !hs->server_handshake_secret.TryCopyFrom(server_handshake_secret) ||
705
0
        !hs->secret.TryCopyFrom(secret) ||
706
0
        !s3->exporter_secret.TryCopyFrom(exporter_secret)) {
707
0
      return false;
708
0
    }
709
710
0
    if (s3->early_data_accepted &&
711
0
        !hs->early_traffic_secret.TryCopyFrom(early_traffic_secret)) {
712
0
      return false;
713
0
    }
714
0
  }
715
0
  Array<uint8_t> key_block;
716
0
  switch (type) {
717
0
    case handback_after_session_resumption:
718
      // The write keys are installed after server Finished, but the client
719
      // keys must wait for ChangeCipherSpec.
720
0
      if (!tls1_configure_aead(ssl, evp_aead_seal, &key_block, session,
721
0
                               write_iv)) {
722
0
        return false;
723
0
      }
724
0
      break;
725
0
    case handback_after_ecdhe:
726
      // The premaster secret is not yet computed, so install no keys.
727
0
      break;
728
0
    case handback_after_handshake:
729
      // The handshake is complete, so both keys are installed.
730
0
      if (!tls1_configure_aead(ssl, evp_aead_seal, &key_block, session,
731
0
                               write_iv) ||
732
0
          !tls1_configure_aead(ssl, evp_aead_open, &key_block, session,
733
0
                               read_iv)) {
734
0
        return false;
735
0
      }
736
0
      break;
737
0
    case handback_tls13:
738
      // After server Finished, the application write keys are installed, but
739
      // none of the read keys. The read keys are installed in the state machine
740
      // immediately after processing handback.
741
0
      if (!tls13_set_traffic_key(ssl, ssl_encryption_application, evp_aead_seal,
742
0
                                 hs->new_session.get(),
743
0
                                 hs->server_traffic_secret_0)) {
744
0
        return false;
745
0
      }
746
0
      break;
747
0
  }
748
0
  uint8_t read_sequence[8], write_sequence[8];
749
0
  if (!CopyExact(read_sequence, &read_seq) ||
750
0
      !CopyExact(write_sequence, &write_seq)) {
751
0
    return false;
752
0
  }
753
0
  s3->read_sequence = CRYPTO_load_u64_be(read_sequence);
754
0
  s3->write_sequence = CRYPTO_load_u64_be(write_sequence);
755
0
  if (type == handback_after_ecdhe) {
756
0
    uint64_t group_id;
757
0
    CBS private_key;
758
0
    if (!CBS_get_asn1_uint64(&key_share, &group_id) ||  //
759
0
        group_id > 0xffff ||
760
0
        !CBS_get_asn1(&key_share, &private_key, CBS_ASN1_OCTETSTRING)) {
761
0
      return false;
762
0
    }
763
0
    hs->key_shares[0] = SSLKeyShare::Create(group_id);
764
0
    if (!hs->key_shares[0] ||
765
0
        !hs->key_shares[0]->DeserializePrivateKey(&private_key)) {
766
0
      return false;
767
0
    }
768
0
  }
769
0
  return true;  // Trailing data allowed for extensibility.
770
0
}
771
772
BSSL_NAMESPACE_END
773
774
using namespace bssl;
775
776
0
int SSL_serialize_capabilities(const SSL *ssl, CBB *out) {
777
0
  CBB seq;
778
0
  if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) ||
779
0
      !serialize_features(&seq) ||  //
780
0
      !CBB_flush(out)) {
781
0
    return 0;
782
0
  }
783
784
0
  return 1;
785
0
}
786
787
int SSL_request_handshake_hints(SSL *ssl, const uint8_t *client_hello,
788
                                size_t client_hello_len,
789
                                const uint8_t *capabilities,
790
0
                                size_t capabilities_len) {
791
0
  if (SSL_is_dtls(ssl)) {
792
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
793
0
    return 0;
794
0
  }
795
796
0
  CBS cbs, seq;
797
0
  CBS_init(&cbs, capabilities, capabilities_len);
798
0
  UniquePtr<SSL_HANDSHAKE_HINTS> hints = MakeUnique<SSL_HANDSHAKE_HINTS>();
799
0
  if (hints == nullptr ||                              //
800
0
      !CBS_get_asn1(&cbs, &seq, CBS_ASN1_SEQUENCE) ||  //
801
0
      !apply_remote_features(ssl, &seq)) {
802
0
    return 0;
803
0
  }
804
805
0
  SSL3_STATE *const s3 = ssl->s3;
806
0
  s3->v2_hello_done = true;
807
0
  s3->has_message = true;
808
809
0
  Array<uint8_t> client_hello_msg;
810
0
  ScopedCBB client_hello_cbb;
811
0
  CBB client_hello_body;
812
0
  if (!ssl->method->init_message(ssl, client_hello_cbb.get(),
813
0
                                 &client_hello_body, SSL3_MT_CLIENT_HELLO) ||
814
0
      !CBB_add_bytes(&client_hello_body, client_hello, client_hello_len) ||
815
0
      !ssl->method->finish_message(ssl, client_hello_cbb.get(),
816
0
                                   &client_hello_msg)) {
817
0
    return 0;
818
0
  }
819
820
0
  s3->hs_buf.reset(BUF_MEM_new());
821
0
  if (!s3->hs_buf || !BUF_MEM_append(s3->hs_buf.get(), client_hello_msg.data(),
822
0
                                     client_hello_msg.size())) {
823
0
    return 0;
824
0
  }
825
826
0
  s3->hs->hints_requested = true;
827
0
  s3->hs->hints = std::move(hints);
828
0
  return 1;
829
0
}
830
831
// |SSL_HANDSHAKE_HINTS| is serialized as the following ASN.1 structure. We use
832
// implicit tagging to make it a little more compact.
833
//
834
// HandshakeHints ::= SEQUENCE {
835
//     serverRandomTLS13       [0] IMPLICIT OCTET STRING OPTIONAL,
836
//     keyShareHint            [1] IMPLICIT KeyShareHint OPTIONAL,
837
//     signatureHint           [2] IMPLICIT SignatureHint OPTIONAL,
838
//     -- At most one of decryptedPSKHint or ignorePSKHint may be present. It
839
//     -- corresponds to the first entry in pre_shared_keys. TLS 1.2 session
840
//     -- tickets use a separate hint, to ensure the caller does not apply the
841
//     -- hint to the wrong field.
842
//     decryptedPSKHint        [3] IMPLICIT OCTET STRING OPTIONAL,
843
//     ignorePSKHint           [4] IMPLICIT NULL OPTIONAL,
844
//     compressCertificateHint [5] IMPLICIT CompressCertificateHint OPTIONAL,
845
//     -- TLS 1.2 and 1.3 use different server random hints because one contains
846
//     -- a timestamp while the other doesn't. If the hint was generated
847
//     -- assuming TLS 1.3 but we actually negotiate TLS 1.2, mixing the two
848
//     -- will break this.
849
//     serverRandomTLS12       [6] IMPLICIT OCTET STRING OPTIONAL,
850
//     ecdheHint               [7] IMPLICIT ECDHEHint OPTIONAL
851
//     -- At most one of decryptedTicketHint or ignoreTicketHint may be present.
852
//     -- renewTicketHint requires decryptedTicketHint.
853
//     decryptedTicketHint     [8] IMPLICIT OCTET STRING OPTIONAL,
854
//     renewTicketHint         [9] IMPLICIT NULL OPTIONAL,
855
//     ignoreTicketHint       [10] IMPLICIT NULL OPTIONAL,
856
// }
857
//
858
// KeyShareHint ::= SEQUENCE {
859
//     groupId                 INTEGER,
860
//     ciphertext              OCTET STRING,
861
//     secret                  OCTET STRING,
862
// }
863
//
864
// SignatureHint ::= SEQUENCE {
865
//     algorithm               INTEGER,
866
//     input                   OCTET STRING,
867
//     subjectPublicKeyInfo    OCTET STRING,
868
//     signature               OCTET STRING,
869
// }
870
//
871
// CompressCertificateHint ::= SEQUENCE {
872
//     algorithm               INTEGER,
873
//     input                   OCTET STRING,
874
//     compressed              OCTET STRING,
875
// }
876
//
877
// ECDHEHint ::= SEQUENCE {
878
//     groupId                 INTEGER,
879
//     publicKey               OCTET STRING,
880
//     privateKey              OCTET STRING,
881
// }
882
883
// HandshakeHints tags.
884
static const CBS_ASN1_TAG kServerRandomTLS13Tag = CBS_ASN1_CONTEXT_SPECIFIC | 0;
885
static const CBS_ASN1_TAG kKeyShareHintTag =
886
    CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;
887
static const CBS_ASN1_TAG kSignatureHintTag =
888
    CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2;
889
static const CBS_ASN1_TAG kDecryptedPSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 3;
890
static const CBS_ASN1_TAG kIgnorePSKTag = CBS_ASN1_CONTEXT_SPECIFIC | 4;
891
static const CBS_ASN1_TAG kCompressCertificateTag =
892
    CBS_ASN1_CONTEXT_SPECIFIC | 5;
893
static const CBS_ASN1_TAG kServerRandomTLS12Tag = CBS_ASN1_CONTEXT_SPECIFIC | 6;
894
static const CBS_ASN1_TAG kECDHEHintTag = CBS_ASN1_CONSTRUCTED | 7;
895
static const CBS_ASN1_TAG kDecryptedTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 8;
896
static const CBS_ASN1_TAG kRenewTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 9;
897
static const CBS_ASN1_TAG kIgnoreTicketTag = CBS_ASN1_CONTEXT_SPECIFIC | 10;
898
899
0
int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) {
900
0
  const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
901
0
  if (!ssl->server || !hs->hints_requested) {
902
0
    OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
903
0
    return 0;
904
0
  }
905
906
0
  const SSL_HANDSHAKE_HINTS *hints = hs->hints.get();
907
0
  CBB seq, child;
908
0
  if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE)) {
909
0
    return 0;
910
0
  }
911
912
0
  if (!hints->server_random_tls13.empty()) {
913
0
    if (!CBB_add_asn1_element(&seq, kServerRandomTLS13Tag,
914
0
                              hints->server_random_tls13.data(),
915
0
                              hints->server_random_tls13.size())) {
916
0
      return 0;
917
0
    }
918
0
  }
919
920
0
  if (hints->key_share_group_id != 0 && !hints->key_share_ciphertext.empty() &&
921
0
      !hints->key_share_secret.empty()) {
922
0
    if (!CBB_add_asn1(&seq, &child, kKeyShareHintTag) ||
923
0
        !CBB_add_asn1_uint64(&child, hints->key_share_group_id) ||
924
0
        !CBB_add_asn1_octet_string(&child, hints->key_share_ciphertext.data(),
925
0
                                   hints->key_share_ciphertext.size()) ||
926
0
        !CBB_add_asn1_octet_string(&child, hints->key_share_secret.data(),
927
0
                                   hints->key_share_secret.size())) {
928
0
      return 0;
929
0
    }
930
0
  }
931
932
0
  if (hints->signature_algorithm != 0 && !hints->signature_input.empty() &&
933
0
      !hints->signature.empty()) {
934
0
    if (!CBB_add_asn1(&seq, &child, kSignatureHintTag) ||
935
0
        !CBB_add_asn1_uint64(&child, hints->signature_algorithm) ||
936
0
        !CBB_add_asn1_octet_string(&child, hints->signature_input.data(),
937
0
                                   hints->signature_input.size()) ||
938
0
        !CBB_add_asn1_octet_string(&child, hints->signature_spki.data(),
939
0
                                   hints->signature_spki.size()) ||
940
0
        !CBB_add_asn1_octet_string(&child, hints->signature.data(),
941
0
                                   hints->signature.size())) {
942
0
      return 0;
943
0
    }
944
0
  }
945
946
0
  if (!hints->decrypted_psk.empty()) {
947
0
    if (!CBB_add_asn1_element(&seq, kDecryptedPSKTag,
948
0
                              hints->decrypted_psk.data(),
949
0
                              hints->decrypted_psk.size())) {
950
0
      return 0;
951
0
    }
952
0
  }
953
954
0
  if (hints->ignore_psk &&  //
955
0
      !CBB_add_asn1(&seq, &child, kIgnorePSKTag)) {
956
0
    return 0;
957
0
  }
958
959
0
  if (hints->cert_compression_alg_id != 0 &&
960
0
      !hints->cert_compression_input.empty() &&
961
0
      !hints->cert_compression_output.empty()) {
962
0
    if (!CBB_add_asn1(&seq, &child, kCompressCertificateTag) ||
963
0
        !CBB_add_asn1_uint64(&child, hints->cert_compression_alg_id) ||
964
0
        !CBB_add_asn1_octet_string(&child, hints->cert_compression_input.data(),
965
0
                                   hints->cert_compression_input.size()) ||
966
0
        !CBB_add_asn1_octet_string(&child,
967
0
                                   hints->cert_compression_output.data(),
968
0
                                   hints->cert_compression_output.size())) {
969
0
      return 0;
970
0
    }
971
0
  }
972
973
0
  if (!hints->server_random_tls12.empty()) {
974
0
    if (!CBB_add_asn1_element(&seq, kServerRandomTLS12Tag,
975
0
                              hints->server_random_tls12.data(),
976
0
                              hints->server_random_tls12.size())) {
977
0
      return 0;
978
0
    }
979
0
  }
980
981
0
  if (hints->ecdhe_group_id != 0 && !hints->ecdhe_public_key.empty() &&
982
0
      !hints->ecdhe_private_key.empty()) {
983
0
    if (!CBB_add_asn1(&seq, &child, kECDHEHintTag) ||
984
0
        !CBB_add_asn1_uint64(&child, hints->ecdhe_group_id) ||
985
0
        !CBB_add_asn1_octet_string(&child, hints->ecdhe_public_key.data(),
986
0
                                   hints->ecdhe_public_key.size()) ||
987
0
        !CBB_add_asn1_octet_string(&child, hints->ecdhe_private_key.data(),
988
0
                                   hints->ecdhe_private_key.size())) {
989
0
      return 0;
990
0
    }
991
0
  }
992
993
994
0
  if (!hints->decrypted_ticket.empty()) {
995
0
    if (!CBB_add_asn1_element(&seq, kDecryptedTicketTag,
996
0
                              hints->decrypted_ticket.data(),
997
0
                              hints->decrypted_ticket.size())) {
998
0
      return 0;
999
0
    }
1000
0
  }
1001
1002
0
  if (hints->renew_ticket &&  //
1003
0
      !CBB_add_asn1(&seq, &child, kRenewTicketTag)) {
1004
0
    return 0;
1005
0
  }
1006
1007
0
  if (hints->ignore_ticket &&  //
1008
0
      !CBB_add_asn1(&seq, &child, kIgnoreTicketTag)) {
1009
0
    return 0;
1010
0
  }
1011
1012
0
  return CBB_flush(out);
1013
0
}
1014
1015
static bool get_optional_implicit_null(CBS *cbs, bool *out_present,
1016
0
                                       CBS_ASN1_TAG tag) {
1017
0
  CBS value;
1018
0
  int present;
1019
0
  if (!CBS_get_optional_asn1(cbs, &value, &present, tag) ||
1020
0
      (present && CBS_len(&value) != 0)) {
1021
0
    return false;
1022
0
  }
1023
0
  *out_present = present;
1024
0
  return true;
1025
0
}
1026
1027
603
int SSL_set_handshake_hints(SSL *ssl, const uint8_t *hints, size_t hints_len) {
1028
603
  if (SSL_is_dtls(ssl)) {
1029
603
    OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1030
603
    return 0;
1031
603
  }
1032
1033
0
  UniquePtr<SSL_HANDSHAKE_HINTS> hints_obj = MakeUnique<SSL_HANDSHAKE_HINTS>();
1034
0
  if (hints_obj == nullptr) {
1035
0
    return 0;
1036
0
  }
1037
1038
0
  CBS cbs, seq, server_random_tls13, key_share, signature_hint, psk,
1039
0
      cert_compression, server_random_tls12, ecdhe, ticket;
1040
0
  int has_server_random_tls13, has_key_share, has_signature_hint, has_psk,
1041
0
      has_cert_compression, has_server_random_tls12, has_ecdhe, has_ticket;
1042
0
  CBS_init(&cbs, hints, hints_len);
1043
0
  if (!CBS_get_asn1(&cbs, &seq, CBS_ASN1_SEQUENCE) ||
1044
0
      !CBS_get_optional_asn1(&seq, &server_random_tls13,
1045
0
                             &has_server_random_tls13, kServerRandomTLS13Tag) ||
1046
0
      !CBS_get_optional_asn1(&seq, &key_share, &has_key_share,
1047
0
                             kKeyShareHintTag) ||
1048
0
      !CBS_get_optional_asn1(&seq, &signature_hint, &has_signature_hint,
1049
0
                             kSignatureHintTag) ||
1050
0
      !CBS_get_optional_asn1(&seq, &psk, &has_psk, kDecryptedPSKTag) ||
1051
0
      !get_optional_implicit_null(&seq, &hints_obj->ignore_psk,
1052
0
                                  kIgnorePSKTag) ||
1053
0
      !CBS_get_optional_asn1(&seq, &cert_compression, &has_cert_compression,
1054
0
                             kCompressCertificateTag) ||
1055
0
      !CBS_get_optional_asn1(&seq, &server_random_tls12,
1056
0
                             &has_server_random_tls12, kServerRandomTLS12Tag) ||
1057
0
      !CBS_get_optional_asn1(&seq, &ecdhe, &has_ecdhe, kECDHEHintTag) ||
1058
0
      !CBS_get_optional_asn1(&seq, &ticket, &has_ticket, kDecryptedTicketTag) ||
1059
0
      !get_optional_implicit_null(&seq, &hints_obj->renew_ticket,
1060
0
                                  kRenewTicketTag) ||
1061
0
      !get_optional_implicit_null(&seq, &hints_obj->ignore_ticket,
1062
0
                                  kIgnoreTicketTag)) {
1063
0
    OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
1064
0
    return 0;
1065
0
  }
1066
1067
0
  if (has_server_random_tls13 &&
1068
0
      !hints_obj->server_random_tls13.CopyFrom(server_random_tls13)) {
1069
0
    return 0;
1070
0
  }
1071
1072
0
  if (has_key_share) {
1073
0
    uint64_t group_id;
1074
0
    CBS ciphertext, secret;
1075
0
    if (!CBS_get_asn1_uint64(&key_share, &group_id) ||  //
1076
0
        group_id == 0 || group_id > 0xffff ||
1077
0
        !CBS_get_asn1(&key_share, &ciphertext, CBS_ASN1_OCTETSTRING) ||
1078
0
        !hints_obj->key_share_ciphertext.CopyFrom(ciphertext) ||
1079
0
        !CBS_get_asn1(&key_share, &secret, CBS_ASN1_OCTETSTRING) ||
1080
0
        !hints_obj->key_share_secret.CopyFrom(secret)) {
1081
0
      OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
1082
0
      return 0;
1083
0
    }
1084
0
    hints_obj->key_share_group_id = static_cast<uint16_t>(group_id);
1085
0
  }
1086
1087
0
  if (has_signature_hint) {
1088
0
    uint64_t sig_alg;
1089
0
    CBS input, spki, signature;
1090
0
    if (!CBS_get_asn1_uint64(&signature_hint, &sig_alg) ||  //
1091
0
        sig_alg == 0 || sig_alg > 0xffff ||
1092
0
        !CBS_get_asn1(&signature_hint, &input, CBS_ASN1_OCTETSTRING) ||
1093
0
        !hints_obj->signature_input.CopyFrom(input) ||
1094
0
        !CBS_get_asn1(&signature_hint, &spki, CBS_ASN1_OCTETSTRING) ||
1095
0
        !hints_obj->signature_spki.CopyFrom(spki) ||
1096
0
        !CBS_get_asn1(&signature_hint, &signature, CBS_ASN1_OCTETSTRING) ||
1097
0
        !hints_obj->signature.CopyFrom(signature)) {
1098
0
      OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
1099
0
      return 0;
1100
0
    }
1101
0
    hints_obj->signature_algorithm = static_cast<uint16_t>(sig_alg);
1102
0
  }
1103
1104
0
  if (has_psk && !hints_obj->decrypted_psk.CopyFrom(psk)) {
1105
0
    return 0;
1106
0
  }
1107
0
  if (has_psk && hints_obj->ignore_psk) {
1108
0
    OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
1109
0
    return 0;
1110
0
  }
1111
1112
0
  if (has_cert_compression) {
1113
0
    uint64_t alg;
1114
0
    CBS input, output;
1115
0
    if (!CBS_get_asn1_uint64(&cert_compression, &alg) ||  //
1116
0
        alg == 0 || alg > 0xffff ||
1117
0
        !CBS_get_asn1(&cert_compression, &input, CBS_ASN1_OCTETSTRING) ||
1118
0
        !hints_obj->cert_compression_input.CopyFrom(input) ||
1119
0
        !CBS_get_asn1(&cert_compression, &output, CBS_ASN1_OCTETSTRING) ||
1120
0
        !hints_obj->cert_compression_output.CopyFrom(output)) {
1121
0
      OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
1122
0
      return 0;
1123
0
    }
1124
0
    hints_obj->cert_compression_alg_id = static_cast<uint16_t>(alg);
1125
0
  }
1126
1127
0
  if (has_server_random_tls12 &&
1128
0
      !hints_obj->server_random_tls12.CopyFrom(server_random_tls12)) {
1129
0
    return 0;
1130
0
  }
1131
1132
0
  if (has_ecdhe) {
1133
0
    uint64_t group_id;
1134
0
    CBS public_key, private_key;
1135
0
    if (!CBS_get_asn1_uint64(&ecdhe, &group_id) ||  //
1136
0
        group_id == 0 || group_id > 0xffff ||
1137
0
        !CBS_get_asn1(&ecdhe, &public_key, CBS_ASN1_OCTETSTRING) ||
1138
0
        !hints_obj->ecdhe_public_key.CopyFrom(public_key) ||
1139
0
        !CBS_get_asn1(&ecdhe, &private_key, CBS_ASN1_OCTETSTRING) ||
1140
0
        !hints_obj->ecdhe_private_key.CopyFrom(private_key)) {
1141
0
      OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
1142
0
      return 0;
1143
0
    }
1144
0
    hints_obj->ecdhe_group_id = static_cast<uint16_t>(group_id);
1145
0
  }
1146
1147
0
  if (has_ticket && !hints_obj->decrypted_ticket.CopyFrom(ticket)) {
1148
0
    return 0;
1149
0
  }
1150
0
  if (has_ticket && hints_obj->ignore_ticket) {
1151
0
    OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
1152
0
    return 0;
1153
0
  }
1154
0
  if (!has_ticket && hints_obj->renew_ticket) {
1155
0
    OPENSSL_PUT_ERROR(SSL, SSL_R_COULD_NOT_PARSE_HINTS);
1156
0
    return 0;
1157
0
  }
1158
1159
0
  ssl->s3->hs->hints = std::move(hints_obj);
1160
0
  return 1;
1161
0
}