// 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"

// For security sanity checks
#define UW_MACAROON_CAVEAT_SCOPE_LOWEST_POSSIBLE 127

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 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 create_caveat_no_value_(UwMacaroonCaveatType type,
                                    uint8_t* buffer,
                                    size_t buffer_size,
                                    UwMacaroonCaveat* new_caveat) {
  // (buffer_size == 0 || get_buffer_size_() > 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:
      return UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;

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

    // Byte strings
    case kUwMacaroonCaveatTypeNonce:
    case kUwMacaroonCaveatTypeDelegateeUser:
    case kUwMacaroonCaveatTypeDelegateeApp:
    case kUwMacaroonCaveatTypeDelegateeService:
    case kUwMacaroonCaveatTypeLanSessionID:
    case kUwMacaroonCaveatTypeClientAuthorizationTokenV1:
    case kUwMacaroonCaveatTypeServerAuthenticationTokenV1:
      return str_len + 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_(
    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_(kUwMacaroonCaveatTypeDelegateeService,
                                   id_str, id_str_len, 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_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 bstr_cbor_prefix[UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN] = {0};
  size_t bstr_cbor_prefix_len = 0;
  if (caveat_type != kUwMacaroonCaveatTypeBleSessionID) {
    if (!uw_macaroon_encoding_encode_byte_str_len_(
            (uint32_t)(caveat->num_bytes), bstr_cbor_prefix,
            sizeof(bstr_cbor_prefix), &bstr_cbor_prefix_len)) {
      return false;
    }

    UwCryptoHmacMsg messages[] = {
        {bstr_cbor_prefix, bstr_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.
  if (context->ble_session_id == NULL || context->ble_session_id_len == 0) {
    return false;
  }

  // The length here includes the length of the BLE session ID string.
  if (!uw_macaroon_encoding_encode_byte_str_len_(
          (uint32_t)(context->ble_session_id_len + caveat->num_bytes),
          bstr_cbor_prefix, sizeof(bstr_cbor_prefix), &bstr_cbor_prefix_len)) {
    return false;
  }

  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)(context->ble_session_id_len), value_cbor_prefix,
          sizeof(value_cbor_prefix), &value_cbor_prefix_len)) {
    return false;
  }

  UwCryptoHmacMsg messages[] = {
      {bstr_cbor_prefix, bstr_cbor_prefix_len},
      {caveat->bytes, caveat->num_bytes},
      {value_cbor_prefix, value_cbor_prefix_len},
      {context->ble_session_id, context->ble_session_id_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,
                                  UwMacaroonValidationResult* result) {
  if (result->num_delegatees >= MAX_NUM_DELEGATEES) {
    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 (!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].type = delegatee_type;
  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:
      return true;

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

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

    case kUwMacaroonCaveatTypeTTL24Hour:
      if (!(state->has_issued_time)) {
        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, 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 != 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 != kUwMacaroonCaveatTypeDelegateeService &&
      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->has_issued_time = false;
  state->issued_time = 0;
  return true;
}
