Initial commit
This commit is contained in:
commit
e4bb767690
12
Makefile
Normal file
12
Makefile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
salty: salty.o
|
||||||
|
cc ./build/salty.o -o ./build/salty -lsodium -I.
|
||||||
|
rm ./build/salty.o
|
||||||
|
|
||||||
|
salty.o: build
|
||||||
|
cc -c salty.c -o ./build/salty.o -lsodium -I.
|
||||||
|
|
||||||
|
build:
|
||||||
|
mkdir -p ./build
|
||||||
|
|
||||||
|
install:
|
||||||
|
install -m 755 ./build/salty /usr/local/bin/salty
|
||||||
86
pawstd.h
Normal file
86
pawstd.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* This is free and unencumbered software released into the public domain.
|
||||||
|
*
|
||||||
|
* For more information, please refer to <https://unlicense.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Regular text
|
||||||
|
#define BLK "\e[0;30m"
|
||||||
|
#define RED "\e[0;31m"
|
||||||
|
#define GRN "\e[0;32m"
|
||||||
|
#define YEL "\e[0;33m"
|
||||||
|
#define BLU "\e[0;34m"
|
||||||
|
#define MAG "\e[0;35m"
|
||||||
|
#define CYN "\e[0;36m"
|
||||||
|
#define WHT "\e[0;37m"
|
||||||
|
|
||||||
|
//Regular bold text
|
||||||
|
#define BBLK "\e[1;30m"
|
||||||
|
#define BRED "\e[1;31m"
|
||||||
|
#define BGRN "\e[1;32m"
|
||||||
|
#define BYEL "\e[1;33m"
|
||||||
|
#define BBLU "\e[1;34m"
|
||||||
|
#define BMAG "\e[1;35m"
|
||||||
|
#define BCYN "\e[1;36m"
|
||||||
|
#define BWHT "\e[1;37m"
|
||||||
|
|
||||||
|
//Regular underline text
|
||||||
|
#define UBLK "\e[4;30m"
|
||||||
|
#define URED "\e[4;31m"
|
||||||
|
#define UGRN "\e[4;32m"
|
||||||
|
#define UYEL "\e[4;33m"
|
||||||
|
#define UBLU "\e[4;34m"
|
||||||
|
#define UMAG "\e[4;35m"
|
||||||
|
#define UCYN "\e[4;36m"
|
||||||
|
#define UWHT "\e[4;37m"
|
||||||
|
|
||||||
|
//Regular background
|
||||||
|
#define BLKB "\e[40m"
|
||||||
|
#define REDB "\e[41m"
|
||||||
|
#define GRNB "\e[42m"
|
||||||
|
#define YELB "\e[43m"
|
||||||
|
#define BLUB "\e[44m"
|
||||||
|
#define MAGB "\e[45m"
|
||||||
|
#define CYNB "\e[46m"
|
||||||
|
#define WHTB "\e[47m"
|
||||||
|
|
||||||
|
//High intensty background
|
||||||
|
#define BLKHB "\e[0;100m"
|
||||||
|
#define REDHB "\e[0;101m"
|
||||||
|
#define GRNHB "\e[0;102m"
|
||||||
|
#define YELHB "\e[0;103m"
|
||||||
|
#define BLUHB "\e[0;104m"
|
||||||
|
#define MAGHB "\e[0;105m"
|
||||||
|
#define CYNHB "\e[0;106m"
|
||||||
|
#define WHTHB "\e[0;107m"
|
||||||
|
|
||||||
|
//High intensty text
|
||||||
|
#define HBLK "\e[0;90m"
|
||||||
|
#define HRED "\e[0;91m"
|
||||||
|
#define HGRN "\e[0;92m"
|
||||||
|
#define HYEL "\e[0;93m"
|
||||||
|
#define HBLU "\e[0;94m"
|
||||||
|
#define HMAG "\e[0;95m"
|
||||||
|
#define HCYN "\e[0;96m"
|
||||||
|
#define HWHT "\e[0;97m"
|
||||||
|
|
||||||
|
//Bold high intensity text
|
||||||
|
#define BHBLK "\e[1;90m"
|
||||||
|
#define BHRED "\e[1;91m"
|
||||||
|
#define BHGRN "\e[1;92m"
|
||||||
|
#define BHYEL "\e[1;93m"
|
||||||
|
#define BHBLU "\e[1;94m"
|
||||||
|
#define BHMAG "\e[1;95m"
|
||||||
|
#define BHCYN "\e[1;96m"
|
||||||
|
#define BHWHT "\e[1;97m"
|
||||||
|
|
||||||
|
//Reset
|
||||||
|
#define reset "\e[0m"
|
||||||
|
#define CRESET "\e[0m"
|
||||||
|
#define COLOR_RESET "\e[0m"
|
||||||
|
|
||||||
|
// Line decorations
|
||||||
|
#define ERR "[ "RED"ERR"reset" ] "
|
||||||
|
#define NOR "[ --- ] "
|
||||||
|
#define OK "[ "GRN"OK!"reset" ] "
|
||||||
|
#define DBG "[ " YEL "DBG" reset " ] "
|
||||||
336
salty.c
Normal file
336
salty.c
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sodium.h>
|
||||||
|
#include <pawstd.h>
|
||||||
|
#define KEY_SIZE crypto_secretbox_KEYBYTES
|
||||||
|
#define SALT_SIZE crypto_pwhash_SALTBYTES
|
||||||
|
|
||||||
|
|
||||||
|
int encryptMessage(const char* inputFile, const char* outputFile, const char* password) {
|
||||||
|
// Open files
|
||||||
|
FILE *inFile = fopen(inputFile,"rb");
|
||||||
|
FILE *outFile = fopen(outputFile,"wb");
|
||||||
|
if (inFile == NULL || outFile == NULL) {
|
||||||
|
fprintf(stderr,ERR"Could not open files!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// Variables
|
||||||
|
unsigned char salt[SALT_SIZE];
|
||||||
|
unsigned char nonce[crypto_secretbox_NONCEBYTES];
|
||||||
|
unsigned char key[KEY_SIZE];
|
||||||
|
|
||||||
|
// Read input file
|
||||||
|
|
||||||
|
fprintf(stderr,NOR"Reading input filesize...\n");
|
||||||
|
fseek(inFile,0,SEEK_END);
|
||||||
|
size_t inLen = ftell(inFile);
|
||||||
|
fseek(inFile,0,SEEK_SET);
|
||||||
|
fprintf(stderr,OK"File is %d bytes.\n",inLen);
|
||||||
|
unsigned char decrypted[inLen];
|
||||||
|
|
||||||
|
// Generate salt
|
||||||
|
randombytes_buf(salt, SALT_SIZE);
|
||||||
|
fprintf(stderr,NOR"Beginning key generation...\n");
|
||||||
|
|
||||||
|
// Key generation from password
|
||||||
|
if (crypto_pwhash(
|
||||||
|
key,KEY_SIZE,
|
||||||
|
password,strlen(password),
|
||||||
|
salt,crypto_pwhash_OPSLIMIT_INTERACTIVE,
|
||||||
|
crypto_pwhash_MEMLIMIT_INTERACTIVE,
|
||||||
|
crypto_pwhash_ALG_DEFAULT) != 0) {
|
||||||
|
fprintf(stderr,ERR"Out of memory! Key could not be generated.\n");
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr,OK"Key generation successful!\n");
|
||||||
|
fprintf(stderr,NOR"Reading file...\n");
|
||||||
|
|
||||||
|
// Read the input file
|
||||||
|
if(fread(decrypted,1,inLen,inFile) != inLen) {
|
||||||
|
fprintf(stderr,ERR"Error reading from file.\n");
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fprintf(stderr,OK"File read successfully!\n");
|
||||||
|
fprintf(stderr,NOR"Beginning encryption...\n");
|
||||||
|
|
||||||
|
// Generate a nonce, write headers and encrypted message
|
||||||
|
randombytes_buf(nonce,sizeof(nonce));
|
||||||
|
|
||||||
|
if (fwrite("gneurshk",1,strlen("gneurshk"),outFile) != strlen("gneurshk")) {
|
||||||
|
fprintf(stderr,ERR"Error writing header to file.\n");
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite(salt,1,sizeof(salt),outFile) != sizeof(salt)) {
|
||||||
|
fprintf(stderr,ERR"Error writing salt to file.\n");
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite(nonce,1,sizeof(nonce),outFile) != sizeof(nonce)) {
|
||||||
|
fprintf(stderr,ERR"Error writing nonce to file.\n");
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr,OK"Headers written!\n");
|
||||||
|
fprintf(stderr,NOR"Writing encrypted data...\n");
|
||||||
|
|
||||||
|
unsigned char encrypted[inLen + crypto_secretbox_MACBYTES];
|
||||||
|
|
||||||
|
crypto_secretbox_easy(encrypted, decrypted, inLen, nonce, key);
|
||||||
|
|
||||||
|
if(fwrite(encrypted,1,sizeof(encrypted),outFile) != sizeof(encrypted)) {
|
||||||
|
fprintf(stderr,ERR"Error writing encrypted data to file.\n");
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
|
||||||
|
fprintf(stderr,"\n"OK"File encrypted!\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int decryptMessage(const char* inputFile, const char* outputFile, const char* password) {
|
||||||
|
// Open files
|
||||||
|
FILE *inFile = fopen(inputFile,"rb");
|
||||||
|
FILE *outFile = fopen(outputFile,"wb");
|
||||||
|
if (inFile == NULL || outFile == NULL) {
|
||||||
|
fprintf(stderr,ERR"Could not open files.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
unsigned char salt[SALT_SIZE];
|
||||||
|
unsigned char nonce[crypto_secretbox_NONCEBYTES];
|
||||||
|
unsigned char key[KEY_SIZE];
|
||||||
|
|
||||||
|
// Get the size of the file and assume the length of the content
|
||||||
|
fseek(inFile,0,SEEK_END);
|
||||||
|
size_t fileLen = ftell(inFile);
|
||||||
|
fseek(inFile,0,SEEK_SET);
|
||||||
|
|
||||||
|
size_t encLen = fileLen - sizeof(salt) - sizeof(nonce) - 8;
|
||||||
|
|
||||||
|
fprintf(stderr,DBG"Size of encrypted file: %d bytes.\n",fileLen);
|
||||||
|
fprintf(stderr,DBG"This means the encrypted content is %d bytes.\n",encLen);
|
||||||
|
|
||||||
|
unsigned char encrypted[encLen];
|
||||||
|
|
||||||
|
// Verify file
|
||||||
|
unsigned char header[8];
|
||||||
|
if (fread(header,1,sizeof(header),inFile) != sizeof(header)) {
|
||||||
|
fprintf(stderr,ERR"Error reading header from file.\n");
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(header,"gneurshk",sizeof(header)) != 0) {
|
||||||
|
fprintf(stderr,ERR"Invalid header.\n");
|
||||||
|
fprintf(stderr,ERR"Make sure the input file was signed by this program!\n");
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fprintf(stderr,OK"Valid header! Reading the rest...\n");
|
||||||
|
|
||||||
|
// Read salt and nonce
|
||||||
|
if(fread(salt,1,sizeof(salt),inFile) != sizeof(salt)) {
|
||||||
|
fprintf(stderr,ERR"Error reading salt from file.\n");
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fprintf(stderr,OK"Salt retrieved.\n");
|
||||||
|
|
||||||
|
if(fread(nonce,1,sizeof(nonce),inFile) != sizeof(nonce)) {
|
||||||
|
fprintf(stderr,ERR"Error reading nonce from file.\n");
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fprintf(stderr,OK"Nonce retrieved.\n");
|
||||||
|
|
||||||
|
if(fread(encrypted,1,encLen,inFile) != encLen) {
|
||||||
|
fprintf(stderr,ERR"Error reading data from file.\n");
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fprintf(stderr,OK"Data retrieved.\n");
|
||||||
|
fprintf(stderr,OK"Deriving key from password...\n");
|
||||||
|
|
||||||
|
// Key derivation
|
||||||
|
if (crypto_pwhash(
|
||||||
|
key,KEY_SIZE,
|
||||||
|
password,strlen(password),
|
||||||
|
salt,crypto_pwhash_OPSLIMIT_INTERACTIVE,
|
||||||
|
crypto_pwhash_MEMLIMIT_INTERACTIVE,
|
||||||
|
crypto_pwhash_ALG_DEFAULT) != 0) {
|
||||||
|
fprintf(stderr,ERR"Out of memory! Key could not be generated.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fprintf(stderr,OK"Key derivation successful!\n");
|
||||||
|
fprintf(stderr,OK"Proceeding to decrypt file...\n");
|
||||||
|
|
||||||
|
size_t decLen = encLen - crypto_secretbox_MACBYTES;
|
||||||
|
unsigned char decrypted[decLen];
|
||||||
|
|
||||||
|
if (crypto_secretbox_open_easy(decrypted,encrypted,encLen,nonce,key) < 0) {
|
||||||
|
fprintf(stderr,ERR"Error decrypting file.\n");
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite(decrypted,1,decLen,outFile) != decLen) {
|
||||||
|
fprintf(stderr,ERR"Error writing data to file.\n");
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(inFile);
|
||||||
|
fclose(outFile);
|
||||||
|
|
||||||
|
fprintf(stderr,"\n"OK"File decrypted!\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFile(const char* filename) {
|
||||||
|
struct stat buffer;
|
||||||
|
return (stat(filename, &buffer) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
fprintf(stderr,"\n- NetPaws Salty - File Encryption Program\n");
|
||||||
|
fprintf(stderr,"- 2024 Ignacio Rivero\n");
|
||||||
|
fprintf(stderr,"- FOR INTERNAL USE ONLY\n\n");
|
||||||
|
// Initialize libsodium
|
||||||
|
if (sodium_init() < 0) {
|
||||||
|
fprintf(stderr,ERR"libsodium initialization failed! It is not safe to proceed.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle input, output and password arguments
|
||||||
|
int in = -1, out = -1, pass = -1;
|
||||||
|
bool decrypt = false;
|
||||||
|
|
||||||
|
int i = 1, exit = 0;
|
||||||
|
while (i < argc && exit == 0) {
|
||||||
|
if (strcmp (argv[i],"-in") == 0) {
|
||||||
|
if (i+1 >= argc) {
|
||||||
|
fprintf(stderr,ERR"Argument -in requires a file.\n");
|
||||||
|
exit = 1;
|
||||||
|
} else if (!isFile(argv[i+1])) {
|
||||||
|
fprintf(stderr,ERR"File not found error: %s\n",argv[i+1]);
|
||||||
|
exit = 1;
|
||||||
|
} else if (in == -1) {
|
||||||
|
in = ++i;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,ERR"Too many arguments.\n");
|
||||||
|
exit = 1;
|
||||||
|
}
|
||||||
|
} else if (strcmp(argv[i],"-out") == 0) {
|
||||||
|
if (i+1 >= argc) {
|
||||||
|
fprintf(stderr,ERR"Argument -out requires a file.\n");
|
||||||
|
exit = 1;
|
||||||
|
} else if (strcmp(argv[i+1],"-") == 0) {
|
||||||
|
out = -2;
|
||||||
|
i++;
|
||||||
|
} else if (out == -1) {
|
||||||
|
out = ++i;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,ERR"Too many arguments.\n");
|
||||||
|
exit = 1;
|
||||||
|
}
|
||||||
|
} else if (strcmp (argv[i],"-key") == 0) {
|
||||||
|
if (i+1 >= argc) {
|
||||||
|
fprintf(stderr,ERR"Argument -key requires a password.\n");
|
||||||
|
exit = 1;
|
||||||
|
} else if (pass == -1) {
|
||||||
|
if (strlen(argv[i+1]) > 128) {
|
||||||
|
fprintf(stderr,ERR"Password too long.");
|
||||||
|
exit = 1;
|
||||||
|
} else {
|
||||||
|
pass = ++i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,ERR"Too many arguments.\n");
|
||||||
|
exit = 1;
|
||||||
|
}
|
||||||
|
} else if (strcmp (argv[i],"-d") == 0) {
|
||||||
|
decrypt = true;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,ERR"Invalid argument: %s\n",argv[i]);
|
||||||
|
exit = 1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exit != 0)
|
||||||
|
return exit;
|
||||||
|
|
||||||
|
// Set input and output filenames, or go to standard I/O if none
|
||||||
|
char input[FILENAME_MAX];
|
||||||
|
char output[FILENAME_MAX];
|
||||||
|
char psw[129];
|
||||||
|
|
||||||
|
if (in == -1) {
|
||||||
|
fprintf(stderr,ERR"No input file specified.\n");
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
snprintf(input,sizeof(input),argv[in]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out == -1) {
|
||||||
|
fprintf(stderr,NOR"No output file, writing to stdout.\n");
|
||||||
|
snprintf(output,sizeof(output),"/dev/stdout");
|
||||||
|
} else if (out == -2) {
|
||||||
|
fprintf(stderr,NOR"Writing to stdout.\n");
|
||||||
|
snprintf(output,sizeof(output),"/dev/stdout");
|
||||||
|
} else {
|
||||||
|
snprintf(output,sizeof(output),argv[out]);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* password;
|
||||||
|
|
||||||
|
// Set password and run!
|
||||||
|
if (pass == -1) {
|
||||||
|
password = getpass("Enter your encryption password: ");
|
||||||
|
printf(DBG"Password : %s\n",password);
|
||||||
|
} else {
|
||||||
|
password = argv[pass];
|
||||||
|
printf(DBG"Password : %s\n",password);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decrypt) {
|
||||||
|
return decryptMessage(input,output,password);
|
||||||
|
} else {
|
||||||
|
return encryptMessage(input,output,password);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user