// 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; }
// 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; }