/* Copyright (c) 2019, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/sha.h>
#include <openssl/trust_token.h>

#include "internal.h"


// The Trust Token API is described in
// https://github.com/WICG/trust-token-api/blob/master/README.md and provides a
// protocol for issuing and redeeming tokens built on top of the PMBTokens
// construction.

static int cbb_add_raw_point(CBB *cbb, const EC_GROUP *group,
                             const EC_RAW_POINT *point) {
  size_t len =
      ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0);
  if (len == 0) {
    return 0;
  }
  uint8_t *p;
  return CBB_add_u16(cbb, len) && CBB_add_space(cbb, &p, len) &&
         ec_point_to_bytes(group, point, POINT_CONVERSION_UNCOMPRESSED, p,
                           len) == len;
}

static int cbs_get_raw_point(CBS *cbs, const EC_GROUP *group,
                             EC_RAW_POINT *out) {
  CBS child;
  return CBS_get_u16_length_prefixed(cbs, &child) &&
         ec_point_from_uncompressed(group, out, CBS_data(&child),
                                    CBS_len(&child));
}

TRUST_TOKEN *TRUST_TOKEN_new(const uint8_t *data, size_t len) {
  TRUST_TOKEN *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN));
  if (ret == NULL) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN));
  ret->data = OPENSSL_memdup(data, len);
  if (len != 0 && ret->data == NULL) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    OPENSSL_free(ret);
    return NULL;
  }
  ret->len = len;
  return ret;
}

void TRUST_TOKEN_free(TRUST_TOKEN *token) {
  if (token == NULL) {
    return;
  }
  OPENSSL_free(token->data);
  OPENSSL_free(token);
}

TRUST_TOKEN_CLIENT *TRUST_TOKEN_CLIENT_new(uint16_t max_batchsize) {
  TRUST_TOKEN_CLIENT *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN_CLIENT));
  if (ret == NULL) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_CLIENT));
  ret->max_batchsize = max_batchsize;
  ret->pretokens = sk_PMBTOKEN_PRETOKEN_new_null();
  if (ret->pretokens == NULL) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    OPENSSL_free(ret);
    return NULL;
  }
  return ret;
}

void TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT *ctx) {
  if (ctx == NULL) {
    return;
  }
  EVP_PKEY_free(ctx->srr_key);
  sk_PMBTOKEN_PRETOKEN_pop_free(ctx->pretokens, PMBTOKEN_PRETOKEN_free);
  OPENSSL_free(ctx);
}

int TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT *ctx, size_t *out_key_index,
                               const uint8_t *key, size_t key_len) {
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1);
  if (group == NULL) {
    return 0;
  }

  if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS);
    return 0;
  }

  struct trust_token_client_key_st *key_s = &ctx->keys[ctx->num_keys];

  CBS cbs;
  CBS_init(&cbs, key, key_len);
  uint32_t key_id;
  if (!CBS_get_u32(&cbs, &key_id) ||
      !cbs_get_raw_point(&cbs, group, &key_s->pub0) ||
      !cbs_get_raw_point(&cbs, group, &key_s->pub1) ||
      !cbs_get_raw_point(&cbs, group, &key_s->pubs) ||
      CBS_len(&cbs) != 0) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    return 0;
  }
  key_s->id = key_id;
  *out_key_index = ctx->num_keys;
  ctx->num_keys += 1;
  return 1;
}

int TRUST_TOKEN_CLIENT_set_srr_key(TRUST_TOKEN_CLIENT *ctx, EVP_PKEY *key) {
  EVP_PKEY_free(ctx->srr_key);
  EVP_PKEY_up_ref(key);
  ctx->srr_key = key;
  return 1;
}

int TRUST_TOKEN_CLIENT_begin_issuance(TRUST_TOKEN_CLIENT *ctx, uint8_t **out,
                                      size_t *out_len, size_t count) {
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1);
  if (group == NULL) {
    return 0;
  }

  if (count > ctx->max_batchsize) {
    count = ctx->max_batchsize;
  }

  int ret = 0;
  CBB request;
  if (!CBB_init(&request, 0) ||
      !CBB_add_u16(&request, count)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  for (size_t i = 0; i < count; i++) {
    PMBTOKEN_PRETOKEN *pretoken = pmbtoken_blind();
    if (pretoken == NULL ||
        !cbb_add_raw_point(&request, group, &pretoken->Tp) ||
        !sk_PMBTOKEN_PRETOKEN_push(ctx->pretokens, pretoken)) {
      PMBTOKEN_PRETOKEN_free(pretoken);
      goto err;
    }
  }

  if (!CBB_finish(&request, out, out_len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  ret = 1;

err:
  CBB_cleanup(&request);
  return ret;
}

STACK_OF(TRUST_TOKEN) *
    TRUST_TOKEN_CLIENT_finish_issuance(TRUST_TOKEN_CLIENT *ctx,
                                       size_t *out_key_index,
                                       const uint8_t *response,
                                       size_t response_len) {
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1);
  if (group == NULL) {
    return 0;
  }

  CBS in;
  CBS_init(&in, response, response_len);
  uint16_t count;
  uint32_t key_id;
  if (!CBS_get_u16(&in, &count) ||
      !CBS_get_u32(&in, &key_id)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    return NULL;
  }

  size_t key_index = 0;
  const struct trust_token_client_key_st *key = NULL;
  for (size_t i = 0; i < ctx->num_keys; i++) {
    if (ctx->keys[i].id == key_id) {
      key_index = i;
      key = &ctx->keys[i];
      break;
    }
  }

  if (key == NULL) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_KEY_ID);
    return NULL;
  }

  if (count > sk_PMBTOKEN_PRETOKEN_num(ctx->pretokens)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    return NULL;
  }

  int ok = 0;
  STACK_OF(TRUST_TOKEN) *tokens = sk_TRUST_TOKEN_new_null();
  if (tokens == NULL) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    return NULL;
  }

  for (size_t i = 0; i < count; i++) {
    uint8_t s[PMBTOKEN_NONCE_SIZE];
    EC_RAW_POINT Wp, Wsp;
    if (!CBS_copy_bytes(&in, s, PMBTOKEN_NONCE_SIZE) ||
        !cbs_get_raw_point(&in, group, &Wp) ||
        !cbs_get_raw_point(&in, group, &Wsp)) {
      OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
      goto err;
    }

    PMBTOKEN_PRETOKEN *pretoken = sk_PMBTOKEN_PRETOKEN_value(ctx->pretokens, i);
    PMBTOKEN_TOKEN pmbtoken;
    if (!pmbtoken_unblind(&pmbtoken, s, &Wp, &Wsp, pretoken)) {
      OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
      goto err;
    }

    int token_ok = 0;
    TRUST_TOKEN *token = NULL;
    CBB token_cbb;
    if (!CBB_init(&token_cbb, 0) ||
        !CBB_add_u32(&token_cbb, key_id) ||
        !CBB_add_bytes(&token_cbb, pmbtoken.t, PMBTOKEN_NONCE_SIZE) ||
        !cbb_add_raw_point(&token_cbb, group, &pmbtoken.S) ||
        !cbb_add_raw_point(&token_cbb, group, &pmbtoken.W) ||
        !cbb_add_raw_point(&token_cbb, group, &pmbtoken.Ws)) {
      goto token_err;
    }

    token = TRUST_TOKEN_new(CBB_data(&token_cbb), CBB_len(&token_cbb));
    if (token == NULL) {
      OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
      goto token_err;
    }

    if (!sk_TRUST_TOKEN_push(tokens, token)) {
      OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
      goto token_err;
    }
    token_ok = 1;

  token_err:
    CBB_cleanup(&token_cbb);
    if (!token_ok) {
      TRUST_TOKEN_free(token);
      goto err;
    }
  }

  sk_PMBTOKEN_PRETOKEN_pop_free(ctx->pretokens, PMBTOKEN_PRETOKEN_free);
  ctx->pretokens = NULL;

  *out_key_index = key_index;
  ok = 1;

err:
  if (!ok) {
    sk_TRUST_TOKEN_pop_free(tokens, TRUST_TOKEN_free);
    return NULL;
  } else {
    return tokens;
  }
}

int TRUST_TOKEN_CLIENT_begin_redemption(TRUST_TOKEN_CLIENT *ctx, uint8_t **out,
                                        size_t *out_len,
                                        const TRUST_TOKEN *token,
                                        const uint8_t *data, size_t data_len,
                                        uint64_t time) {
  CBB request, token_inner, inner;
  if (!CBB_init(&request, 0) ||
      !CBB_add_u16_length_prefixed(&request, &token_inner) ||
      !CBB_add_bytes(&token_inner, token->data, token->len) ||
      !CBB_add_u16_length_prefixed(&request, &inner) ||
      !CBB_add_bytes(&inner, data, data_len) ||
      !CBB_add_u64(&request, time) ||
      !CBB_finish(&request, out, out_len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    CBB_cleanup(&request);
    return 0;
  }
  return 1;
}

int TRUST_TOKEN_CLIENT_finish_redemption(TRUST_TOKEN_CLIENT *ctx,
                                         uint8_t **out_srr, size_t *out_srr_len,
                                         uint8_t **out_sig, size_t *out_sig_len,
                                         const uint8_t *response,
                                         size_t response_len) {
  if (ctx->srr_key == NULL) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_NO_SRR_KEY_CONFIGURED);
    return 0;
  }

  CBS in, srr, sig;
  CBS_init(&in, response, response_len);
  if (!CBS_get_u16_length_prefixed(&in, &srr) ||
      !CBS_get_u16_length_prefixed(&in, &sig)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
    return 0;
  }

  EVP_MD_CTX md_ctx;
  EVP_MD_CTX_init(&md_ctx);
  int sig_ok = EVP_DigestVerifyInit(&md_ctx, NULL, NULL, NULL, ctx->srr_key) &&
               EVP_DigestVerify(&md_ctx, CBS_data(&sig), CBS_len(&sig),
                                CBS_data(&srr), CBS_len(&srr));
  EVP_MD_CTX_cleanup(&md_ctx);

  if (!sig_ok) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_SRR_SIGNATURE_ERROR);
    return 0;
  }

  uint8_t *srr_buf = NULL, *sig_buf = NULL;
  size_t srr_len, sig_len;
  if (!CBS_stow(&srr, &srr_buf, &srr_len) ||
      !CBS_stow(&sig, &sig_buf, &sig_len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    OPENSSL_free(srr_buf);
    OPENSSL_free(sig_buf);
    return 0;
  }

  *out_srr = srr_buf;
  *out_srr_len = srr_len;
  *out_sig = sig_buf;
  *out_sig_len = sig_len;
  return 1;
}

TRUST_TOKEN_ISSUER *TRUST_TOKEN_ISSUER_new(uint16_t max_batchsize) {
  TRUST_TOKEN_ISSUER *ret = OPENSSL_malloc(sizeof(TRUST_TOKEN_ISSUER));
  if (ret == NULL) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  OPENSSL_memset(ret, 0, sizeof(TRUST_TOKEN_ISSUER));
  ret->max_batchsize = max_batchsize;
  return ret;
}

void TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER *ctx) {
  if (ctx == NULL) {
    return;
  }
  EVP_PKEY_free(ctx->srr_key);
  OPENSSL_free(ctx->metadata_key);
  OPENSSL_free(ctx);
}

int TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER *ctx, const uint8_t *key,
                               size_t key_len) {
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1);
  if (group == NULL) {
    return 0;
  }

  if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS);
    return 0;
  }

  CBS cbs, tmp;
  CBS_init(&cbs, key, key_len);
  uint32_t key_id;
  if (!CBS_get_u32(&cbs, &key_id)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    return 0;
  }

  size_t scalar_len = BN_num_bytes(&group->order);
  struct trust_token_issuer_key_st *key_s = &(ctx->keys[ctx->num_keys]);
  EC_SCALAR *scalars[] = {&key_s->x0, &key_s->y0, &key_s->x1,
                          &key_s->y1, &key_s->xs, &key_s->ys};
  for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(scalars); i++) {
    if (!CBS_get_bytes(&cbs, &tmp, scalar_len) ||
        !ec_scalar_from_bytes(group, scalars[i], CBS_data(&tmp),
                              CBS_len(&tmp))) {
      OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
     return 0;
    }
  }
  key_s->id = key_id;
  ctx->num_keys += 1;
  return 1;
}

int TRUST_TOKEN_ISSUER_set_srr_key(TRUST_TOKEN_ISSUER *ctx, EVP_PKEY *key) {
  EVP_PKEY_free(ctx->srr_key);
  EVP_PKEY_up_ref(key);
  ctx->srr_key = key;
  return 1;
}

int TRUST_TOKEN_ISSUER_set_metadata_key(TRUST_TOKEN_ISSUER *ctx,
                                        const uint8_t *key, size_t len) {
  if (len < 32) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA_KEY);
  }
  OPENSSL_free(ctx->metadata_key);
  ctx->metadata_key_len = 0;
  ctx->metadata_key = OPENSSL_memdup(key, len);
  if (ctx->metadata_key == NULL) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    return 0;
  }
  ctx->metadata_key_len = len;
  return 1;
}

int TRUST_TOKEN_ISSUER_issue(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out,
                             size_t *out_len, uint8_t *out_tokens_issued,
                             const uint8_t *request, size_t request_len,
                             uint32_t public_metadata, uint8_t private_metadata,
                             size_t max_issuance) {
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1);
  if (group == NULL) {
    return 0;
  }

  if (max_issuance > ctx->max_batchsize) {
    max_issuance = ctx->max_batchsize;
  }

  int found_public_metadata = 0;
  for (size_t i = 0; i < ctx->num_keys; i++) {
    if (ctx->keys[i].id == public_metadata) {
      found_public_metadata = 1;
      break;
    }
  }

  if (!found_public_metadata || private_metadata > 1) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_METADATA);
    return 0;
  }

  CBS in;
  CBS_init(&in, request, request_len);

  CBB response;
  if (!CBB_init(&response, 0)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    return 0;
  }

  int ret = 0;
  uint16_t count;
  if (!CBS_get_u16(&in, &count)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
    goto err;
  }

  if (count > max_issuance) {
    count = max_issuance;
  }

  if (!CBB_add_u16(&response, count) ||
      !CBB_add_u32(&response, public_metadata)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  for (size_t i = 0; i < count; i++) {
    EC_RAW_POINT Tp;
    if (!cbs_get_raw_point(&in, group, &Tp)) {
      OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
      goto err;
    }

    uint8_t s[PMBTOKEN_NONCE_SIZE];
    EC_RAW_POINT Wp, Wsp;
    if (!pmbtoken_sign(ctx, s, &Wp, &Wsp, &Tp, public_metadata,
                       private_metadata)) {
      goto err;
    }

    if (!CBB_add_bytes(&response, s, PMBTOKEN_NONCE_SIZE) ||
        !cbb_add_raw_point(&response, group, &Wp) ||
        !cbb_add_raw_point(&response, group, &Wsp)) {
      goto err;
    }
  }

  *out_tokens_issued = count;

  if (!CBB_finish(&response, out, out_len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  ret = 1;

err:
  CBB_cleanup(&response);
  return ret;
}

// https://tools.ietf.org/html/rfc7049#section-2.1
static int add_cbor_int_with_type(CBB *cbb, uint8_t major_type,
                                  uint64_t value) {
  if (value <= 23) {
    return CBB_add_u8(cbb, value | major_type);
  }
  if (value <= 0xff) {
    return CBB_add_u8(cbb, 0x18 | major_type) && CBB_add_u8(cbb, value);
  }
  if (value <= 0xffff) {
    return CBB_add_u8(cbb, 0x19 | major_type) && CBB_add_u16(cbb, value);
  }
  if (value <= 0xffffffff) {
    return CBB_add_u8(cbb, 0x1a | major_type) && CBB_add_u32(cbb, value);
  }
  if (value <= 0xffffffffffffffff) {
    return CBB_add_u8(cbb, 0x1b | major_type) && CBB_add_u64(cbb, value);
  }

  return 0;
}

// https://tools.ietf.org/html/rfc7049#section-2.1
static int add_cbor_int(CBB *cbb, uint64_t value) {
  return add_cbor_int_with_type(cbb, 0, value);
}

// https://tools.ietf.org/html/rfc7049#section-2.1
static int add_cbor_text(CBB *cbb, const char *data, size_t len) {
  return add_cbor_int_with_type(cbb, 0x60, len) &&
         CBB_add_bytes(cbb, (const uint8_t *)data, len);
}

// https://tools.ietf.org/html/rfc7049#section-2.1
static int add_cbor_map(CBB *cbb, uint8_t size) {
  return add_cbor_int_with_type(cbb, 0xa0, size);
}

static uint8_t get_metadata_obfuscator(const uint8_t *key, size_t key_len,
                                       const uint8_t *client_data,
                                       size_t client_data_len) {
  uint8_t metadata_obfuscator[SHA256_DIGEST_LENGTH];
  SHA256_CTX sha_ctx;
  SHA256_Init(&sha_ctx);
  SHA256_Update(&sha_ctx, key, key_len);
  SHA256_Update(&sha_ctx, client_data, client_data_len);
  SHA256_Final(metadata_obfuscator, &sha_ctx);
  return metadata_obfuscator[0] >> 7;
}

int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out,
                              size_t *out_len, TRUST_TOKEN **out_token,
                              uint8_t **out_client_data,
                              size_t *out_client_data_len,
                              uint64_t *out_redemption_time,
                              const uint8_t *request, size_t request_len,
                              uint64_t lifetime) {
  EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp521r1);
  if (group == NULL) {
    return 0;
  }

  CBS request_cbs, token_cbs;
  CBS_init(&request_cbs, request, request_len);
  if (!CBS_get_u16_length_prefixed(&request_cbs, &token_cbs)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
    return 0;
  }

  uint32_t public_metadata = 0;
  uint8_t private_metadata = 0;

  // Parse the token. If there is an error, treat it as an invalid token.
  PMBTOKEN_TOKEN pmbtoken;
  if (!CBS_get_u32(&token_cbs, &public_metadata) ||
      !CBS_copy_bytes(&token_cbs, pmbtoken.t, PMBTOKEN_NONCE_SIZE) ||
      !cbs_get_raw_point(&token_cbs, group, &pmbtoken.S) ||
      !cbs_get_raw_point(&token_cbs, group, &pmbtoken.W) ||
      !cbs_get_raw_point(&token_cbs, group, &pmbtoken.Ws) ||
      CBS_len(&token_cbs) != 0 ||
      !pmbtoken_read(ctx, &private_metadata, &pmbtoken, public_metadata)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_INVALID_TOKEN);
    return 0;
  }

  int ok = 0;
  CBB response, srr;
  uint8_t *srr_buf = NULL, *sig_buf = NULL, *client_data_buf = NULL;
  size_t srr_len = 0, sig_len = 0, client_data_len = 0;
  EVP_MD_CTX md_ctx;
  EVP_MD_CTX_init(&md_ctx);
  CBB_zero(&srr);
  if (!CBB_init(&response, 0)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  CBS client_data;
  uint64_t redemption_time;
  if (!CBS_get_u16_length_prefixed(&request_cbs, &client_data) ||
      !CBS_get_u64(&request_cbs, &redemption_time)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_ERROR);
    goto err;
  }

  uint8_t metadata_obfuscator =
      get_metadata_obfuscator(ctx->metadata_key, ctx->metadata_key_len,
                              CBS_data(&client_data), CBS_len(&client_data));

  // The SRR is constructed as per the format described in
  // https://docs.google.com/document/d/1TNnya6B8pyomDK2F1R9CL3dY10OAmqWlnCxsWyOBDVQ/edit#heading=h.7mkzvhpqb8l5

  static const char kClientDataLabel[] = "client-data";
  static const char kExpiryTimestampLabel[] = "expiry-timestamp";
  static const char kMetadataLabel[] = "metadata";
  static const char kPrivateLabel[] = "private";
  static const char kPublicLabel[] = "public";

  if (!CBB_init(&srr, 0) ||
      !add_cbor_map(&srr, 3) ||  // SRR map
      !add_cbor_text(&srr, kClientDataLabel, strlen(kClientDataLabel)) ||
      !CBB_add_bytes(&srr, CBS_data(&client_data), CBS_len(&client_data)) ||
      !add_cbor_text(&srr, kExpiryTimestampLabel,
                     strlen(kExpiryTimestampLabel)) ||
      !add_cbor_int(&srr, redemption_time + lifetime) ||
      !add_cbor_text(&srr, kMetadataLabel, strlen(kMetadataLabel)) ||
      !add_cbor_map(&srr, 2) ||  // Metadata map
      !add_cbor_text(&srr, kPrivateLabel, strlen(kPrivateLabel)) ||
      !add_cbor_int(&srr, private_metadata ^ metadata_obfuscator) ||
      !add_cbor_text(&srr, kPublicLabel, strlen(kPublicLabel)) ||
      !add_cbor_int(&srr, public_metadata) ||
      !CBB_finish(&srr, &srr_buf, &srr_len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  if (!EVP_DigestSignInit(&md_ctx, NULL, NULL, NULL, ctx->srr_key) ||
      !EVP_DigestSign(&md_ctx, NULL, &sig_len, srr_buf, srr_len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_SRR_SIGNATURE_ERROR);
    goto err;
  }

  CBB child;
  uint8_t *ptr;
  if (!CBB_add_u16_length_prefixed(&response, &child) ||
      !CBB_add_bytes(&child, srr_buf, srr_len) ||
      !CBB_add_u16_length_prefixed(&response, &child) ||
      !CBB_reserve(&child, &ptr, sig_len) ||
      !EVP_DigestSign(&md_ctx, ptr, &sig_len, srr_buf, srr_len) ||
      !CBB_did_write(&child, sig_len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  if (!CBS_stow(&client_data, &client_data_buf, &client_data_len) ||
      !CBB_finish(&response, out, out_len)) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  TRUST_TOKEN *token = TRUST_TOKEN_new(pmbtoken.t, PMBTOKEN_NONCE_SIZE);
  if (token == NULL) {
    OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
    goto err;
  }
  *out_token = token;
  *out_client_data = client_data_buf;
  *out_client_data_len = client_data_len;
  *out_redemption_time = redemption_time;

  ok = 1;

err:
  CBB_cleanup(&response);
  CBB_cleanup(&srr);
  OPENSSL_free(srr_buf);
  OPENSSL_free(sig_buf);
  EVP_MD_CTX_cleanup(&md_ctx);
  if (!ok) {
    OPENSSL_free(client_data_buf);
  }
  return ok;
}

int TRUST_TOKEN_decode_private_metadata(uint8_t *out_value, const uint8_t *key,
                                        size_t key_len,
                                        const uint8_t *client_data,
                                        size_t client_data_len,
                                        uint8_t encrypted_bit) {
  uint8_t metadata_obfuscator =
      get_metadata_obfuscator(key, key_len, client_data, client_data_len);
  *out_value = encrypted_bit ^ metadata_obfuscator;
  return 1;
}
