// Copyright 2015 The Weave Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/macaroon_caveat.h"
#include "src/macaroon_caveat_internal.h"

#include <string.h>

#include "src/crypto_hmac.h"
#include "src/macaroon.h"
#include "src/macaroon_context.h"
#include "src/macaroon_encoding.h"

static bool is_valid_caveat_type_(UwMacaroonCaveatType type) {
  switch (type) {
    case kUwMacaroonCaveatTypeNonce:
    case kUwMacaroonCaveatTypeScope:
    case kUwMacaroonCaveatTypeExpirationAbsolute:
    case kUwMacaroonCaveatTypeTTL1Hour:
    case kUwMacaroonCaveatTypeTTL24Hour:
    case kUwMacaroonCaveatTypeDelegationTimestamp:
    case kUwMacaroonCaveatTypeDelegateeUser:
    case kUwMacaroonCaveatTypeDelegateeApp:
    case kUwMacaroonCaveatTypeAppCommandsOnly:
    case kUwMacaroonCaveatTypeDelegateeService:
    case kUwMacaroonCaveatTypeBleSessionID:
    case kUwMacaroonCaveatTypeLanSessionID:
    case kUwMacaroonCaveatTypeAuthenticationChallenge:
    case kUwMacaroonCaveatTypeClientAuthorizationTokenV1:
    case kUwMacaroonCaveatTypeServerAuthenticationTokenV1:
      return true;
  }
  return false;
}

static bool is_valid_scope_type_(UwMacaroonCaveatScopeType type) {
  switch (type) {
    case kUwMacaroonCaveatScopeTypeOwner:
    case kUwMacaroonCaveatScopeTypeManager:
    case kUwMacaroonCaveatScopeTypeUser:
    case kUwMacaroonCaveatScopeTypeViewer:
      return true;
  }
  return false;
}

static bool is_valid_service_id_(UwMacaroonCaveatCloudServiceId service_id) {
  switch (service_id) {
    case kUwMacaroonCaveatCloudServiceIdNotCloudRegistered:
    case kUwMacaroonCaveatCloudServiceIdGoogleWeave:
      return true;
  }
  return false;
}

static bool create_caveat_no_value_(UwMacaroonCaveatType type,
                                    uint8_t* buffer,
                                    size_t buffer_size,
                                    UwMacaroonCaveat* new_caveat) {
  // (buffer_size == 0 || get_buffsize_() > buffer_size) will conver the case
  // that get_buffer_size_() returns 0 (for errors), so there is no need to
  // check get_buffer_size_() == 0 again.
  if (buffer == NULL || buffer_size == 0 || new_caveat == NULL ||
      uw_macaroon_caveat_creation_get_buffsize_(type, 0) > buffer_size) {
    return false;
  }

  size_t encoded_str_len = 0, total_str_len = 0;
  if (!uw_macaroon_encoding_encode_uint_((uint32_t)type, buffer, buffer_size,
                                         &encoded_str_len)) {
    return false;
  }
  total_str_len += encoded_str_len;

  new_caveat->bytes = buffer;
  new_caveat->num_bytes = total_str_len;
  return true;
}

static bool create_caveat_uint_value_(UwMacaroonCaveatType type,
                                      uint32_t unsigned_int,
                                      uint8_t* buffer,
                                      size_t buffer_size,
                                      UwMacaroonCaveat* new_caveat) {
  if (buffer == NULL || buffer_size == 0 || new_caveat == NULL ||
      uw_macaroon_caveat_creation_get_buffsize_(type, 0) > buffer_size) {
    return false;
  }

  size_t encoded_str_len = 0, total_str_len = 0;
  if (!uw_macaroon_encoding_encode_uint_((uint32_t)type, buffer, buffer_size,
                                         &encoded_str_len)) {
    return false;
  }
  total_str_len += encoded_str_len;
  if (!uw_macaroon_encoding_encode_uint_(unsigned_int, buffer + total_str_len,
                                         buffer_size - total_str_len,
                                         &encoded_str_len)) {
    return false;
  }
  total_str_len += encoded_str_len;

  new_caveat->bytes = buffer;
  new_caveat->num_bytes = total_str_len;
  return true;
}

static bool create_caveat_bstr_value_(UwMacaroonCaveatType type,
                                      const uint8_t* str,
                                      size_t str_len,
                                      uint8_t* buffer,
                                      size_t buffer_size,
                                      UwMacaroonCaveat* new_caveat) {
  if ((str == NULL && str_len != 0) || buffer == NULL || buffer_size == 0 ||
      new_caveat == NULL ||
      uw_macaroon_caveat_creation_get_buffsize_(type, str_len) > buffer_size) {
    return false;
  }

  size_t encoded_str_len = 0, total_str_len = 0;
  if (!uw_macaroon_encoding_encode_uint_((uint32_t)type, buffer, buffer_size,
                                         &encoded_str_len)) {
    return false;
  }
  total_str_len += encoded_str_len;
  if (!uw_macaroon_encoding_encode_byte_str_(
          str, str_len, buffer + total_str_len, buffer_size - total_str_len,
          &encoded_str_len)) {
    return false;
  }
  total_str_len += encoded_str_len;

  new_caveat->bytes = buffer;
  new_caveat->num_bytes = total_str_len;
  return true;
}

size_t uw_macaroon_caveat_creation_get_buffsize_(UwMacaroonCaveatType type,
                                                 size_t str_len) {
  switch (type) {
    // No values
    case kUwMacaroonCaveatTypeTTL1Hour:
    case kUwMacaroonCaveatTypeTTL24Hour:
    case kUwMacaroonCaveatTypeAppCommandsOnly:
    case kUwMacaroonCaveatTypeBleSessionID:
    case kUwMacaroonCaveatTypeAuthenticationChallenge:
      return UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;

    // Unsigned integers
    case kUwMacaroonCaveatTypeScope:
    case kUwMacaroonCaveatTypeDelegateeService:
    case kUwMacaroonCaveatTypeExpirationAbsolute:
    case kUwMacaroonCaveatTypeDelegationTimestamp:
      return 2 * UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;

    // Byte strings
    case kUwMacaroonCaveatTypeNonce:
    case kUwMacaroonCaveatTypeDelegateeUser:
    case kUwMacaroonCaveatTypeDelegateeApp:
    case kUwMacaroonCaveatTypeLanSessionID:
    case kUwMacaroonCaveatTypeClientAuthorizationTokenV1:
    case kUwMacaroonCaveatTypeServerAuthenticationTokenV1:
      return str_len + 2 * UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;

    default:
      return 0;  // For errors
  }
}

bool uw_macaroon_caveat_create_nonce_(const uint8_t* nonce,
                                      size_t nonce_size,
                                      uint8_t* buffer,
                                      size_t buffer_size,
                                      UwMacaroonCaveat* new_caveat) {
  return create_caveat_bstr_value_(kUwMacaroonCaveatTypeNonce, nonce,
                                   nonce_size, buffer, buffer_size, new_caveat);
}

bool uw_macaroon_caveat_create_scope_(UwMacaroonCaveatScopeType scope,
                                      uint8_t* buffer,
                                      size_t buffer_size,
                                      UwMacaroonCaveat* new_caveat) {
  if (!is_valid_scope_type_(scope)) {
    return false;
  }

  return create_caveat_uint_value_(kUwMacaroonCaveatTypeScope, scope, buffer,
                                   buffer_size, new_caveat);
}

bool uw_macaroon_caveat_create_expiration_absolute_(
    uint32_t expiration_time,
    uint8_t* buffer,
    size_t buffer_size,
    UwMacaroonCaveat* new_caveat) {
  return create_caveat_uint_value_(kUwMacaroonCaveatTypeExpirationAbsolute,
                                   expiration_time, buffer, buffer_size,
                                   new_caveat);
}

bool uw_macaroon_caveat_create_ttl_1_hour_(uint8_t* buffer,
                                           size_t buffer_size,
                                           UwMacaroonCaveat* new_caveat) {
  return create_caveat_no_value_(kUwMacaroonCaveatTypeTTL1Hour, buffer,
                                 buffer_size, new_caveat);
}

bool uw_macaroon_caveat_create_ttl_24_hour_(uint8_t* buffer,
                                            size_t buffer_size,
                                            UwMacaroonCaveat* new_caveat) {
  return create_caveat_no_value_(kUwMacaroonCaveatTypeTTL24Hour, buffer,
                                 buffer_size, new_caveat);
}

bool uw_macaroon_caveat_create_delegation_timestamp_(
    uint32_t timestamp,
    uint8_t* buffer,
    size_t buffer_size,
    UwMacaroonCaveat* new_caveat) {
  return create_caveat_uint_value_(kUwMacaroonCaveatTypeDelegationTimestamp,
                                   timestamp, buffer, buffer_size, new_caveat);
}

bool uw_macaroon_caveat_create_delegatee_user_(const uint8_t* id_str,
                                               size_t id_str_len,
                                               uint8_t* buffer,
                                               size_t buffer_size,
                                               UwMacaroonCaveat* new_caveat) {
  return create_caveat_bstr_value_(kUwMacaroonCaveatTypeDelegateeUser, id_str,
                                   id_str_len, buffer, buffer_size, new_caveat);
}

bool uw_macaroon_caveat_create_delegatee_app_(const uint8_t* id_str,
                                              size_t id_str_len,
                                              uint8_t* buffer,
                                              size_t buffer_size,
                                              UwMacaroonCaveat* new_caveat) {
  return create_caveat_bstr_value_(kUwMacaroonCaveatTypeDelegateeApp, id_str,
                                   id_str_len, buffer, buffer_size, new_caveat);
}

bool uw_macaroon_caveat_create_app_commands_only_(
    uint8_t* buffer,
    size_t buffer_size,
    UwMacaroonCaveat* new_caveat) {
  return create_caveat_no_value_(kUwMacaroonCaveatTypeAppCommandsOnly, buffer,
                                 buffer_size, new_caveat);
}

bool uw_macaroon_caveat_create_delegatee_service_(
    UwMacaroonCaveatCloudServiceId service_id,
    uint8_t* buffer,
    size_t buffer_size,
    UwMacaroonCaveat* new_caveat) {
  if (!is_valid_service_id_(service_id)) {
    return false;
  }

  return create_caveat_uint_value_(kUwMacaroonCaveatTypeDelegateeService,
                                   (uint32_t)service_id, buffer, buffer_size,
                                   new_caveat);
}

bool uw_macaroon_caveat_create_ble_session_id_(uint8_t* buffer,
                                               size_t buffer_size,
                                               UwMacaroonCaveat* new_caveat) {
  return create_caveat_no_value_(kUwMacaroonCaveatTypeBleSessionID, buffer,
                                 buffer_size, new_caveat);
}

bool uw_macaroon_caveat_create_lan_session_id_(const uint8_t* session_id,
                                               size_t session_id_len,
                                               uint8_t* buffer,
                                               size_t buffer_size,
                                               UwMacaroonCaveat* new_caveat) {
  return create_caveat_bstr_value_(kUwMacaroonCaveatTypeLanSessionID,
                                   session_id, session_id_len, buffer,
                                   buffer_size, new_caveat);
}

bool uw_macaroon_caveat_create_authentication_challenge_(
    uint8_t* buffer,
    size_t buffer_size,
    UwMacaroonCaveat* new_caveat) {
  return create_caveat_no_value_(kUwMacaroonCaveatTypeAuthenticationChallenge,
                                 buffer, buffer_size, new_caveat);
}

bool uw_macaroon_caveat_create_client_authorization_token_(
    const uint8_t* str,
    size_t str_len,
    uint8_t* buffer,
    size_t buffer_size,
    UwMacaroonCaveat* new_caveat) {
  if (str_len == 0) {
    return create_caveat_no_value_(
        kUwMacaroonCaveatTypeClientAuthorizationTokenV1, buffer, buffer_size,
        new_caveat);
  }
  return create_caveat_bstr_value_(
      kUwMacaroonCaveatTypeClientAuthorizationTokenV1, str, str_len, buffer,
      buffer_size, new_caveat);
}

bool uw_macaroon_caveat_create_server_authentication_token_(
    const uint8_t* str,
    size_t str_len,
    uint8_t* buffer,
    size_t buffer_size,
    UwMacaroonCaveat* new_caveat) {
  if (str_len == 0) {
    return create_caveat_no_value_(
        kUwMacaroonCaveatTypeServerAuthenticationTokenV1, buffer, buffer_size,
        new_caveat);
  }
  return create_caveat_bstr_value_(
      kUwMacaroonCaveatTypeServerAuthenticationTokenV1, str, str_len, buffer,
      buffer_size, new_caveat);
}

bool uw_macaroon_caveat_get_type_(const UwMacaroonCaveat* caveat,
                                  UwMacaroonCaveatType* type) {
  if (caveat == NULL || type == NULL) {
    return false;
  }

  uint32_t unsigned_int;
  if (!uw_macaroon_encoding_decode_uint_(caveat->bytes, caveat->num_bytes,
                                         &unsigned_int)) {
    return false;
  }

  *type = (UwMacaroonCaveatType)unsigned_int;
  return is_valid_caveat_type_(*type);
}

/* === Some internal functions defined in macaroon_caveat_internal.h === */

bool uw_macaroon_caveat_sign_(const uint8_t* key,
                              size_t key_len,
                              const UwMacaroonContext* context,
                              const UwMacaroonCaveat* caveat,
                              uint8_t* mac_tag,
                              size_t mac_tag_size) {
  if (key == NULL || key_len == 0 || context == NULL || caveat == NULL ||
      mac_tag == NULL || mac_tag_size == 0) {
    return false;
  }

  UwMacaroonCaveatType caveat_type;
  if (!uw_macaroon_caveat_get_type_(caveat, &caveat_type)) {
    return false;
  }

  // Need to encode the whole caveat as a byte string and then sign it

  // If there is no additional value from the context, just compute the HMAC on
  // the current byte string.
  uint8_t caveat_cbor_prefix[UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN] = {0};
  size_t caveat_cbor_prefix_len = 0;
  if (caveat_type != kUwMacaroonCaveatTypeBleSessionID &&
      caveat_type != kUwMacaroonCaveatTypeAuthenticationChallenge) {
    if (!uw_macaroon_encoding_encode_byte_str_len_(
            (uint32_t)(caveat->num_bytes), caveat_cbor_prefix,
            sizeof(caveat_cbor_prefix), &caveat_cbor_prefix_len)) {
      return false;
    }

    UwCryptoHmacMsg messages[] = {
        {caveat_cbor_prefix, caveat_cbor_prefix_len},
        {caveat->bytes, caveat->num_bytes},
    };

    return uw_crypto_hmac_(key, key_len, messages,
                           sizeof(messages) / sizeof(messages[0]), mac_tag,
                           mac_tag_size);
  }

  // If there is additional value from the context.
  const uint8_t* additional_value_str = NULL;
  size_t additional_value_str_len = 0;
  if (caveat_type == kUwMacaroonCaveatTypeBleSessionID) {
    if (context->ble_session_id == NULL || context->ble_session_id_len == 0) {
      return false;
    }

    additional_value_str = context->ble_session_id;
    additional_value_str_len = context->ble_session_id_len;
  } else {  // kUwMacaroonCaveatTypeAuthenticationChallenge
    if (context->auth_challenge_str == NULL ||
        context->auth_challenge_str_len == 0) {
      return false;
    }

    additional_value_str = context->auth_challenge_str;
    additional_value_str_len = context->auth_challenge_str_len;
  }

  uint8_t value_cbor_prefix[UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN] = {0};
  size_t value_cbor_prefix_len = 0;
  if (!uw_macaroon_encoding_encode_byte_str_len_(
          (uint32_t)additional_value_str_len, value_cbor_prefix,
          sizeof(value_cbor_prefix), &value_cbor_prefix_len)) {
    return false;
  }

  // The length here includes: 1. the header for the whole byte string; 2. the
  // header for the additional value part; 3. the additional value part.
  size_t total_length =
      caveat->num_bytes + value_cbor_prefix_len + additional_value_str_len;
  if (!uw_macaroon_encoding_encode_byte_str_len_(
          (uint32_t)total_length, caveat_cbor_prefix,
          sizeof(caveat_cbor_prefix), &caveat_cbor_prefix_len)) {
    return false;
  }

  UwCryptoHmacMsg messages[] = {
      {caveat_cbor_prefix, caveat_cbor_prefix_len},
      {caveat->bytes, caveat->num_bytes},
      {value_cbor_prefix, value_cbor_prefix_len},
      {additional_value_str, additional_value_str_len},
  };

  return uw_crypto_hmac_(key, key_len, messages,
                         sizeof(messages) / sizeof(messages[0]), mac_tag,
                         mac_tag_size);
}

static bool update_and_check_expiration_time(
    uint32_t current_time,
    uint32_t new_expiration_time,
    UwMacaroonValidationResult* result) {
  if (result->expiration_time > new_expiration_time) {
    result->expiration_time = new_expiration_time;
  }

  return current_time <= result->expiration_time;
}

static bool update_delegatee_list(UwMacaroonCaveatType caveat_type,
                                  const UwMacaroonCaveat* caveat,
                                  uint32_t issued_time,
                                  UwMacaroonValidationResult* result) {
  if (result->num_delegatees >= MAX_NUM_DELEGATEES || issued_time == 0) {
    return false;
  }

  UwMacaroonDelegateeType delegatee_type = kUwMacaroonDelegateeTypeNone;
  switch (caveat_type) {
    case kUwMacaroonCaveatTypeDelegateeUser:
      delegatee_type = kUwMacaroonDelegateeTypeUser;
      break;

    case kUwMacaroonCaveatTypeDelegateeApp:
      delegatee_type = kUwMacaroonDelegateeTypeApp;
      break;

    case kUwMacaroonCaveatTypeDelegateeService:
      delegatee_type = kUwMacaroonDelegateeTypeService;
      break;

    default:
      return false;
  }

  if (caveat_type != kUwMacaroonCaveatTypeDelegateeUser) {
    for (size_t i = 0; i < result->num_delegatees; i++) {
      // There must have at most one DelegateeApp or DelegateeService
      if (result->delegatees[i].type == delegatee_type) {
        return false;
      }
    }
  }

  if (caveat_type != kUwMacaroonCaveatTypeDelegateeService) {
    if (!uw_macaroon_caveat_get_value_bstr_(
            caveat, &(result->delegatees[result->num_delegatees].id),
            &(result->delegatees[result->num_delegatees].id_len))) {
      return false;
    }
    result->delegatees[result->num_delegatees].service_id =
        kUwMacaroonCaveatCloudServiceIdNotCloudRegistered;  // Default value

  } else {
    uint32_t service_id = 0;
    if (!uw_macaroon_caveat_get_value_uint_(caveat, &service_id)) {
      return false;
    }
    if (!is_valid_service_id_((UwMacaroonCaveatCloudServiceId)service_id)) {
      return false;
    }
    result->delegatees[result->num_delegatees].service_id =
        (UwMacaroonCaveatCloudServiceId)service_id;
    result->delegatees[result->num_delegatees].id = NULL;
    result->delegatees[result->num_delegatees].id_len = 0;
  }

  result->delegatees[result->num_delegatees].type = delegatee_type;
  result->delegatees[result->num_delegatees].timestamp = issued_time;
  result->num_delegatees++;
  return true;
}

bool uw_macaroon_caveat_validate_(const UwMacaroonCaveat* caveat,
                                  const UwMacaroonContext* context,
                                  UwMacaroonValidationState* state,
                                  UwMacaroonValidationResult* result) {
  if (caveat == NULL || context == NULL || state == NULL || result == NULL) {
    return false;
  }

  uint32_t expiration_time = 0;
  uint32_t issued_time = 0;
  uint32_t scope = UW_MACAROON_CAVEAT_SCOPE_LOWEST_POSSIBLE;

  UwMacaroonCaveatType caveat_type;
  if (!uw_macaroon_caveat_get_type_(caveat, &caveat_type)) {
    return false;
  }

  switch (caveat_type) {
    // The types that always validate
    case kUwMacaroonCaveatTypeClientAuthorizationTokenV1:
    case kUwMacaroonCaveatTypeServerAuthenticationTokenV1:
    case kUwMacaroonCaveatTypeNonce:
    case kUwMacaroonCaveatTypeBleSessionID:
    case kUwMacaroonCaveatTypeAuthenticationChallenge:
      return true;

    case kUwMacaroonCaveatTypeDelegationTimestamp:
      if (!uw_macaroon_caveat_get_value_uint_(caveat, &issued_time) ||
          issued_time < state->issued_time) {
        return false;
      }
      state->issued_time = issued_time;
      return true;

    case kUwMacaroonCaveatTypeTTL1Hour:
      if (state->issued_time == 0) {
        return false;
      }
      return update_and_check_expiration_time(
          context->current_time, state->issued_time + 60 * 60, result);

    case kUwMacaroonCaveatTypeTTL24Hour:
      if (state->issued_time == 0) {
        return false;
      }
      return update_and_check_expiration_time(
          context->current_time, state->issued_time + 24 * 60 * 60, result);

    // Need to create a list of delegatees
    case kUwMacaroonCaveatTypeDelegateeUser:
    case kUwMacaroonCaveatTypeDelegateeApp:
    case kUwMacaroonCaveatTypeDelegateeService:
      return update_delegatee_list(caveat_type, caveat, state->issued_time,
                                   result);

    // Time related caveats
    case kUwMacaroonCaveatTypeExpirationAbsolute:
      if (!uw_macaroon_caveat_get_value_uint_(caveat, &expiration_time)) {
        return false;
      }
      return update_and_check_expiration_time(context->current_time,
                                              expiration_time, result);

    // The caveats that update the values of the result object
    case kUwMacaroonCaveatTypeScope:
      if (!uw_macaroon_caveat_get_value_uint_(caveat, &scope) ||
          // Larger value means less priviledge
          scope > UW_MACAROON_CAVEAT_SCOPE_LOWEST_POSSIBLE) {
        return false;
      }
      if (scope > (uint32_t)(result->granted_scope)) {
        result->granted_scope = (UwMacaroonCaveatScopeType)scope;
      }
      return true;

    case kUwMacaroonCaveatTypeAppCommandsOnly:
      result->app_commands_only = true;
      return true;

    case kUwMacaroonCaveatTypeLanSessionID:
      return uw_macaroon_caveat_get_value_bstr_(
          caveat, &(result->lan_session_id), &(result->lan_session_id_len));
  }

  return false;
}

bool uw_macaroon_caveat_get_value_uint_(const UwMacaroonCaveat* caveat,
                                        uint32_t* unsigned_int) {
  if (caveat == NULL || unsigned_int == NULL) {
    return false;
  }

  UwMacaroonCaveatType type;
  if (!uw_macaroon_caveat_get_type_(caveat, &type)) {
    return false;
  }
  if (type != kUwMacaroonCaveatTypeScope &&
      type != kUwMacaroonCaveatTypeDelegateeService &&
      type != kUwMacaroonCaveatTypeExpirationAbsolute &&
      type != kUwMacaroonCaveatTypeDelegationTimestamp) {
    // Wrong type
    return false;
  }

  // Skip the portion for CBOR type
  size_t offset;
  if (!uw_macaroon_encoding_get_item_len_(caveat->bytes, caveat->num_bytes,
                                          &offset)) {
    return false;
  }

  return uw_macaroon_encoding_decode_uint_(
      caveat->bytes + offset, caveat->num_bytes - offset, unsigned_int);
}

bool uw_macaroon_caveat_get_value_bstr_(const UwMacaroonCaveat* caveat,
                                        const uint8_t** str,
                                        size_t* str_len) {
  if (caveat == NULL || str == NULL || str_len == NULL) {
    return false;
  }

  UwMacaroonCaveatType type;
  if (!uw_macaroon_caveat_get_type_(caveat, &type)) {
    return false;
  }
  if (type != kUwMacaroonCaveatTypeNonce &&
      type != kUwMacaroonCaveatTypeDelegateeUser &&
      type != kUwMacaroonCaveatTypeDelegateeApp &&
      type != kUwMacaroonCaveatTypeLanSessionID &&
      type != kUwMacaroonCaveatTypeClientAuthorizationTokenV1 &&
      type != kUwMacaroonCaveatTypeServerAuthenticationTokenV1) {
    // Wrong type
    return false;
  }

  size_t offset;
  if (!uw_macaroon_encoding_get_item_len_(caveat->bytes, caveat->num_bytes,
                                          &offset)) {
    return false;
  }

  return uw_macaroon_encoding_decode_byte_str_(
      caveat->bytes + offset, caveat->num_bytes - offset, str, str_len);
}

bool uw_macaroon_caveat_init_validation_state_(
    UwMacaroonValidationState* state) {
  if (state == NULL) {
    return false;
  }

  state->issued_time = 0;
  return true;
}
