<commit_before>/*
 * Molch, an implementation of the axolotl ratchet based on libsodium
 *
 * ISC License
 *
 * Copyright (C) 2015-2016 1984not Security GmbH
 * Author: <NAME> (FSMaxB)
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <string.h>

#include "constants.h"
#include "header-and-message-keystore.h"

static const time_t EXPIRATION_TIME = 3600 * 24 * 31; //one month

//create new keystore
void header_and_message_keystore_init(header_and_message_keystore * const keystore) {
	keystore->length = 0;
	keystore->head = NULL;
	keystore->tail = NULL;
}

/*
 * create an empty header_and_message_keystore_node and set up all the pointers.
 */
header_and_message_keystore_node *create_node() {
	header_and_message_keystore_node *node = sodium_malloc(sizeof(header_and_message_keystore_node));
	if (node == NULL) {
		return NULL;
	}

	//initialise buffers with storage arrays
	buffer_init_with_pointer(node->message_key, node->message_key_storage, MESSAGE_KEY_SIZE, 0);
	buffer_init_with_pointer(node->header_key, node->header_key_storage, HEADER_KEY_SIZE, 0);

	return node;
}

/*
 * add a new header_and_message_key_node to a keystore
 */
void add_node(header_and_message_keystore * const keystore, header_and_message_keystore_node * const node) {
	if (node == NULL) {
		return;
	}

	if (keystore->length == 0) { //first node in the list
		node->previous = NULL;
		node->next = NULL;
		keystore->head = node;
		keystore->tail = node;

		//update length
		keystore->length++;
		return;
	}

	//add the new node to the tail of the list
	keystore->tail->next = node;
	node->previous = keystore->tail;
	node->next = NULL;
	keystore->tail = node;

	//update length
	keystore->length++;
}

//add a message key to the keystore
//NOTE: The entire keys are copied, not only the pointer
return_status header_and_message_keystore_add(
		header_and_message_keystore *keystore,
		const buffer_t * const message_key,
		const buffer_t * const header_key) {
	return_status status = return_status_init();

	//check buffer sizes
	if ((message_key->content_length != MESSAGE_KEY_SIZE)
			|| (header_key->content_length != HEADER_KEY_SIZE)) {
		throw(INVALID_INPUT, "Invalid input to header_and_message_keystore_add.");
	}

	header_and_message_keystore_node *new_node = create_node();
	if (new_node == NULL) {
		throw(CREATION_ERROR, "Failed to create node.");
	}

	int status_int = 0;
	//set keys and expiration date
	new_node->expiration_date = time(NULL) + EXPIRATION_TIME;
	status_int = buffer_clone(new_node->message_key, message_key);
	if (status_int != 0) {
		sodium_free_and_null_if_valid(new_node);
		throw(BUFFER_ERROR, "Failed to copy message key.");
	}
	status_int = buffer_clone(new_node->header_key, header_key);
	if (status_int != 0) {
		sodium_free_and_null_if_valid(new_node);
		throw(BUFFER_ERROR, "Failed to copy header key.");
	}

	add_node(keystore, new_node);

cleanup:
	return status;
}

//remove a set of header and message keys from the keystore
void header_and_message_keystore_remove(header_and_message_keystore *keystore, header_and_message_keystore_node *node) {
	if (node == NULL) {
		return;<commit_msg>header_and_message_keystore: Split Adding and populating nodes<commit_after>/*
 * Molch, an implementation of the axolotl ratchet based on libsodium
 *
 * ISC License
 *
 * Copyright (C) 2015-2016 1984not Security GmbH
 * Author: <NAME> (FSMaxB)
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <string.h>

#include "constants.h"
#include "header-and-message-keystore.h"

static const time_t EXPIRATION_TIME = 3600 * 24 * 31; //one month

//create new keystore
void header_and_message_keystore_init(header_and_message_keystore * const keystore) {
	keystore->length = 0;
	keystore->head = NULL;
	keystore->tail = NULL;
}

/*
 * create an empty header_and_message_keystore_node and set up all the pointers.
 */
header_and_message_keystore_node *create_node() {
	header_and_message_keystore_node *node = sodium_malloc(sizeof(header_and_message_keystore_node));
	if (node == NULL) {
		return NULL;
	}

	//initialise buffers with storage arrays
	buffer_init_with_pointer(node->message_key, node->message_key_storage, MESSAGE_KEY_SIZE, 0);
	buffer_init_with_pointer(node->header_key, node->header_key_storage, HEADER_KEY_SIZE, 0);

	return node;
}

/*
 * add a new header_and_message_key_node to a keystore
 */
void add_node(header_and_message_keystore * const keystore, header_and_message_keystore_node * const node) {
	if (node == NULL) {
		return;
	}

	if (keystore->length == 0) { //first node in the list
		node->previous = NULL;
		node->next = NULL;
		keystore->head = node;
		keystore->tail = node;

		//update length
		keystore->length++;
		return;
	}

	//add the new node to the tail of the list
	keystore->tail->next = node;
	node->previous = keystore->tail;
	node->next = NULL;
	keystore->tail = node;

	//update length
	keystore->length++;
}

return_status create_and_populate_node(
		header_and_message_keystore_node ** const new_node,
		const time_t expiration_date,
		const buffer_t * const header_key,
		const buffer_t * const message_key) __attribute__((warn_unused_result));
return_status create_and_populate_node(
		header_and_message_keystore_node ** const new_node,
		const time_t expiration_date,
		const buffer_t * const header_key,
		const buffer_t * const message_key) {
	return_status status = return_status_init();

	//check buffer sizes
	if ((message_key->content_length != MESSAGE_KEY_SIZE)
			|| (header_key->content_length != HEADER_KEY_SIZE)) {
		throw(INVALID_INPUT, "Invalid input to populate_node.");
	}

	*new_node = create_node();
	throw_on_failed_alloc(*new_node);

	int status_int = 0;
	//set keys and expiration date
	(*new_node)->expiration_date = expiration_date;
	status_int = buffer_clone((*new_node)->message_key, message_key);
	if (status_int != 0) {
		throw(BUFFER_ERROR, "Failed to copy message key.");
	}
	status_int = buffer_clone((*new_node)->header_key, header_key);
	if (status_int != 0) {
		throw(BUFFER_ERROR, "Failed to copy header key.");
	}

cleanup:
	on_error(
		if (new_node != NULL) {
			sodium_free_and_null_if_valid(*new_node);
		}
	)

	return status;
	}

//add a message key to the keystore
//NOTE: The entire keys are copied, not only the pointer
return_status header_and_message_keystore_add(
		header_and_message_keystore *keystore,
		const buffer_t * const message_key,
		const buffer_t * const header_key) {
	return_status status = return_status_init();

	header_and_message_keystore_node *new_node = NULL;

	time_t expiration_date = time(NULL) + EXPIRATION_TIME;

	status = create_and_populate_node(&new_node, expiration_date, header_key, message_key);
	throw_on_error(INIT_ERROR, "Failed to populate node.")

	add_node(keystore, new_node);

cleanup:
	on_error(
		sodium_free_and_null_if_valid(new_node);
	)
	return status;
}

//remove a set of header and message keys from the keystore
void header_and_message_keystore_remove(header_and_message_keystore *keystore, header_and_message_keystore_node *node) {
	if (node == NULL) {
		return;
{'fraction_non_alphanumeric': 0.09341573567863086, 'fraction_numerical': 0.0064178749702876155, 'mean_word_length': 4.963855421686747, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3725431', 'n_tokens_mistral': 2975, 'n_tokens_neox': 2709, 'n_words': 802}