Coverage Report

Created: 2024-09-19 09:45

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