示例#1
0
// see core.h
kssl_error_code kssl_error(DWORD id,
                           BYTE error,
                           BYTE **response,
                           int *response_len) {
  kssl_header e;
  int offset = 0;
  int size = KSSL_HEADER_SIZE + KSSL_OPCODE_ITEM_SIZE + KSSL_ERROR_ITEM_SIZE;
  BYTE *resp;

  // The operation will always be padded to KSSL_PAD_TO +
  // KSSL_ITEM_HEADER_SIZE bytes

  int padding_size = 0;
  if (size < KSSL_PAD_TO) {
    padding_size = KSSL_PAD_TO - size;
  }

  if (response == NULL || response_len == NULL) {
    return KSSL_ERROR_INTERNAL;
  }

  size += padding_size + KSSL_ITEM_HEADER_SIZE;

  // The memory is calloced here to ensure that it is all zero. This is
  // important because the padding added below is done by just adding a
  // KSSL_ITEM at the end of the message stating that it has N bytes of
  // padding.
  
  resp = (BYTE *)calloc(size, 1);
  if (resp == NULL) {
    return KSSL_ERROR_INTERNAL;
  }

  e.version_maj = KSSL_VERSION_MAJ;
  e.version_min = KSSL_VERSION_MIN;
  e.length  = size - KSSL_HEADER_SIZE;
  e.id      = id;

  flatten_header(&e, resp, &offset);
  flatten_item_byte(KSSL_TAG_OPCODE, KSSL_OP_ERROR, resp, &offset);
  flatten_item_byte(KSSL_TAG_PAYLOAD, error, resp, &offset);
  add_padding(padding_size, resp, &offset);

  *response = resp;
  *response_len = size;

  return KSSL_ERROR_NONE;
}
示例#2
0
// flatten_operation: serialize a kssl_operation
kssl_error_code flatten_operation(kssl_header *header,
                                  kssl_operation *operation,
                                  BYTE **out_operation,
                                  int *length) {
    int local_req_len;
    BYTE *local_req;
    int offset = 0;
    if (header == NULL        ||
            operation == NULL     ||
            out_operation == NULL ||
            length == NULL) {
        return KSSL_ERROR_INTERNAL;
    }

    // Allocate response (header + opcode + response)
    local_req_len = KSSL_HEADER_SIZE;

    if (operation->is_opcode_set) {
        local_req_len += KSSL_OPCODE_ITEM_SIZE;
    }
    if (operation->is_payload_set) {
        local_req_len += KSSL_ITEM_HEADER_SIZE + operation->payload_len;
    }
    if (operation->is_digest_set) {
        local_req_len += KSSL_ITEM_HEADER_SIZE + KSSL_DIGEST_SIZE;
    }
    if (operation->is_ip_set) {
        local_req_len += KSSL_ITEM_HEADER_SIZE + operation->ip_len;
    }

    // The operation will always be padded to KSSL_PAD_TO +
    // KSSL_ITEM_HEADER_SIZE bytes

    int padding_size = 0;
    if (local_req_len < KSSL_PAD_TO) {
        padding_size = KSSL_PAD_TO - local_req_len;
    }

    local_req_len += KSSL_ITEM_HEADER_SIZE + padding_size;

    // The memory is calloced here to ensure that it is all zero. This is
    // important because the padding added below is done by just adding a
    // KSSL_ITEM at the end of the message stating that it has N bytes of
    // padding.

    local_req = (BYTE *)calloc(local_req_len, 1);
    if (local_req == NULL) {
        return KSSL_ERROR_INTERNAL;
    }

    // Override header length
    header->length = local_req_len - KSSL_HEADER_SIZE;

    flatten_header(header, local_req, &offset);
    if (operation->is_opcode_set) {
        flatten_item_byte(KSSL_TAG_OPCODE, operation->opcode, local_req, &offset);
    }
    if (operation->is_payload_set) {
        flatten_item(KSSL_TAG_PAYLOAD, operation->payload, operation->payload_len,
                     local_req, &offset);
    }
    if (operation->is_digest_set) {
        flatten_item(KSSL_TAG_DIGEST, operation->digest, KSSL_DIGEST_SIZE,
                     local_req, &offset);
    }
    if (operation->is_ip_set) {
        flatten_item(KSSL_TAG_CLIENT_IP, operation->ip, operation->ip_len,
                     local_req, &offset);
    }

    add_padding(padding_size, local_req, &offset);

    *out_operation = local_req;
    *length = local_req_len;

    return KSSL_ERROR_NONE;
}