Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ae0afcfffd | |||
| e45aa04b05 | |||
| 8e1fcdb108 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
otp
|
||||
pads/
|
||||
Gemini.md
|
||||
|
||||
|
||||
@@ -199,3 +199,5 @@ When contributing:
|
||||
1. The version will automatically increment on builds
|
||||
2. For major features, consider manually creating minor version tags
|
||||
3. Generated version files (`src/version.*`, `VERSION`) should not be committed
|
||||
# Test change
|
||||
# Testing -m flag
|
||||
|
||||
45
build.sh
45
build.sh
@@ -13,6 +13,23 @@ print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||||
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
|
||||
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
|
||||
# Global variable for commit message
|
||||
COMMIT_MESSAGE=""
|
||||
|
||||
# Parse command line arguments for -m flag
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-m|--message)
|
||||
COMMIT_MESSAGE="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
# Keep other arguments for main logic
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Function to automatically increment version
|
||||
increment_version() {
|
||||
print_status "Incrementing version..."
|
||||
@@ -57,8 +74,22 @@ increment_version() {
|
||||
print_warning "Failed to stage changes (maybe not a git repository)"
|
||||
fi
|
||||
|
||||
# Commit changes with version message
|
||||
if git commit -m "Version $NEW_VERSION - Automatic version increment" 2>/dev/null; then
|
||||
# Handle commit message - use global variable if set, otherwise prompt
|
||||
if [[ -z "$COMMIT_MESSAGE" ]]; then
|
||||
echo ""
|
||||
print_status "Please enter a meaningful commit message for version $NEW_VERSION:"
|
||||
echo -n "> "
|
||||
read -r COMMIT_MESSAGE
|
||||
fi
|
||||
|
||||
# Check if user provided a message
|
||||
if [[ -z "$COMMIT_MESSAGE" ]]; then
|
||||
print_warning "No commit message provided. Using default message."
|
||||
COMMIT_MESSAGE="Automatic version increment"
|
||||
fi
|
||||
|
||||
# Commit changes with user-provided message
|
||||
if git commit -m "Version $NEW_VERSION - $COMMIT_MESSAGE" 2>/dev/null; then
|
||||
print_success "Committed changes for version $NEW_VERSION"
|
||||
else
|
||||
print_warning "Failed to commit changes (maybe no changes to commit or not a git repository)"
|
||||
@@ -227,7 +258,10 @@ case "${1:-build}" in
|
||||
;;
|
||||
*)
|
||||
echo "OTP Cipher Build Script"
|
||||
echo "Usage: $0 {build|static|clean|install|uninstall|version}"
|
||||
echo "Usage: $0 [-m \"commit message\"] {build|static|clean|install|uninstall|version}"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -m, --message \"text\" - Specify commit message (skips interactive prompt)"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " build - Build project with automatic version increment (default)"
|
||||
@@ -236,6 +270,11 @@ case "${1:-build}" in
|
||||
echo " install - Install to system (requires build first)"
|
||||
echo " uninstall - Remove from system"
|
||||
echo " version - Generate version files only"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 build"
|
||||
echo " $0 -m \"Fixed checksum parsing bug\" build"
|
||||
echo " $0 --message \"Added new feature\" static"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
182
otp.c
182
otp.c
@@ -50,8 +50,8 @@ int command_line_mode(int argc, char* argv[]);
|
||||
// Core functions
|
||||
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 encrypt_text(const char* pad_identifier);
|
||||
int decrypt_text(const char* pad_identifier);
|
||||
int encrypt_text(const char* pad_identifier, const char* input_text);
|
||||
int decrypt_text(const char* pad_identifier, const char* encrypted_message);
|
||||
|
||||
// Keyboard entropy functions
|
||||
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
|
||||
}
|
||||
else if (strcmp(argv[1], "encrypt") == 0) {
|
||||
if (argc != 3) {
|
||||
printf("Usage: %s encrypt <pad_chksum_or_prefix>\n", argv[0]);
|
||||
if (argc < 3 || argc > 4) {
|
||||
printf("Usage: %s encrypt <pad_chksum_or_prefix> [text_to_encrypt]\n", argv[0]);
|
||||
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) {
|
||||
if (argc != 3) {
|
||||
printf("Usage: %s decrypt <pad_chksum_or_prefix>\n", argv[0]);
|
||||
if (argc < 3 || argc > 4) {
|
||||
printf("Usage: %s decrypt <pad_chksum_or_prefix> [encrypted_message]\n", argv[0]);
|
||||
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) {
|
||||
return list_available_pads();
|
||||
@@ -250,12 +254,12 @@ int handle_encrypt_menu(void) {
|
||||
}
|
||||
|
||||
input[strcspn(input, "\n")] = 0;
|
||||
return encrypt_text(input);
|
||||
return encrypt_text(input, NULL); // NULL for interactive mode
|
||||
}
|
||||
|
||||
int handle_decrypt_menu(void) {
|
||||
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) {
|
||||
@@ -797,13 +801,13 @@ int generate_pad_with_entropy(uint64_t size_bytes, int display_progress, int use
|
||||
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);
|
||||
if (!pad_chksum) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
char input_text[MAX_INPUT_SIZE];
|
||||
char text_buffer[MAX_INPUT_SIZE];
|
||||
char chksum_hex[MAX_HASH_LENGTH];
|
||||
uint64_t current_offset;
|
||||
|
||||
@@ -841,23 +845,30 @@ int encrypt_text(const char* pad_identifier) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get input text from user
|
||||
printf("Enter text to encrypt: ");
|
||||
fflush(stdout);
|
||||
|
||||
if (fgets(input_text, sizeof(input_text), stdin) == NULL) {
|
||||
printf("Error: Failed to read input\n");
|
||||
free(pad_chksum);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Remove newline if present
|
||||
size_t input_len = strlen(input_text);
|
||||
if (input_len > 0 && input_text[input_len - 1] == '\n') {
|
||||
input_text[input_len - 1] = '\0';
|
||||
input_len--;
|
||||
// Get input text - either from parameter or user input
|
||||
if (input_text != NULL) {
|
||||
// Use provided text
|
||||
strncpy(text_buffer, input_text, sizeof(text_buffer) - 1);
|
||||
text_buffer[sizeof(text_buffer) - 1] = '\0';
|
||||
} else {
|
||||
// Get input text from user (interactive mode)
|
||||
printf("Enter text to encrypt: ");
|
||||
fflush(stdout);
|
||||
|
||||
if (fgets(text_buffer, sizeof(text_buffer), stdin) == NULL) {
|
||||
printf("Error: Failed to read input\n");
|
||||
free(pad_chksum);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
printf("Error: No input provided\n");
|
||||
free(pad_chksum);
|
||||
@@ -908,7 +919,7 @@ int encrypt_text(const char* pad_identifier) {
|
||||
// XOR encrypt the input
|
||||
unsigned char* ciphertext = malloc(input_len);
|
||||
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
|
||||
@@ -943,7 +954,7 @@ int encrypt_text(const char* pad_identifier) {
|
||||
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
|
||||
(void)pad_identifier; // Suppress unused parameter warning
|
||||
|
||||
@@ -954,36 +965,80 @@ int decrypt_text(const char* pad_identifier) {
|
||||
char base64_data[MAX_INPUT_SIZE * 2] = {0};
|
||||
int in_data_section = 0;
|
||||
|
||||
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 (encrypted_message != NULL) {
|
||||
// Parse provided encrypted message
|
||||
char *message_copy = strdup(encrypted_message);
|
||||
char *line_ptr = strtok(message_copy, "\n");
|
||||
|
||||
if (strcmp(line, "-----BEGIN OTP MESSAGE-----") == 0) {
|
||||
found_begin = 1;
|
||||
continue;
|
||||
int found_begin = 0;
|
||||
while (line_ptr != NULL) {
|
||||
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) {
|
||||
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 (!found_begin) {
|
||||
printf("Error: Invalid message format - missing BEGIN header\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1345,11 +1400,16 @@ void print_usage(const char* program_name) {
|
||||
printf("OTP Cipher - One Time Pad Implementation %s\n", get_version());
|
||||
printf("%s\n", get_build_info());
|
||||
printf("Usage:\n");
|
||||
printf(" %s - Interactive mode\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 decrypt <pad_checksum_prefix> - Decrypt message\n", program_name);
|
||||
printf(" %s list - List available pads\n", program_name);
|
||||
printf(" %s - Interactive mode\n", program_name);
|
||||
printf(" %s generate <size> - Generate new pad\n", program_name);
|
||||
printf(" %s encrypt <pad_checksum_prefix> [text] - Encrypt text\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("\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("Pad selection: Full chksum, prefix, or number from list\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user