Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 482687cb68 | |||
| e35d94243e | |||
| e88e1b5d3d |
143
otp.c
143
otp.c
@@ -81,6 +81,7 @@ 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, const char* input_text);
|
||||
int decrypt_text(const char* pad_identifier, const char* encrypted_message);
|
||||
int decrypt_text_silent(const char* pad_identifier, const char* encrypted_message);
|
||||
int encrypt_file(const char* pad_identifier, const char* input_file, const char* output_file, int ascii_armor);
|
||||
int decrypt_file(const char* input_file, const char* output_file);
|
||||
int decrypt_binary_file(FILE* input_fp, const char* output_file);
|
||||
@@ -137,11 +138,16 @@ int main(int argc, char* argv[]) {
|
||||
// Check for piped input first (before any output)
|
||||
int is_pipe_mode = (argc == 1 && has_stdin_data());
|
||||
|
||||
// Check for decrypt command with piped input
|
||||
int is_decrypt_pipe = (argc == 2 &&
|
||||
(strcmp(argv[1], "decrypt") == 0 || strcmp(argv[1], "-d") == 0) &&
|
||||
has_stdin_data());
|
||||
|
||||
// Check for OTP thumb drive on startup
|
||||
char otp_drive_path[512];
|
||||
if (detect_otp_thumb_drive(otp_drive_path, sizeof(otp_drive_path))) {
|
||||
// Only show messages in interactive/command mode, not pipe mode
|
||||
if (!is_pipe_mode) {
|
||||
if (!is_pipe_mode && !is_decrypt_pipe) {
|
||||
printf("Detected OTP thumb drive: %s\n", otp_drive_path);
|
||||
printf("Using as default pads directory for this session.\n\n");
|
||||
}
|
||||
@@ -238,6 +244,16 @@ int command_line_mode(int argc, char* argv[]) {
|
||||
}
|
||||
else if (strcmp(argv[1], "decrypt") == 0 || strcmp(argv[1], "-d") == 0) {
|
||||
if (argc == 2) {
|
||||
// Check for piped input first
|
||||
if (has_stdin_data()) {
|
||||
// Piped decrypt mode - read stdin and decrypt silently
|
||||
char* piped_message = read_stdin_text();
|
||||
if (piped_message) {
|
||||
int result = decrypt_text_silent(NULL, piped_message);
|
||||
free(piped_message);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// Interactive mode - no arguments needed
|
||||
return decrypt_text(NULL, NULL);
|
||||
}
|
||||
@@ -1599,6 +1615,131 @@ int decrypt_text(const char* pad_identifier, const char* encrypted_message) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int decrypt_text_silent(const char* pad_identifier, const char* encrypted_message) {
|
||||
// For piped decrypt mode - silent operation with minimal output
|
||||
(void)pad_identifier; // Suppress unused parameter warning
|
||||
|
||||
char line[MAX_LINE_LENGTH];
|
||||
char stored_chksum[MAX_HASH_LENGTH];
|
||||
char current_chksum[MAX_HASH_LENGTH];
|
||||
uint64_t pad_offset;
|
||||
char base64_data[MAX_INPUT_SIZE * 2] = {0};
|
||||
int in_data_section = 0;
|
||||
|
||||
if (encrypted_message != NULL) {
|
||||
// Parse provided encrypted message
|
||||
char *message_copy = strdup(encrypted_message);
|
||||
char *line_ptr = strtok(message_copy, "\n");
|
||||
|
||||
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) {
|
||||
fprintf(stderr, "Error: Invalid message format - missing BEGIN header\n");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Error: No encrypted message provided\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Now we have the pad chksum from the message, construct filename
|
||||
char pad_path[MAX_HASH_LENGTH + 20];
|
||||
char state_path[MAX_HASH_LENGTH + 20];
|
||||
get_pad_path(stored_chksum, pad_path, state_path);
|
||||
|
||||
// Check if we have this pad
|
||||
if (access(pad_path, R_OK) != 0) {
|
||||
fprintf(stderr, "Error: Required pad not found: %s\n", stored_chksum);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Verify pad integrity (silent check)
|
||||
if (calculate_checksum(pad_path, current_chksum) != 0) {
|
||||
fprintf(stderr, "Error: Cannot calculate current pad checksum\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strcmp(stored_chksum, current_chksum) != 0) {
|
||||
fprintf(stderr, "Error: Pad integrity check failed!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Decode base64
|
||||
int ciphertext_len;
|
||||
unsigned char* ciphertext = custom_base64_decode(base64_data, &ciphertext_len);
|
||||
if (!ciphertext) {
|
||||
fprintf(stderr, "Error: Invalid base64 data\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read pad data at specified offset
|
||||
FILE* pad_file = fopen(pad_path, "rb");
|
||||
if (!pad_file) {
|
||||
fprintf(stderr, "Error: Cannot open pad file %s\n", pad_path);
|
||||
free(ciphertext);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fseek(pad_file, pad_offset, SEEK_SET) != 0) {
|
||||
fprintf(stderr, "Error: Cannot seek to offset %lu in pad file\n", pad_offset);
|
||||
free(ciphertext);
|
||||
fclose(pad_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char* pad_data = malloc(ciphertext_len);
|
||||
if (fread(pad_data, 1, ciphertext_len, pad_file) != (size_t)ciphertext_len) {
|
||||
fprintf(stderr, "Error: Cannot read pad data\n");
|
||||
free(ciphertext);
|
||||
free(pad_data);
|
||||
fclose(pad_file);
|
||||
return 1;
|
||||
}
|
||||
fclose(pad_file);
|
||||
|
||||
// XOR decrypt
|
||||
char* plaintext = malloc(ciphertext_len + 1);
|
||||
for (int i = 0; i < ciphertext_len; i++) {
|
||||
plaintext[i] = ciphertext[i] ^ pad_data[i];
|
||||
}
|
||||
plaintext[ciphertext_len] = '\0';
|
||||
|
||||
// Output only the decrypted text - no extra messages
|
||||
printf("%s", plaintext);
|
||||
|
||||
// Cleanup
|
||||
free(ciphertext);
|
||||
free(pad_data);
|
||||
free(plaintext);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int encrypt_file(const char* pad_identifier, const char* input_file, const char* output_file, int ascii_armor) {
|
||||
char* pad_chksum = find_pad_by_prefix(pad_identifier);
|
||||
if (!pad_chksum) {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Testing updated files directory functionality
|
||||
@@ -1 +0,0 @@
|
||||
Testing files directory functionality
|
||||
BIN
test_new.txt.otp
BIN
test_new.txt.otp
Binary file not shown.
Reference in New Issue
Block a user