// 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) ||
      !is_valid_caveat_type_(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 addtional 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->weave_app_restricted = 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;
}
