From 09eba06535af135a9d1ba7d8827b72d58009733d Mon Sep 17 00:00:00 2001 From: Ignacio Date: Mon, 1 Apr 2024 11:55:39 -0300 Subject: [PATCH] Added stdin functionality to encryption only --- salty.c | 205 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 135 insertions(+), 70 deletions(-) diff --git a/salty.c b/salty.c index 679afd9..7fbe7ce 100644 --- a/salty.c +++ b/salty.c @@ -10,35 +10,19 @@ #include #define KEY_SIZE crypto_secretbox_KEYBYTES #define SALT_SIZE crypto_pwhash_SALTBYTES +#define BUF_SIZE 1024 +bool stdinput = false; -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]; +size_t fileSize(FILE *file) { + fseek(file,0,SEEK_END); + size_t size = ftell(file); + fseek(file,0,SEEK_SET); + return 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); +bool keyGen(const unsigned char* salt, const char* password, unsigned char* key) { fprintf(stderr,NOR"Beginning key generation...\n"); - - // Key generation from password if (crypto_pwhash( key,KEY_SIZE, password,strlen(password), @@ -46,67 +30,147 @@ int encryptMessage(const char* inputFile, const char* outputFile, const char* pa 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 false; + } + fprintf(stderr,OK"Key generation successful!\n"); + return true; +} + +int encryptMessage(const char* inputFile, const char* outputFile, const char* password) { + + // Generate salt + unsigned char salt[SALT_SIZE]; + randombytes_buf(salt, SALT_SIZE); + + // Key generation from password + unsigned char key[KEY_SIZE]; + if (!keyGen(salt,password,key)) { 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); + FILE *outFile = fopen(outputFile,"wb"); + if (outFile == NULL) { + fprintf(stderr,ERR"Could not open output file!\n"); return 1; } - fprintf(stderr,OK"File read successfully!\n"); + + unsigned char* decrypted; + size_t decLen; + + // Check if input is stdin, and read the input + if (stdinput) { + // Begin reading into buffer + unsigned char buffer[BUF_SIZE]; + size_t inputSize = 0; + unsigned char c; + unsigned char* input = malloc(BUF_SIZE); + if (input == NULL) { + fprintf(stderr,ERR"Memory allocation error."); + fclose(outFile); + return 1; + } + int i = 0; + c = fgetc(stdin); + while (feof(stdin) == 0) { + inputSize++; + if (i < BUF_SIZE) { + buffer[i] = c; + i++; + } else { + char *old = input; + input = realloc(input, inputSize); + if (input == NULL) { + fprintf(stderr,ERR"Memory allocation error."); + fclose(outFile); + free(old); + return 1; + } + memcpy(input + inputSize - BUF_SIZE,buffer,BUF_SIZE); + i = 0; + } + c = fgetc(stdin); + } + if (i > 0) { + char *old = input; + input = realloc(input, inputSize); + if (input == NULL) { + fprintf(stderr,ERR"Memory allocation error."); + fclose(outFile); + free(old); + return 1; + } + memcpy(input + inputSize - i,buffer,i); + } + decrypted = input; + decLen = inputSize; + } else { + // Open input file + FILE *inFile = fopen(inputFile,"rb"); + if (inFile == NULL || outFile == NULL) { + fprintf(stderr,ERR"Could not open input file!\n"); + return 1; + } + + // Read input file + fprintf(stderr,NOR"Reading input filesize...\n"); + decLen = fileSize(inFile); + fprintf(stderr,OK"File is %d bytes.\n",decLen); + decrypted = malloc(decLen); + + if (fread(decrypted,1,decLen,inFile) != decLen) { + fprintf(stderr,ERR"Error reading from file.\n"); + fclose(inFile); + fclose(outFile); + return 1; + } + fclose(inFile); + } + + fprintf(stderr,OK"Input read successfully!\n"); fprintf(stderr,NOR"Beginning encryption...\n"); // Generate a nonce, write headers and encrypted message + unsigned char nonce[crypto_secretbox_NONCEBYTES]; 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); + // Encrypt the data + unsigned char encrypted[decLen + crypto_secretbox_MACBYTES]; + crypto_secretbox_easy(encrypted, decrypted, decLen, nonce, key); + + // Patchy but correct-ish attempt to solve annoying stdout issue + size_t totalSize = strlen("gneurshk") + sizeof(salt) + sizeof(nonce) + sizeof(encrypted); + size_t offset = 0; + unsigned char* outputBuffer = malloc(totalSize); + if (outputBuffer == NULL) { + fprintf(stderr,ERR"Memory allocation error.\n"); return 1; } + memcpy(outputBuffer + offset, "gneurshk", strlen("gneurshk")); + offset += strlen("gneurshk"); - if (fwrite(salt,1,sizeof(salt),outFile) != sizeof(salt)) { - fprintf(stderr,ERR"Error writing salt to file.\n"); - fclose(inFile); - fclose(outFile); - return 1; - } + memcpy(outputBuffer + offset, salt, sizeof(salt)); + offset += sizeof(salt); - if (fwrite(nonce,1,sizeof(nonce),outFile) != sizeof(nonce)) { - fprintf(stderr,ERR"Error writing nonce to file.\n"); - fclose(inFile); - fclose(outFile); - return 1; - } + memcpy(outputBuffer + offset, nonce, sizeof(nonce)); + offset += sizeof(nonce); + + memcpy(outputBuffer + offset, encrypted, sizeof(encrypted)); - 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)) { + if(fwrite(outputBuffer, 1, totalSize, outFile) != totalSize) { fprintf(stderr,ERR"Error writing encrypted data to file.\n"); - fclose(inFile); fclose(outFile); return 1; } - - fclose(inFile); fclose(outFile); + free(decrypted); + free(outputBuffer); -fprintf(stderr,"\n"OK"File encrypted!\n"); + fprintf(stderr,"\n"OK"File encrypted!\n"); return 0; } @@ -126,13 +190,10 @@ int decryptMessage(const char* inputFile, const char* outputFile, const char* pa 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 inLen = fileSize(inFile); + size_t encLen = inLen - sizeof(salt) - sizeof(nonce) - 8; - size_t encLen = fileLen - sizeof(salt) - sizeof(nonce) - 8; - - fprintf(stderr,DBG"Size of encrypted file: %d bytes.\n",fileLen); + fprintf(stderr,DBG"Size of encrypted file: %d bytes.\n",inLen); fprintf(stderr,DBG"This means the encrypted content is %d bytes.\n",encLen); unsigned char encrypted[encLen]; @@ -217,7 +278,6 @@ int decryptMessage(const char* inputFile, const char* outputFile, const char* pa fprintf(stderr,"\n"OK"File decrypted!\n"); return 0; - } bool isFile(const char* filename) { @@ -245,6 +305,9 @@ int main(int argc, char *argv[]) { if (i+1 >= argc) { fprintf(stderr,ERR"Argument -in requires a file.\n"); exit = 1; + } else if (strcmp(argv[i+1],"-") == 0) { + in = -2; + i++; } else if (!isFile(argv[i+1])) { fprintf(stderr,ERR"File not found error: %s\n",argv[i+1]); exit = 1; @@ -300,8 +363,11 @@ int main(int argc, char *argv[]) { char psw[129]; if (in == -1) { - fprintf(stderr,ERR"No input file specified.\n"); - return 1; + fprintf(stderr,NOR"No input file, reading from stdin.\n"); + stdinput = true; + } else if (in == -2) { + fprintf(stderr,NOR"Reading from stdin.\n"); + stdinput = true; } else { snprintf(input,sizeof(input),argv[in]); } @@ -332,5 +398,4 @@ int main(int argc, char *argv[]) { } else { return encryptMessage(input,output,password); } - }