Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 974470238d | |||
| 7c2821dd0d | |||
| 6f3976bc07 | |||
| 3bef639cc3 | |||
| 81eded2995 | |||
| e126e30889 |
31
Makefile
31
Makefile
@@ -1,25 +1,40 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -Wall -Wextra -std=c99 -Isrc -Isrc/miniz -Isrc/microtar
|
CFLAGS = -Wall -Wextra -std=c99 -Isrc -Isrc/miniz -Isrc/microtar
|
||||||
|
CFLAGS_MINIZ = -Wall -Wextra -std=c99 -D_POSIX_C_SOURCE=200112L -Isrc -Isrc/miniz -Isrc/microtar -Wno-unused-function -Wno-implicit-function-declaration
|
||||||
LIBS = -lm
|
LIBS = -lm
|
||||||
LIBS_STATIC = -static -lm
|
LIBS_STATIC = -static -lm
|
||||||
ARCH = $(shell uname -m)
|
ARCH = $(shell uname -m)
|
||||||
TARGET = build/otp-$(ARCH)
|
TARGET = build/otp-$(ARCH)
|
||||||
SOURCES = $(wildcard src/*.c) $(wildcard src/miniz/*.c) $(wildcard src/microtar/*.c)
|
SOURCES = $(wildcard src/*.c)
|
||||||
|
MINIZ_SOURCES = $(wildcard src/miniz/*.c)
|
||||||
|
MICROTAR_SOURCES = $(wildcard src/microtar/*.c)
|
||||||
OBJS = $(SOURCES:.c=.o)
|
OBJS = $(SOURCES:.c=.o)
|
||||||
|
MINIZ_OBJS = $(MINIZ_SOURCES:.c=.o)
|
||||||
|
MICROTAR_OBJS = $(MICROTAR_SOURCES:.c=.o)
|
||||||
|
ALL_OBJS = $(OBJS) $(MINIZ_OBJS) $(MICROTAR_OBJS)
|
||||||
|
|
||||||
# Default build target
|
# Default build target
|
||||||
$(TARGET): $(OBJS)
|
$(TARGET): $(ALL_OBJS)
|
||||||
@mkdir -p build
|
@mkdir -p build
|
||||||
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
|
$(CC) $(CFLAGS) -o $(TARGET) $(ALL_OBJS) $(LIBS)
|
||||||
@rm -f $(OBJS)
|
@rm -f $(ALL_OBJS)
|
||||||
|
|
||||||
# Static linking target
|
# Static linking target
|
||||||
static: $(OBJS)
|
static: $(ALL_OBJS)
|
||||||
@mkdir -p build
|
@mkdir -p build
|
||||||
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS_STATIC)
|
$(CC) $(CFLAGS) -o $(TARGET) $(ALL_OBJS) $(LIBS_STATIC)
|
||||||
@rm -f $(OBJS)
|
@rm -f $(ALL_OBJS)
|
||||||
|
|
||||||
%.o: %.c
|
# Compile main source files with full warnings
|
||||||
|
src/%.o: src/%.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
# Compile miniz library files with reduced warnings
|
||||||
|
src/miniz/%.o: src/miniz/%.c
|
||||||
|
$(CC) $(CFLAGS_MINIZ) -c $< -o $@
|
||||||
|
|
||||||
|
# Compile microtar library files normally
|
||||||
|
src/microtar/%.o: src/microtar/%.c
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|||||||
@@ -58,14 +58,14 @@ One-time pads can be trivially encrypted and decrypted using pencil and paper, m
|
|||||||
|
|
||||||
### Download Pre-Built Binaries
|
### Download Pre-Built Binaries
|
||||||
|
|
||||||
**[Download Current Linux x86](https://git.laantungir.net/laantungir/otp/releases/download/v0.3.39/otp-v0.3.39-linux-x86_64)**
|
**[Download Current Linux x86](https://git.laantungir.net/laantungir/otp/releases/download/v0.3.45/otp-v0.3.45-linux-x86_64)**
|
||||||
|
|
||||||
**[Download Current Raspberry Pi 64](https://git.laantungir.net/laantungir/otp/releases/download/v0.3.39/otp-v0.3.39-linux-arm64)**
|
**[Download Current Raspberry Pi 64](https://git.laantungir.net/laantungir/otp/releases/download/v0.3.45/otp-v0.3.45-linux-arm64)**
|
||||||
|
|
||||||
After downloading:
|
After downloading:
|
||||||
```bash
|
```bash
|
||||||
# Rename for convenience, then make executable
|
# Rename for convenience, then make executable
|
||||||
mv otp-v0.3.39-linux-x86_64 otp
|
mv otp-v0.3.45-linux-x86_64 otp
|
||||||
chmod +x otp
|
chmod +x otp
|
||||||
|
|
||||||
# Run it
|
# Run it
|
||||||
|
|||||||
@@ -11,7 +11,12 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "microtar/microtar.h"
|
#include "microtar/microtar.h"
|
||||||
|
|
||||||
|
// Suppress warnings from miniz header
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||||
#include "miniz/miniz.h"
|
#include "miniz/miniz.h"
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// DIRECTORY ARCHIVING FUNCTIONS
|
// DIRECTORY ARCHIVING FUNCTIONS
|
||||||
|
|||||||
62
src/crypto.c
62
src/crypto.c
@@ -297,7 +297,6 @@ int encrypt_text(const char* pad_identifier, const char* input_text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char text_buffer[MAX_INPUT_SIZE];
|
char text_buffer[MAX_INPUT_SIZE];
|
||||||
char chksum_hex[MAX_HASH_LENGTH];
|
|
||||||
uint64_t current_offset;
|
uint64_t current_offset;
|
||||||
|
|
||||||
char pad_path[MAX_HASH_LENGTH + 20];
|
char pad_path[MAX_HASH_LENGTH + 20];
|
||||||
@@ -327,12 +326,8 @@ int encrypt_text(const char* pad_identifier, const char* input_text) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate XOR checksum of pad file
|
// Use pad_chksum directly - it's already the checksum from the filename
|
||||||
if (calculate_checksum(pad_path, chksum_hex) != 0) {
|
// No need to recalculate by reading the entire pad file
|
||||||
printf("Error: Cannot calculate pad checksum\n");
|
|
||||||
free(pad_chksum);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get input text - either from parameter or user input
|
// Get input text - either from parameter or user input
|
||||||
if (input_text != NULL) {
|
if (input_text != NULL) {
|
||||||
@@ -464,7 +459,7 @@ int encrypt_text(const char* pad_identifier, const char* input_text) {
|
|||||||
|
|
||||||
// Use universal ASCII armor generator
|
// Use universal ASCII armor generator
|
||||||
char* ascii_output;
|
char* ascii_output;
|
||||||
if (generate_ascii_armor(chksum_hex, current_offset, ciphertext, input_len, &ascii_output) != 0) {
|
if (generate_ascii_armor(pad_chksum, current_offset, ciphertext, input_len, &ascii_output) != 0) {
|
||||||
printf("Error: Failed to generate ASCII armor\n");
|
printf("Error: Failed to generate ASCII armor\n");
|
||||||
free(pad_data);
|
free(pad_data);
|
||||||
free(ciphertext);
|
free(ciphertext);
|
||||||
@@ -592,36 +587,14 @@ int universal_decrypt(const char* input_data, const char* output_target, decrypt
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate pad integrity
|
// Pad integrity validation disabled for performance
|
||||||
int integrity_result = validate_pad_integrity(pad_path, stored_chksum);
|
// The checksum is already verified by matching the filename
|
||||||
if (integrity_result == 3) {
|
// If you need to verify pad integrity, the pad file would need to be read entirely
|
||||||
if (mode == DECRYPT_MODE_SILENT) {
|
// which is very slow for large pads (multi-GB files)
|
||||||
fprintf(stderr, "Error: Pad integrity check failed!\n");
|
|
||||||
return 1;
|
// Skip integrity check - trust the filename checksum
|
||||||
} else if (mode == DECRYPT_MODE_INTERACTIVE) {
|
if (mode == DECRYPT_MODE_INTERACTIVE || mode == DECRYPT_MODE_FILE_TO_TEXT) {
|
||||||
printf("Warning: Pad integrity check failed!\n");
|
printf("Using pad: %s\n", stored_chksum);
|
||||||
printf("Expected: %s\n", stored_chksum);
|
|
||||||
printf("Continue anyway? (y/N): ");
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
char response[10];
|
|
||||||
if (fgets(response, sizeof(response), stdin) == NULL ||
|
|
||||||
(response[0] != 'y' && response[0] != 'Y')) {
|
|
||||||
printf("Decryption aborted.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (integrity_result != 0) {
|
|
||||||
if (mode == DECRYPT_MODE_SILENT) {
|
|
||||||
fprintf(stderr, "Error: Cannot verify pad integrity\n");
|
|
||||||
} else {
|
|
||||||
printf("Error: Cannot verify pad integrity\n");
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
if (mode == DECRYPT_MODE_INTERACTIVE || mode == DECRYPT_MODE_FILE_TO_TEXT) {
|
|
||||||
printf("Pad integrity: VERIFIED\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode base64 ciphertext
|
// Decode base64 ciphertext
|
||||||
@@ -746,7 +719,6 @@ int encrypt_file(const char* pad_identifier, const char* input_file, const char*
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char chksum_hex[MAX_HASH_LENGTH];
|
|
||||||
uint64_t current_offset;
|
uint64_t current_offset;
|
||||||
|
|
||||||
char pad_path[MAX_HASH_LENGTH + 20];
|
char pad_path[MAX_HASH_LENGTH + 20];
|
||||||
@@ -791,12 +763,8 @@ int encrypt_file(const char* pad_identifier, const char* input_file, const char*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate XOR checksum of pad file
|
// Use pad_chksum directly - it's already the checksum from the filename
|
||||||
if (calculate_checksum(pad_path, chksum_hex) != 0) {
|
// No need to recalculate by reading the entire pad file
|
||||||
printf("Error: Cannot calculate pad checksum\n");
|
|
||||||
free(pad_chksum);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we have enough pad space
|
// Check if we have enough pad space
|
||||||
struct stat pad_stat;
|
struct stat pad_stat;
|
||||||
@@ -927,7 +895,7 @@ int encrypt_file(const char* pad_identifier, const char* input_file, const char*
|
|||||||
|
|
||||||
// Use universal ASCII armor generator
|
// Use universal ASCII armor generator
|
||||||
char* ascii_output;
|
char* ascii_output;
|
||||||
if (generate_ascii_armor(chksum_hex, current_offset, encrypted_data, file_size, &ascii_output) != 0) {
|
if (generate_ascii_armor(pad_chksum, current_offset, encrypted_data, file_size, &ascii_output) != 0) {
|
||||||
printf("Error: Failed to generate ASCII armor\n");
|
printf("Error: Failed to generate ASCII armor\n");
|
||||||
fclose(output_fp);
|
fclose(output_fp);
|
||||||
free(encrypted_data);
|
free(encrypted_data);
|
||||||
@@ -961,7 +929,7 @@ int encrypt_file(const char* pad_identifier, const char* input_file, const char*
|
|||||||
// Pad checksum: 32 bytes (binary)
|
// Pad checksum: 32 bytes (binary)
|
||||||
unsigned char pad_chksum_bin[32];
|
unsigned char pad_chksum_bin[32];
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
sscanf(chksum_hex + i*2, "%2hhx", &pad_chksum_bin[i]);
|
sscanf(pad_chksum + i*2, "%2hhx", &pad_chksum_bin[i]);
|
||||||
}
|
}
|
||||||
fwrite(pad_chksum_bin, 1, 32, output_fp);
|
fwrite(pad_chksum_bin, 1, 32, output_fp);
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
// Version - Updated automatically by build.sh
|
// Version - Updated automatically by build.sh
|
||||||
#define OTP_VERSION "v0.3.39"
|
#define OTP_VERSION "v0.3.45"
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
#define MAX_INPUT_SIZE 4096
|
#define MAX_INPUT_SIZE 4096
|
||||||
|
|||||||
@@ -470,6 +470,13 @@ char* select_pad_interactive(const char* title, const char* prompt, pad_filter_t
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If only one pad available, auto-select it
|
||||||
|
if (pad_count == 1) {
|
||||||
|
printf("\n%s\n", title);
|
||||||
|
printf("Only one pad available - auto-selecting: %.16s...\n\n", pads[0].chksum);
|
||||||
|
return strdup(pads[0].chksum);
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate minimal unique prefixes for each pad
|
// Calculate minimal unique prefixes for each pad
|
||||||
char prefixes[100][65];
|
char prefixes[100][65];
|
||||||
int prefix_lengths[100];
|
int prefix_lengths[100];
|
||||||
|
|||||||
31
src/ui.c
31
src/ui.c
@@ -334,7 +334,15 @@ int handle_decrypt_menu(void) {
|
|||||||
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
|
||||||
if (strstr(temp_default, ".otp.asc")) {
|
if (strstr(temp_default, ".tar.gz.otp")) {
|
||||||
|
// Directory archive - remove .tar.gz.otp to get original directory name
|
||||||
|
char* ext_pos = strstr(temp_default, ".tar.gz.otp");
|
||||||
|
*ext_pos = '\0';
|
||||||
|
} else if (strstr(temp_default, ".tar.otp")) {
|
||||||
|
// Directory archive without compression - remove .tar.otp
|
||||||
|
char* ext_pos = strstr(temp_default, ".tar.otp");
|
||||||
|
*ext_pos = '\0';
|
||||||
|
} else if (strstr(temp_default, ".otp.asc")) {
|
||||||
// Replace .otp.asc with original extension or no extension
|
// Replace .otp.asc with original extension or no extension
|
||||||
char* ext_pos = strstr(temp_default, ".otp.asc");
|
char* ext_pos = strstr(temp_default, ".otp.asc");
|
||||||
*ext_pos = '\0';
|
*ext_pos = '\0';
|
||||||
@@ -402,7 +410,15 @@ int handle_decrypt_menu(void) {
|
|||||||
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
|
||||||
if (strstr(temp_default, ".otp.asc")) {
|
if (strstr(temp_default, ".tar.gz.otp")) {
|
||||||
|
// Directory archive - remove .tar.gz.otp to get original directory name
|
||||||
|
char* ext_pos = strstr(temp_default, ".tar.gz.otp");
|
||||||
|
*ext_pos = '\0';
|
||||||
|
} else if (strstr(temp_default, ".tar.otp")) {
|
||||||
|
// Directory archive without compression - remove .tar.otp
|
||||||
|
char* ext_pos = strstr(temp_default, ".tar.otp");
|
||||||
|
*ext_pos = '\0';
|
||||||
|
} else if (strstr(temp_default, ".otp.asc")) {
|
||||||
// Replace .otp.asc with original extension or no extension
|
// Replace .otp.asc with original extension or no extension
|
||||||
char* ext_pos = strstr(temp_default, ".otp.asc");
|
char* ext_pos = strstr(temp_default, ".otp.asc");
|
||||||
*ext_pos = '\0';
|
*ext_pos = '\0';
|
||||||
@@ -595,16 +611,9 @@ int handle_directory_encrypt(void) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate default output filename
|
// Generate default output filename - append .tar.gz.otp to the directory path
|
||||||
char default_output[1024];
|
char default_output[1024];
|
||||||
const char* dir_name = strrchr(dir_path, '/');
|
snprintf(default_output, sizeof(default_output), "%s.tar.gz.otp", dir_path);
|
||||||
if (dir_name) {
|
|
||||||
dir_name++; // Skip the '/'
|
|
||||||
} else {
|
|
||||||
dir_name = dir_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(default_output, sizeof(default_output), "%s.tar.gz.otp", dir_name);
|
|
||||||
|
|
||||||
// Get output filename
|
// Get output filename
|
||||||
char output_file[512];
|
char output_file[512];
|
||||||
|
|||||||
Reference in New Issue
Block a user