Compare commits

...

6 Commits

6 changed files with 92 additions and 139 deletions

View File

@@ -1 +1 @@
Hello, this is a test file for encryption! Test file content for decryption

1
files/o2.txt Normal file
View File

@@ -0,0 +1 @@
Hello, this is a test file for encryption!

BIN
files/out2.otp Normal file

Binary file not shown.

Binary file not shown.

227
otp.c
View File

@@ -73,7 +73,6 @@ void simple_entropy_mix(unsigned char* urandom_buffer, size_t buffer_size,
// Directory management // Directory management
int ensure_pads_directory(void); int ensure_pads_directory(void);
int ensure_files_directory(void);
void get_pad_path(const char* chksum, char* pad_path, char* state_path); void get_pad_path(const char* chksum, char* pad_path, char* state_path);
const char* get_files_directory(void); const char* get_files_directory(void);
void get_default_file_path(const char* filename, char* result_path, size_t result_size); void get_default_file_path(const char* filename, char* result_path, size_t result_size);
@@ -83,14 +82,12 @@ uint64_t parse_size_string(const char* size_str);
char* find_pad_by_prefix(const char* prefix); char* find_pad_by_prefix(const char* prefix);
int list_available_pads(void); int list_available_pads(void);
int show_pad_info(const char* chksum); int show_pad_info(const char* chksum);
int get_user_choice(int min, int max);
void show_progress(uint64_t current, uint64_t total, time_t start_time); void show_progress(uint64_t current, uint64_t total, time_t start_time);
// File operations // File operations
int read_state_offset(const char* pad_chksum, uint64_t* offset); int read_state_offset(const char* pad_chksum, uint64_t* offset);
int write_state_offset(const char* pad_chksum, uint64_t offset); int write_state_offset(const char* pad_chksum, uint64_t offset);
int calculate_checksum(const char* filename, char* checksum_hex); int calculate_checksum(const char* filename, char* checksum_hex);
void xor_checksum_256(const unsigned char* data, size_t len, unsigned char checksum[32]);
char* custom_base64_encode(const unsigned char* input, int length); char* custom_base64_encode(const unsigned char* input, int length);
unsigned char* custom_base64_decode(const char* input, int* output_length); unsigned char* custom_base64_decode(const char* input, int* output_length);
@@ -101,7 +98,6 @@ int handle_encrypt_menu(void);
int handle_decrypt_menu(void); int handle_decrypt_menu(void);
int handle_text_encrypt(void); int handle_text_encrypt(void);
int handle_file_encrypt(void); int handle_file_encrypt(void);
int handle_smart_decrypt(void);
// Enhanced input functions // Enhanced input functions
int get_filename_with_default(const char* prompt, const char* default_path, char* result, size_t result_size); int get_filename_with_default(const char* prompt, const char* default_path, char* result, size_t result_size);
@@ -117,7 +113,7 @@ int main(int argc, char* argv[]) {
} }
int interactive_mode(void) { int interactive_mode(void) {
printf("\n\n\n\n=== OTP Cipher %s ===\n\n", get_version()); // printf("\n\n\n\n=== OTP Cipher %s ===\n\n", get_version());
while (1) { while (1) {
show_main_menu(); show_main_menu();
@@ -133,7 +129,7 @@ int interactive_mode(void) {
handle_file_encrypt(); handle_file_encrypt();
break; break;
case 'D': case 'D':
handle_smart_decrypt(); handle_decrypt_menu();
break; break;
case 'G': case 'G':
handle_generate_menu(); handle_generate_menu();
@@ -275,14 +271,16 @@ int command_line_mode(int argc, char* argv[]) {
} }
void show_main_menu(void) { void show_main_menu(void) {
printf("======================== Main Menu ========================\n");
printf("\033[4mT\033[0mext encrypt\n"); printf("\n\n\n\n=========================== Main Menu - OTP %s ===========================\n\n", get_version() );
printf("\033[4mF\033[0mile encrypt\n");
printf("\033[4mD\033[0mecrypt\n"); printf(" \033[4mT\033[0mext encrypt\n");
printf("\033[4mG\033[0menerate new pad\n"); printf(" \033[4mF\033[0mile encrypt\n");
printf("\033[4mL\033[0mist available pads\n"); printf(" \033[4mD\033[0mecrypt\n");
printf("\033[4mS\033[0mhow pad information\n"); printf(" \033[4mG\033[0menerate new pad\n");
printf("E\033[4mx\033[0mit\n"); printf(" \033[4mL\033[0mist available pads\n");
printf(" \033[4mS\033[0mhow pad information\n");
printf(" E\033[4mx\033[0mit\n");
printf("\nSelect option: "); printf("\nSelect option: ");
} }
@@ -336,8 +334,8 @@ int handle_encrypt_menu(void) {
// Ask user to choose between text and file encryption // Ask user to choose between text and file encryption
printf("\nSelect encryption type:\n"); printf("\nSelect encryption type:\n");
printf("1. Text message\n"); printf(" 1. Text message\n");
printf("2. File\n"); printf(" 2. File\n");
printf("Enter choice (1-2): "); printf("Enter choice (1-2): ");
char choice_input[10]; char choice_input[10];
@@ -351,9 +349,9 @@ int handle_encrypt_menu(void) {
if (choice == 1) { if (choice == 1) {
// Text encryption // Text encryption
printf("\nPad selection options:\n"); printf("\nPad selection options:\n");
printf("1. Select from numbered list\n"); printf(" 1. Select from numbered list\n");
printf("2. Enter checksum/prefix manually\n"); printf(" 2. Enter checksum/prefix manually\n");
printf("3. Browse pad files\n"); printf(" 3. Browse pad files\n");
printf("Enter choice (1-3): "); printf("Enter choice (1-3): ");
char pad_choice[10]; char pad_choice[10];
@@ -404,8 +402,8 @@ int handle_encrypt_menu(void) {
else if (choice == 2) { else if (choice == 2) {
// File encryption // File encryption
printf("\nFile selection options:\n"); printf("\nFile selection options:\n");
printf("1. Type file path directly\n"); printf(" 1. Type file path directly\n");
printf("2. Use file manager\n"); printf(" 2. Use file manager\n");
printf("Enter choice (1-2): "); printf("Enter choice (1-2): ");
char file_choice[10]; char file_choice[10];
@@ -453,8 +451,8 @@ int handle_encrypt_menu(void) {
// Ask for output format // Ask for output format
printf("\nSelect output format:\n"); printf("\nSelect output format:\n");
printf("1. Binary (.otp) - preserves file permissions\n"); printf(" 1. Binary (.otp) - preserves file permissions\n");
printf("2. ASCII (.otp.asc) - text-safe format\n"); printf(" 2. ASCII (.otp.asc) - text-safe format\n");
printf("Enter choice (1-2): "); printf("Enter choice (1-2): ");
char format_input[10]; char format_input[10];
@@ -496,46 +494,30 @@ int handle_encrypt_menu(void) {
} }
int handle_decrypt_menu(void) { int handle_decrypt_menu(void) {
printf("\n=== Decrypt Data ===\n"); printf("\n=== Smart Decrypt ===\n");
printf("Enter encrypted data (paste ASCII armor), file path, or press Enter to browse files:\n");
// Ask user to choose between text/message and file decryption char input_line[MAX_LINE_LENGTH];
printf("\nSelect decryption type:\n"); if (!fgets(input_line, sizeof(input_line), stdin)) {
printf("1. Text message (ASCII armored)\n");
printf("2. File (.otp or .otp.asc)\n");
printf("Enter choice (1-2): ");
char choice_input[10];
if (!fgets(choice_input, sizeof(choice_input), stdin)) {
printf("Error: Failed to read input\n"); printf("Error: Failed to read input\n");
return 1; return 1;
} }
int choice = atoi(choice_input); // Remove newline
input_line[strcspn(input_line, "\n")] = 0;
if (choice == 1) { if (strlen(input_line) == 0) {
// Text/message decryption - interactive input // Empty input - launch file manager to browse for files
return decrypt_text(NULL, NULL); // No pad selection needed - chksum comes from message char selected_file[512];
} if (launch_file_manager(get_files_directory(), selected_file, sizeof(selected_file)) != 0) {
else if (choice == 2) { printf("Error: Could not launch file manager\n");
// File decryption
printf("\nEnter encrypted file path (.otp or .otp.asc): ");
char input_file[512];
if (!fgets(input_file, sizeof(input_file), stdin)) {
printf("Error: Failed to read input\n");
return 1;
}
input_file[strcspn(input_file, "\n")] = 0;
// Check if file exists
if (access(input_file, R_OK) != 0) {
printf("Error: File '%s' not found or cannot be read\n", input_file);
return 1; return 1;
} }
// Generate smart default output filename with files directory and use enhanced input function // Generate smart default output filename with files directory and use enhanced input function
char temp_default[512]; char temp_default[512];
char default_output[512]; char default_output[512];
strncpy(temp_default, input_file, sizeof(temp_default) - 1); strncpy(temp_default, selected_file, sizeof(temp_default) - 1);
temp_default[sizeof(temp_default) - 1] = '\0'; temp_default[sizeof(temp_default) - 1] = '\0';
// Remove common encrypted extensions to get a better default // Remove common encrypted extensions to get a better default
@@ -561,13 +543,63 @@ int handle_decrypt_menu(void) {
return 1; return 1;
} }
const char* output_filename = output_file; return decrypt_file(selected_file, output_file);
}
else if (strncmp(input_line, "-----BEGIN OTP MESSAGE-----", 27) == 0) {
// Looks like ASCII armor - collect the full message
char full_message[MAX_INPUT_SIZE * 4] = {0};
strcat(full_message, input_line);
strcat(full_message, "\n");
return decrypt_file(input_file, output_filename); printf("Continue pasting the message (end with -----END OTP MESSAGE-----):\n");
char line[MAX_LINE_LENGTH];
while (fgets(line, sizeof(line), stdin)) {
strncat(full_message, line, sizeof(full_message) - strlen(full_message) - 1);
if (strstr(line, "-----END OTP MESSAGE-----")) {
break;
}
}
return decrypt_text(NULL, full_message);
} }
else { else {
printf("Invalid choice. Please enter 1 or 2.\n"); // Check if it looks like a file path
return 1; if (access(input_line, R_OK) == 0) {
// It's a valid file - decrypt it with enhanced input for output filename
char temp_default[512];
char default_output[512];
strncpy(temp_default, input_line, sizeof(temp_default) - 1);
temp_default[sizeof(temp_default) - 1] = '\0';
// Remove common encrypted extensions to get a better default
if (strstr(temp_default, ".otp.asc")) {
// Replace .otp.asc with original extension or no extension
char* ext_pos = strstr(temp_default, ".otp.asc");
*ext_pos = '\0';
} else if (strstr(temp_default, ".otp")) {
// Replace .otp with original extension or no extension
char* ext_pos = strstr(temp_default, ".otp");
*ext_pos = '\0';
} else {
// No recognized encrypted extension, add .decrypted suffix
strncat(temp_default, ".decrypted", sizeof(temp_default) - strlen(temp_default) - 1);
}
// Apply files directory default path
get_default_file_path(temp_default, default_output, sizeof(default_output));
char output_file[512];
if (get_filename_with_default("Output filename:", default_output, output_file, sizeof(output_file)) != 0) {
printf("Error: Failed to read input\n");
return 1;
}
return decrypt_file(input_line, output_file);
} else {
printf("Input not recognized as ASCII armor or valid file path.\n");
return 1;
}
} }
} }
@@ -817,20 +849,6 @@ int show_pad_info(const char* chksum) {
return 0; return 0;
} }
int get_user_choice(int min, int max) {
char input[64];
int choice;
while (1) {
if (fgets(input, sizeof(input), stdin)) {
choice = atoi(input);
if (choice >= min && choice <= max) {
return choice;
}
}
printf("Please enter a number between %d and %d: ", min, max);
}
}
void show_progress(uint64_t current, uint64_t total, time_t start_time) { void show_progress(uint64_t current, uint64_t total, time_t start_time) {
time_t now = time(NULL); time_t now = time(NULL);
@@ -1196,8 +1214,8 @@ int encrypt_text(const char* pad_identifier, const char* input_text) {
} else { } else {
// Get input text from user (interactive mode) // Get input text from user (interactive mode)
printf("\nText input options:\n"); printf("\nText input options:\n");
printf("1. Type text directly\n"); printf(" 1. Type text directly\n");
printf("2. Use text editor\n"); printf(" 2. Use text editor\n");
printf("Enter choice (1-2): "); printf("Enter choice (1-2): ");
char input_choice[10]; char input_choice[10];
@@ -2247,15 +2265,6 @@ int ensure_pads_directory(void) {
return 0; return 0;
} }
int ensure_files_directory(void) {
struct stat st = {0};
if (stat(FILES_DIR, &st) == -1) {
if (mkdir(FILES_DIR, 0755) != 0) {
return 1;
}
}
return 0;
}
const char* get_files_directory(void) { const char* get_files_directory(void) {
struct stat st = {0}; struct stat st = {0};
@@ -2285,14 +2294,6 @@ void get_pad_path(const char* chksum, char* pad_path, char* state_path) {
} }
// Custom XOR checksum function
void xor_checksum_256(const unsigned char* data, size_t len, unsigned char checksum[32]) {
memset(checksum, 0, 32);
for (size_t i = 0; i < len; i++) {
unsigned char bucket = i % 32;
checksum[bucket] ^= data[i] ^ ((i >> 8) & 0xFF) ^ ((i >> 16) & 0xFF) ^ ((i >> 24) & 0xFF);
}
}
// Custom base64 encode function // Custom base64 encode function
char* custom_base64_encode(const unsigned char* input, int length) { char* custom_base64_encode(const unsigned char* input, int length) {
@@ -2841,56 +2842,6 @@ int handle_file_encrypt(void) {
return encrypt_file(pad_input, input_file, output_filename, ascii_armor); return encrypt_file(pad_input, input_file, output_filename, ascii_armor);
} }
int handle_smart_decrypt(void) {
printf("\n=== Smart Decrypt ===\n");
printf("Enter encrypted data (paste ASCII armor) or press Enter to browse files:\n");
char input_line[MAX_LINE_LENGTH];
if (!fgets(input_line, sizeof(input_line), stdin)) {
printf("Error: Failed to read input\n");
return 1;
}
// Remove newline
input_line[strcspn(input_line, "\n")] = 0;
if (strlen(input_line) == 0) {
// Empty input - launch file manager
char selected_file[512];
if (launch_file_manager(".", selected_file, sizeof(selected_file)) != 0) {
printf("Error: Could not launch file manager\n");
return 1;
}
// Decrypt selected file
return decrypt_file(selected_file, NULL);
} else if (strncmp(input_line, "-----BEGIN OTP MESSAGE-----", 27) == 0) {
// Looks like ASCII armor - collect the full message
char full_message[MAX_INPUT_SIZE * 4] = {0};
strcat(full_message, input_line);
strcat(full_message, "\n");
printf("Continue pasting the message (end with -----END OTP MESSAGE-----):\n");
char line[MAX_LINE_LENGTH];
while (fgets(line, sizeof(line), stdin)) {
strncat(full_message, line, sizeof(full_message) - strlen(full_message) - 1);
if (strstr(line, "-----END OTP MESSAGE-----")) {
break;
}
}
return decrypt_text(NULL, full_message);
} else {
// Check if it looks like a file path
if (access(input_line, R_OK) == 0) {
return decrypt_file(input_line, NULL);
} else {
printf("Input not recognized as ASCII armor or valid file path.\n");
return 1;
}
}
}
void print_usage(const char* program_name) { void print_usage(const char* program_name) {
printf("OTP Cipher - One Time Pad Implementation %s\n", get_version()); printf("OTP Cipher - One Time Pad Implementation %s\n", get_version());

1
test_files_dir.txt Normal file
View File

@@ -0,0 +1 @@
Testing updated files directory functionality