Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2c864f1feb | |||
| ae0afcfffd |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
otp
|
||||||
pads/
|
pads/
|
||||||
Gemini.md
|
Gemini.md
|
||||||
|
|
||||||
|
|||||||
13
build.sh
13
build.sh
@@ -98,6 +98,19 @@ increment_version() {
|
|||||||
# Create new git tag
|
# Create new git tag
|
||||||
if git tag "$NEW_VERSION" 2>/dev/null; then
|
if git tag "$NEW_VERSION" 2>/dev/null; then
|
||||||
print_success "Created new version tag: $NEW_VERSION"
|
print_success "Created new version tag: $NEW_VERSION"
|
||||||
|
|
||||||
|
# Push changes and tags to remote repository
|
||||||
|
if git push ssh://ubuntu@laantungir.net:/home/ubuntu/git_repos/otp 2>/dev/null; then
|
||||||
|
print_success "Pushed changes to remote repository"
|
||||||
|
else
|
||||||
|
print_warning "Failed to push changes to remote repository"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if git push ssh://ubuntu@laantungir.net:/home/ubuntu/git_repos/otp --tags 2>/dev/null; then
|
||||||
|
print_success "Pushed tags to remote repository"
|
||||||
|
else
|
||||||
|
print_warning "Failed to push tags to remote repository"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
print_warning "Tag $NEW_VERSION already exists - using existing version"
|
print_warning "Tag $NEW_VERSION already exists - using existing version"
|
||||||
NEW_VERSION=$LATEST_TAG
|
NEW_VERSION=$LATEST_TAG
|
||||||
|
|||||||
187
otp.c
187
otp.c
@@ -50,8 +50,8 @@ int command_line_mode(int argc, char* argv[]);
|
|||||||
// Core functions
|
// Core functions
|
||||||
int generate_pad(uint64_t size_bytes, int show_progress);
|
int generate_pad(uint64_t size_bytes, int show_progress);
|
||||||
int generate_pad_with_entropy(uint64_t size_bytes, int show_progress, int use_keyboard_entropy);
|
int generate_pad_with_entropy(uint64_t size_bytes, int show_progress, int use_keyboard_entropy);
|
||||||
int encrypt_text(const char* pad_identifier);
|
int encrypt_text(const char* pad_identifier, const char* input_text);
|
||||||
int decrypt_text(const char* pad_identifier);
|
int decrypt_text(const char* pad_identifier, const char* encrypted_message);
|
||||||
|
|
||||||
// Keyboard entropy functions
|
// Keyboard entropy functions
|
||||||
int setup_raw_terminal(struct termios* original_termios);
|
int setup_raw_terminal(struct termios* original_termios);
|
||||||
@@ -161,18 +161,22 @@ int command_line_mode(int argc, char* argv[]) {
|
|||||||
return generate_pad_with_entropy(size, 1, 0); // No keyboard entropy for command line
|
return generate_pad_with_entropy(size, 1, 0); // No keyboard entropy for command line
|
||||||
}
|
}
|
||||||
else if (strcmp(argv[1], "encrypt") == 0) {
|
else if (strcmp(argv[1], "encrypt") == 0) {
|
||||||
if (argc != 3) {
|
if (argc < 3 || argc > 4) {
|
||||||
printf("Usage: %s encrypt <pad_chksum_or_prefix>\n", argv[0]);
|
printf("Usage: %s encrypt <pad_chksum_or_prefix> [text_to_encrypt]\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return encrypt_text(argv[2]);
|
// Pass text if provided, otherwise NULL for interactive mode
|
||||||
|
const char* text = (argc == 4) ? argv[3] : NULL;
|
||||||
|
return encrypt_text(argv[2], text);
|
||||||
}
|
}
|
||||||
else if (strcmp(argv[1], "decrypt") == 0) {
|
else if (strcmp(argv[1], "decrypt") == 0) {
|
||||||
if (argc != 3) {
|
if (argc < 3 || argc > 4) {
|
||||||
printf("Usage: %s decrypt <pad_chksum_or_prefix>\n", argv[0]);
|
printf("Usage: %s decrypt <pad_chksum_or_prefix> [encrypted_message]\n", argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return decrypt_text(argv[2]);
|
// Pass message if provided, otherwise NULL for interactive mode
|
||||||
|
const char* message = (argc == 4) ? argv[3] : NULL;
|
||||||
|
return decrypt_text(argv[2], message);
|
||||||
}
|
}
|
||||||
else if (strcmp(argv[1], "list") == 0) {
|
else if (strcmp(argv[1], "list") == 0) {
|
||||||
return list_available_pads();
|
return list_available_pads();
|
||||||
@@ -250,12 +254,12 @@ int handle_encrypt_menu(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input[strcspn(input, "\n")] = 0;
|
input[strcspn(input, "\n")] = 0;
|
||||||
return encrypt_text(input);
|
return encrypt_text(input, NULL); // NULL for interactive mode
|
||||||
}
|
}
|
||||||
|
|
||||||
int handle_decrypt_menu(void) {
|
int handle_decrypt_menu(void) {
|
||||||
printf("\n=== Decrypt Message ===\n");
|
printf("\n=== Decrypt Message ===\n");
|
||||||
return decrypt_text(NULL); // No pad selection needed - chksum comes from message
|
return decrypt_text(NULL, NULL); // No pad selection needed - chksum comes from message
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t parse_size_string(const char* size_str) {
|
uint64_t parse_size_string(const char* size_str) {
|
||||||
@@ -797,13 +801,13 @@ int generate_pad_with_entropy(uint64_t size_bytes, int display_progress, int use
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int encrypt_text(const char* pad_identifier) {
|
int encrypt_text(const char* pad_identifier, const char* input_text) {
|
||||||
char* pad_chksum = find_pad_by_prefix(pad_identifier);
|
char* pad_chksum = find_pad_by_prefix(pad_identifier);
|
||||||
if (!pad_chksum) {
|
if (!pad_chksum) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char input_text[MAX_INPUT_SIZE];
|
char text_buffer[MAX_INPUT_SIZE];
|
||||||
char chksum_hex[MAX_HASH_LENGTH];
|
char chksum_hex[MAX_HASH_LENGTH];
|
||||||
uint64_t current_offset;
|
uint64_t current_offset;
|
||||||
|
|
||||||
@@ -841,23 +845,30 @@ int encrypt_text(const char* pad_identifier) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get input text from user
|
// Get input text - either from parameter or user input
|
||||||
printf("Enter text to encrypt: ");
|
if (input_text != NULL) {
|
||||||
fflush(stdout);
|
// Use provided text
|
||||||
|
strncpy(text_buffer, input_text, sizeof(text_buffer) - 1);
|
||||||
if (fgets(input_text, sizeof(input_text), stdin) == NULL) {
|
text_buffer[sizeof(text_buffer) - 1] = '\0';
|
||||||
printf("Error: Failed to read input\n");
|
} else {
|
||||||
free(pad_chksum);
|
// Get input text from user (interactive mode)
|
||||||
return 1;
|
printf("Enter text to encrypt: ");
|
||||||
}
|
fflush(stdout);
|
||||||
|
|
||||||
// Remove newline if present
|
if (fgets(text_buffer, sizeof(text_buffer), stdin) == NULL) {
|
||||||
size_t input_len = strlen(input_text);
|
printf("Error: Failed to read input\n");
|
||||||
if (input_len > 0 && input_text[input_len - 1] == '\n') {
|
free(pad_chksum);
|
||||||
input_text[input_len - 1] = '\0';
|
return 1;
|
||||||
input_len--;
|
}
|
||||||
|
|
||||||
|
// Remove newline if present
|
||||||
|
size_t len = strlen(text_buffer);
|
||||||
|
if (len > 0 && text_buffer[len - 1] == '\n') {
|
||||||
|
text_buffer[len - 1] = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t input_len = strlen(text_buffer);
|
||||||
if (input_len == 0) {
|
if (input_len == 0) {
|
||||||
printf("Error: No input provided\n");
|
printf("Error: No input provided\n");
|
||||||
free(pad_chksum);
|
free(pad_chksum);
|
||||||
@@ -908,7 +919,7 @@ int encrypt_text(const char* pad_identifier) {
|
|||||||
// XOR encrypt the input
|
// XOR encrypt the input
|
||||||
unsigned char* ciphertext = malloc(input_len);
|
unsigned char* ciphertext = malloc(input_len);
|
||||||
for (size_t i = 0; i < input_len; i++) {
|
for (size_t i = 0; i < input_len; i++) {
|
||||||
ciphertext[i] = input_text[i] ^ pad_data[i];
|
ciphertext[i] = text_buffer[i] ^ pad_data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode as base64
|
// Encode as base64
|
||||||
@@ -943,7 +954,7 @@ int encrypt_text(const char* pad_identifier) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int decrypt_text(const char* pad_identifier) {
|
int decrypt_text(const char* pad_identifier, const char* encrypted_message) {
|
||||||
// For command line mode, pad_identifier is ignored - we'll get the chksum from the message
|
// For command line mode, pad_identifier is ignored - we'll get the chksum from the message
|
||||||
(void)pad_identifier; // Suppress unused parameter warning
|
(void)pad_identifier; // Suppress unused parameter warning
|
||||||
|
|
||||||
@@ -954,42 +965,81 @@ int decrypt_text(const char* pad_identifier) {
|
|||||||
char base64_data[MAX_INPUT_SIZE * 2] = {0};
|
char base64_data[MAX_INPUT_SIZE * 2] = {0};
|
||||||
int in_data_section = 0;
|
int in_data_section = 0;
|
||||||
|
|
||||||
printf("Enter encrypted message (paste the full ASCII armor block):\n");
|
if (encrypted_message != NULL) {
|
||||||
|
// Parse provided encrypted message
|
||||||
// Read the ASCII armor format
|
char *message_copy = strdup(encrypted_message);
|
||||||
int found_begin = 0;
|
char *line_ptr = strtok(message_copy, "\n");
|
||||||
while (fgets(line, sizeof(line), stdin)) {
|
|
||||||
line[strcspn(line, "\n")] = 0;
|
|
||||||
|
|
||||||
if (strcmp(line, "-----BEGIN OTP MESSAGE-----") == 0) {
|
int found_begin = 0;
|
||||||
found_begin = 1;
|
while (line_ptr != NULL) {
|
||||||
continue;
|
if (strcmp(line_ptr, "-----BEGIN OTP MESSAGE-----") == 0) {
|
||||||
|
found_begin = 1;
|
||||||
|
}
|
||||||
|
else if (strcmp(line_ptr, "-----END OTP MESSAGE-----") == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (found_begin) {
|
||||||
|
if (strncmp(line_ptr, "Pad-ChkSum: ", 12) == 0) {
|
||||||
|
strncpy(stored_chksum, line_ptr + 12, 64);
|
||||||
|
stored_chksum[64] = '\0';
|
||||||
|
}
|
||||||
|
else if (strncmp(line_ptr, "Pad-Offset: ", 12) == 0) {
|
||||||
|
pad_offset = strtoull(line_ptr + 12, NULL, 10);
|
||||||
|
}
|
||||||
|
else if (strlen(line_ptr) == 0) {
|
||||||
|
in_data_section = 1;
|
||||||
|
}
|
||||||
|
else if (in_data_section) {
|
||||||
|
strncat(base64_data, line_ptr, sizeof(base64_data) - strlen(base64_data) - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line_ptr = strtok(NULL, "\n");
|
||||||
|
}
|
||||||
|
free(message_copy);
|
||||||
|
|
||||||
|
if (!found_begin) {
|
||||||
|
printf("Error: Invalid message format - missing BEGIN header\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Interactive mode - read from stdin
|
||||||
|
printf("Enter encrypted message (paste the full ASCII armor block):\n");
|
||||||
|
|
||||||
|
// Read the ASCII armor format
|
||||||
|
int found_begin = 0;
|
||||||
|
while (fgets(line, sizeof(line), stdin)) {
|
||||||
|
line[strcspn(line, "\n")] = 0;
|
||||||
|
|
||||||
|
if (strcmp(line, "-----BEGIN OTP MESSAGE-----") == 0) {
|
||||||
|
found_begin = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(line, "-----END OTP MESSAGE-----") == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_begin) continue;
|
||||||
|
|
||||||
|
if (strncmp(line, "Pad-ChkSum: ", 12) == 0) {
|
||||||
|
strncpy(stored_chksum, line + 12, 64);
|
||||||
|
stored_chksum[64] = '\0';
|
||||||
|
}
|
||||||
|
else if (strncmp(line, "Pad-Offset: ", 12) == 0) {
|
||||||
|
pad_offset = strtoull(line + 12, NULL, 10);
|
||||||
|
}
|
||||||
|
else if (strlen(line) == 0) {
|
||||||
|
in_data_section = 1;
|
||||||
|
}
|
||||||
|
else if (in_data_section) {
|
||||||
|
strncat(base64_data, line, sizeof(base64_data) - strlen(base64_data) - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(line, "-----END OTP MESSAGE-----") == 0) {
|
if (!found_begin) {
|
||||||
break;
|
printf("Error: Invalid message format - missing BEGIN header\n");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found_begin) continue;
|
|
||||||
|
|
||||||
if (strncmp(line, "Pad-ChkSum: ", 12) == 0) {
|
|
||||||
strncpy(stored_chksum, line + 12, 64);
|
|
||||||
stored_chksum[64] = '\0';
|
|
||||||
}
|
|
||||||
else if (strncmp(line, "Pad-Offset: ", 12) == 0) {
|
|
||||||
pad_offset = strtoull(line + 12, NULL, 10);
|
|
||||||
}
|
|
||||||
else if (strlen(line) == 0) {
|
|
||||||
in_data_section = 1;
|
|
||||||
}
|
|
||||||
else if (in_data_section) {
|
|
||||||
strncat(base64_data, line, sizeof(base64_data) - strlen(base64_data) - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_begin) {
|
|
||||||
printf("Error: Invalid message format - missing BEGIN header\n");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we have the pad chksum from the message, construct filename
|
// Now we have the pad chksum from the message, construct filename
|
||||||
@@ -1345,11 +1395,16 @@ 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());
|
||||||
printf("%s\n", get_build_info());
|
printf("%s\n", get_build_info());
|
||||||
printf("Usage:\n");
|
printf("Usage:\n");
|
||||||
printf(" %s - Interactive mode\n", program_name);
|
printf(" %s - Interactive mode\n", program_name);
|
||||||
printf(" %s generate <size> - Generate new pad\n", program_name);
|
printf(" %s generate <size> - Generate new pad\n", program_name);
|
||||||
printf(" %s encrypt <pad_checksum_prefix> - Encrypt text\n", program_name);
|
printf(" %s encrypt <pad_checksum_prefix> [text] - Encrypt text\n", program_name);
|
||||||
printf(" %s decrypt <pad_checksum_prefix> - Decrypt message\n", program_name);
|
printf(" %s decrypt <pad_checksum_prefix> [message] - Decrypt message\n", program_name);
|
||||||
printf(" %s list - List available pads\n", program_name);
|
printf(" %s list - List available pads\n", program_name);
|
||||||
|
printf("\nExamples:\n");
|
||||||
|
printf(" %s encrypt 1a2b3c \"Hello world\" - Encrypt inline text\n", program_name);
|
||||||
|
printf(" %s encrypt 1a2b3c - Encrypt interactively\n", program_name);
|
||||||
|
printf(" %s decrypt 1a2b3c \"-----BEGIN OTP...\" - Decrypt inline message\n", program_name);
|
||||||
|
printf(" %s decrypt 1a2b3c - Decrypt interactively\n", program_name);
|
||||||
printf("\nSize examples: 1GB, 5TB, 512MB, 2048 (bytes)\n");
|
printf("\nSize examples: 1GB, 5TB, 512MB, 2048 (bytes)\n");
|
||||||
printf("Pad selection: Full chksum, prefix, or number from list\n");
|
printf("Pad selection: Full chksum, prefix, or number from list\n");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user