int SSL_serialize_handshake_hints()

in ssl/handoff.cc [901:1015]


int SSL_serialize_handshake_hints(const SSL *ssl, CBB *out) {
  const SSL_HANDSHAKE *hs = ssl->s3->hs.get();
  if (!ssl->server || !hs->hints_requested) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }

  const SSL_HANDSHAKE_HINTS *hints = hs->hints.get();
  CBB seq, child;
  if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE)) {
    return 0;
  }

  if (!hints->server_random_tls13.empty()) {
    if (!CBB_add_asn1(&seq, &child, kServerRandomTLS13Tag) ||
        !CBB_add_bytes(&child, hints->server_random_tls13.data(),
                       hints->server_random_tls13.size())) {
      return 0;
    }
  }

  if (hints->key_share_group_id != 0 && !hints->key_share_public_key.empty() &&
      !hints->key_share_secret.empty()) {
    if (!CBB_add_asn1(&seq, &child, kKeyShareHintTag) ||
        !CBB_add_asn1_uint64(&child, hints->key_share_group_id) ||
        !CBB_add_asn1_octet_string(&child, hints->key_share_public_key.data(),
                                   hints->key_share_public_key.size()) ||
        !CBB_add_asn1_octet_string(&child, hints->key_share_secret.data(),
                                   hints->key_share_secret.size())) {
      return 0;
    }
  }

  if (hints->signature_algorithm != 0 && !hints->signature_input.empty() &&
      !hints->signature.empty()) {
    if (!CBB_add_asn1(&seq, &child, kSignatureHintTag) ||
        !CBB_add_asn1_uint64(&child, hints->signature_algorithm) ||
        !CBB_add_asn1_octet_string(&child, hints->signature_input.data(),
                                   hints->signature_input.size()) ||
        !CBB_add_asn1_octet_string(&child, hints->signature_spki.data(),
                                   hints->signature_spki.size()) ||
        !CBB_add_asn1_octet_string(&child, hints->signature.data(),
                                   hints->signature.size())) {
      return 0;
    }
  }

  if (!hints->decrypted_psk.empty()) {
    if (!CBB_add_asn1(&seq, &child, kDecryptedPSKTag) ||
        !CBB_add_bytes(&child, hints->decrypted_psk.data(),
                       hints->decrypted_psk.size())) {
      return 0;
    }
  }

  if (hints->ignore_psk &&  //
      !CBB_add_asn1(&seq, &child, kIgnorePSKTag)) {
    return 0;
  }

  if (hints->cert_compression_alg_id != 0 &&
      !hints->cert_compression_input.empty() &&
      !hints->cert_compression_output.empty()) {
    if (!CBB_add_asn1(&seq, &child, kCompressCertificateTag) ||
        !CBB_add_asn1_uint64(&child, hints->cert_compression_alg_id) ||
        !CBB_add_asn1_octet_string(&child, hints->cert_compression_input.data(),
                                   hints->cert_compression_input.size()) ||
        !CBB_add_asn1_octet_string(&child,
                                   hints->cert_compression_output.data(),
                                   hints->cert_compression_output.size())) {
      return 0;
    }
  }

  if (!hints->server_random_tls12.empty()) {
    if (!CBB_add_asn1(&seq, &child, kServerRandomTLS12Tag) ||
        !CBB_add_bytes(&child, hints->server_random_tls12.data(),
                       hints->server_random_tls12.size())) {
      return 0;
    }
  }

  if (hints->ecdhe_group_id != 0 && !hints->ecdhe_public_key.empty() &&
      !hints->ecdhe_private_key.empty()) {
    if (!CBB_add_asn1(&seq, &child, kECDHEHintTag) ||
        !CBB_add_asn1_uint64(&child, hints->ecdhe_group_id) ||
        !CBB_add_asn1_octet_string(&child, hints->ecdhe_public_key.data(),
                                   hints->ecdhe_public_key.size()) ||
        !CBB_add_asn1_octet_string(&child, hints->ecdhe_private_key.data(),
                                   hints->ecdhe_private_key.size())) {
      return 0;
    }
  }


  if (!hints->decrypted_ticket.empty()) {
    if (!CBB_add_asn1(&seq, &child, kDecryptedTicketTag) ||
        !CBB_add_bytes(&child, hints->decrypted_ticket.data(),
                       hints->decrypted_ticket.size())) {
      return 0;
    }
  }

  if (hints->renew_ticket &&  //
      !CBB_add_asn1(&seq, &child, kRenewTicketTag)) {
    return 0;
  }

  if (hints->ignore_ticket &&  //
      !CBB_add_asn1(&seq, &child, kIgnoreTicketTag)) {
    return 0;
  }

  return CBB_flush(out);
}