Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #22

Merged
merged 3 commits into from
Nov 7, 2023
Merged

Dev #22

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 86 additions & 25 deletions src/arg_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
This header describes functions and structs for argument parsing
*/

/*! \file arg_parser.h
* \brief This header describes functions and structs for argument parsing
*/

#ifndef ARG_PARSER_H
#define ARG_PARSER_H

Expand All @@ -22,63 +26,120 @@
#include "functional.h"
#include "string-hashtable/hash_table.h"

/*! \enum arg_errors
* \brief
*/
enum arg_errors
{
arg_success,
arg_invalid_arg,
arg_init_error,
arg_alloc_error,
arg_no_entity,
arg_unknown
arg_success, //!< Function completed successfully.
arg_invalid_arg, //!< Function got an invalid argument (e.g. NULL pointer).
arg_init_error, //!< Parser or argument cannot be initialized.
arg_alloc_error, //!< Failed allocation inside a function.
arg_no_entity, //!< Key does not exist.
arg_unknown //!< Unknown argument.
};

// Defines types of arguments
/*! \enum arg_type
* \brief Defines types of arguments
*/
typedef enum
{
arg_flag, // Stores as value count of arguments
arg_parameter, // Stores next argument as a value
arg_flag, //!< Stores as value count of arguments.
arg_parameter, //!< Stores next argument as a value.
} arg_type;

/*! \struct argument_t
* \brief Defines structure for argument.
*/
typedef struct
{
arg_type type;
const char* key;
const char* description;
const char* value;
arg_type type; //!< Argument type flag/parameter.
const char* key; //!< Key associated with arguemt.
const char* description; //!< Description of given argument.
const char* value; //!< Container for specified value if type is parameter and count if flag.
} argument_t;

/*! \struct arg_parser_t
* \brief Describes argument parser.
*/
typedef struct
{
size_t amount;
hashtable_t* arguments;
const char* prog_info;
size_t amount; //!< Stores amount of specified arguments.
hashtable_t* arguments; //!< Hashtable for arguments.
const char* prog_info; //!< Info of program.
} arg_parser_t;

// Constructs an argument parser with total amount of arguments
/*! \fn int arg_parser_init(size_t args_amount, const char* prog_info, arg_parser_t* parser_ptr)
* \brief Constructs an argument parser with total amount of arguments.
* \param[in] args_amount Total amount of arguments that were given.
* \param[in] prog_info Description of the app.
* \param[out] parser_ptr Pointer to argument parser uninitialized structure.
* \return value of \a arg_errors enumeration (0 or \a arg_success on success).
*/
int arg_parser_init(size_t args_amount, const char* prog_info, arg_parser_t* parser_ptr);

// Deletes the arguments parser
/*! \fn int arg_parser_delete(arg_parser_t* parser_ptr)
* \brief Deletes the arguments parser.
* \param[in] parser_ptr Total amount of arguments that were given.
* \return value of \a arg_errors enumeration (0 or \a arg_success on success).
*/
int arg_parser_delete(arg_parser_t* parser_ptr);

// Constructs an argument_t pointer with specified parameters
/*! \fn const argument_t* arg_init_arg(arg_type type, const char* key, const char* description, void* value)
* \brief Constructs an argument_t pointer with specified parameters.
* \param[in] type Argument type flag/parameter.
* \param[in] key Key associated with arguemt.
* \param[in] description Description of given argument.
* \param[in] value Default argument's value.
* \return initialized argument structure or NULL on error.
*/
const argument_t* arg_init_arg(arg_type type, const char* key, const char* description, void* value);

// Adds specified arguments pointer to parser
/*! \fn int arg_add(const argument_t* arg, arg_parser_t* parser_ptr)
* \brief Adds single specified arguments pointer to parser.
* \param[in] arg pointer to argument structure.
* \param[in] parser_ptr pointer to parser structure.
* \return value of \a arg_errors enumeration (0 or \a arg_success on success).
*/
int arg_add(const argument_t* arg, arg_parser_t* parser_ptr);

// Adds specified amount of arguments to parser
/*! \fn int arg_add(const argument_t* arg, arg_parser_t* parser_ptr)
* \brief Adds multiple specified arguments pointer to parser.
* \param[in] args_amount amount of specified arguments.
* \param[in] parser_ptr pointer to parser structure.
* \param[in] ... variadic list of arguments.
* \return value of \a arg_errors enumeration (0 or \a arg_success on success).
*/
int arg_add_amount(size_t args_amount, arg_parser_t* parser_ptr, ...);

// Retrieves argument or NULL if does not exist
/*! \fn argument_t* arg_get(const char* key, arg_parser_t* parser_ptr)
* \brief Returns pointer argument struct or NULL if does not exist.
* \param[in] key Key associated with arguemt.
* \param[in] parser_ptr pointer to parser structure.
* \return pointer to argument struct or NULL if does not exists.
*/
argument_t* arg_get(const char* key, arg_parser_t* parser_ptr);

// Parses arguments given to main function
/*! \fn int arg_parse(int argc, const char** argv, arg_parser_t* parser_ptr)
* \brief Parses arguments given to main function.
* \param[in] argc arguments amount including first arguments.
* \param[in] argv arguments strings array.
* \param[in] parser_ptr pointer to parser structure.
* \return value of \a arg_errors enumeration (0 or \a arg_success on success).
*/
int arg_parse(int argc, const char** argv, arg_parser_t* parser_ptr);

// Shows help message/manual
/*! \fn void arg_show_help(arg_parser_t* parser_ptr)
* \brief Shows help message/manual.
* \param[in] parser_ptr pointer to parser structure.
*/
void arg_show_help(arg_parser_t* parser_ptr);

// Deletes argument pointer
/*! \fn int arg_delete(argument_t* arg)
* \brief Deletes argument pointer
* \param[in] parser_ptr pointer to argument structure.
* \return value of \a arg_errors enumeration (0 or \a arg_success on success).
*/
int arg_delete(argument_t* arg);

#endif
24 changes: 4 additions & 20 deletions src/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,7 @@ static int openssl_evp_wrapper(
uint8_t* get_md5(const char* data, size_t data_size)
{
// Validating parameters
if (data == NULL || data_size == 0)
{
errno = EINVAL;
return NULL;
}
validate_parameters(data == NULL || data_size == 0, NULL);

uint8_t* hash = malloc_check(hash, 16, NULL);

Expand All @@ -176,11 +172,7 @@ uint8_t* get_md5(const char* data, size_t data_size)
int rc4_encrypt(const uint8_t* data, int data_len, uint8_t* key, uint8_t* enc_data)
{
// Validating parameters
if (data == NULL || data_len == 0 || key == NULL || enc_data == NULL)
{
errno = EINVAL;
return NULL;
}
validate_parameters(data == NULL || data_len == 0 || key == NULL || enc_data == NULL, -1);

RC4_KEY rc4_key;
RC4_set_key(&rc4_key, 16, key);
Expand All @@ -197,11 +189,7 @@ int aes_128_cbc_decrypt(
)
{
// Validating parameters
if (enc_data == NULL || data_len == 0 || key == NULL || iv == NULL || dec_data == NULL)
{
errno = EINVAL;
return NULL;
}
validate_parameters(enc_data == NULL || data_len == 0 || key == NULL || iv == NULL || dec_data == NULL, -1);

AES_KEY dec_key;
AES_set_decrypt_key(key, 128, &dec_key);
Expand All @@ -212,11 +200,7 @@ int aes_128_cbc_decrypt(
int des_ecb_decrypt(const uint8_t* enc_data, int data_len, const uint8_t* key, uint8_t* dec_data)
{
// Validating parameters
if (enc_data == NULL || data_len == 0 || key == NULL || dec_data == NULL)
{
errno = EINVAL;
return NULL;
}
validate_parameters(enc_data == NULL || data_len == 0 || key == NULL || dec_data == NULL, -1);

DES_cblock key_block;
memcpy(&key_block, key, sizeof(uint64_t));
Expand Down
53 changes: 49 additions & 4 deletions src/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@

----

This header describes an API for openssl 3.0.11 cryptographic functions
This header describes an API for openssl 3.0.11 and openssl 1.1.1 cryptographic functions
*/

/*! \file crypto.h
* \brief This header describes an API for openssl 3.0.11 and openssl 1.1.1 cryptographic functions
*/

#ifndef CRYPTO_H
#define CRYPTO_H

Expand All @@ -39,13 +43,33 @@

#include "functional.h"

// Returns md5 hash of specified data
/*! \fn uint8_t* get_md5(const char* data, size_t data_size)
* \brief Returns md5 hash of specified data.
* \param[in] data input array of bytes.
* \param[in] data_size length of data to hash.
* \return calculated MD5 bytes array.
*/
uint8_t* get_md5(const char* data, size_t data_size);

// Encrypts RC4
/*! \fn int rc4_encrypt(const uint8_t* data, int data_len, uint8_t* key, uint8_t* enc_data)
* \brief Encrypts data using RC4.
* \param[in] data input array of bytes.
* \param[in] data_len length of data to hash.
* \param[in] key key used to encrypt.
* \param[out] enc_data output encrypted data.
* \return \a data_len on success or negative number correlated to step on error.
*/
int rc4_encrypt(const uint8_t* data, int data_len, uint8_t* key, uint8_t* enc_data);

// Decryps AES 128 CBC
/*! \fn int aes_128_cbc_decrypt(const uint8_t* enc_data, int data_len, const uint8_t* key, const uint8_t* iv, uint8_t* dec_data)
* \brief Decryps data using AES-128-CBC.
* \param[in] enc_data input array of bytes.
* \param[in] data_len length of data to hash.
* \param[in] key key used to encrypt.
* \param[in] iv input vector.
* \param[out] dec_data output encrypted data.
* \return \a data_len on success or negative number correlated to step on error.
*/
int aes_128_cbc_decrypt(
const uint8_t* enc_data,
int data_len,
Expand All @@ -54,9 +78,30 @@ int aes_128_cbc_decrypt(
uint8_t* dec_data
);

/*! \fn int des_ecb_decrypt(const uint8_t* enc_data, int data_len, const uint8_t* key, uint8_t* dec_data)
* \brief Decryps data using DES-ECB.
* \param[in] enc_data input array of bytes.
* \param[in] data_len length of data to hash.
* \param[in] key key used to encrypt.
* \param[out] dec_data output encrypted data.
* \return \a data_len on success or negative number correlated to step on error.
*/
int des_ecb_decrypt(const uint8_t* enc_data, int data_len, const uint8_t* key, uint8_t* dec_data);

#if (OPENSSL_VERSION_MAJOR >= 3)

/*! \fn static int openssl_evp_wrapper(const uint8_t* in_data, int data_len, const uint8_t* key, const uint8_t* iv, uint8_t* out_data, int encrypt_mode, int padding, const EVP_CIPHER* cipher)
* \brief Decryps/encrypts data using specified cipher.
* \param[in] in_data input array of bytes.
* \param[in] data_len length of data to hash.
* \param[in] key key used to encrypt.
* \param[in] iv input vector.
* \param[out] out_data output encrypted data.
* \param[in] encrypt_mode boolean value 1 for encryption and 0 decryption.
* \param[in] padding data padding specific for given cipher.
* \param[in] cipher evp cipher structure.
* \return \a data_len on success or negative number correlated to step on error.
*/
static int openssl_evp_wrapper(
const uint8_t* in_data,
int data_len,
Expand Down
32 changes: 6 additions & 26 deletions src/dump_bootkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@
int dump_bootkey(FILE* sys_hive, char16_t* out_bootkey)
{
// Validating parameters
if (sys_hive == NULL || out_bootkey == NULL)
{
errno = EINVAL;
return -1;
}
validate_parameters(sys_hive == NULL || out_bootkey == NULL, -1);

// Allocating hive header
hive_header_t* hive_header_ptr = malloc_check(hive_header_ptr, sizeof(hive_header_t), -2);
Expand Down Expand Up @@ -123,11 +119,7 @@ int dump_bootkey(FILE* sys_hive, char16_t* out_bootkey)
int get_hashed_bootkey(const char16_t* u16_bootkey, FILE* sam_hive, uint8_t* hashed_bootkey)
{
// Validating parameters
if (u16_bootkey == NULL || hashed_bootkey == NULL)
{
errno = EINVAL;
return -1;
}
validate_parameters(u16_bootkey == NULL || hashed_bootkey == NULL, -1);

// Decoding hex string to raw values
uint8_t* raw_bootkey = bootkey_from_u16(u16_bootkey);
Expand Down Expand Up @@ -264,14 +256,10 @@ int get_hashed_bootkey(const char16_t* u16_bootkey, FILE* sam_hive, uint8_t* has
return 0;
}

uint8_t* bootkey_from_u16(const char16_t* wstr)
static uint8_t* bootkey_from_u16(const char16_t* wstr)
{
// Validating parameter
if (wstr == NULL)
{
errno = EINVAL;
return NULL;
}
validate_parameters(wstr == NULL, NULL);

// Checking a bootkey length
size_t wstr_length = 0;
Expand Down Expand Up @@ -305,11 +293,7 @@ uint8_t* bootkey_from_u16(const char16_t* wstr)
int ntlmv1_hash_bootkey(uint8_t* permutated_bootkey, uint8_t* f_value, uint8_t* hashed_bootkey)
{
// Validating parameters
if (permutated_bootkey == NULL || f_value == NULL || hashed_bootkey == NULL)
{
errno = EINVAL;
return -1;
}
validate_parameters(permutated_bootkey == NULL || f_value == NULL || hashed_bootkey == NULL, -1);

// Constants for hashed bootkey construction
const char* aqwerty = "!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%\0";
Expand Down Expand Up @@ -352,11 +336,7 @@ int ntlmv1_hash_bootkey(uint8_t* permutated_bootkey, uint8_t* f_value, uint8_t*
int ntlmv2_hash_bootkey(uint8_t* permutated_bootkey, uint8_t* f_value, uint8_t* hashed_bootkey)
{
// Validating parameters
if (permutated_bootkey == NULL || f_value == NULL || hashed_bootkey == NULL)
{
errno = EINVAL;
return -1;
}
validate_parameters(permutated_bootkey == NULL || f_value == NULL || hashed_bootkey == NULL, -1);

// Allocating space for IV taken from F[0x78:0x88] and encrypted bootkey taken from F[0x88:0xA8]
uint8_t* iv = malloc_check(iv, AES_BLOCK_SIZE, -3);
Expand Down
Loading