176 lines
3.7 KiB
C
176 lines
3.7 KiB
C
#include <errno.h>
|
|
#include<stdlib.h>
|
|
#include<stdio.h>
|
|
#include<libgen.h>
|
|
#include <sys/syslimits.h>
|
|
#include<string.h>
|
|
#include<pwd.h>
|
|
#include<unistd.h>
|
|
|
|
#include <openssl/evp.h>
|
|
#include <openssl/sha.h>
|
|
// crypto.h used for the version
|
|
#include <openssl/crypto.h>
|
|
#include <openssl/err.h>
|
|
|
|
#define READ_BUFFER 1024
|
|
|
|
struct ceb_header {
|
|
uint32_t version;
|
|
uint16_t app_len;
|
|
char* app;
|
|
uint16_t jid_len;
|
|
char* jid;
|
|
uint64_t timestamp;
|
|
uint8_t iv[12];
|
|
uint8_t salt[16];
|
|
};
|
|
|
|
int main(int argc, char* argv[]) {
|
|
if (argc < 2){
|
|
printf("Need 1 argument.");
|
|
exit(1);
|
|
}
|
|
|
|
// get filename
|
|
char* fn = argv[1];
|
|
|
|
// output file
|
|
char* output = "out.sqlgz";
|
|
if (argc > 2) output = argv[2];
|
|
|
|
struct ceb_header header;
|
|
|
|
// Open file
|
|
FILE* ceb = fopen(fn, "r");
|
|
if (ceb == NULL) {
|
|
perror("Couldn't open input file");
|
|
exit(errno);
|
|
}
|
|
|
|
// Read header
|
|
fread(&header.version, sizeof(uint32_t), 1, ceb);
|
|
header.version = ntohl(header.version);
|
|
|
|
// Read app
|
|
fread(&header.app_len, sizeof(uint16_t), 1, ceb);
|
|
header.app_len = ntohs(header.app_len);
|
|
header.app = malloc(header.app_len+1);
|
|
fread(header.app, sizeof(char), header.app_len, ceb);
|
|
header.app[header.app_len] = 0;
|
|
|
|
// Read JID
|
|
fread(&header.jid_len, sizeof(uint16_t), 1, ceb);
|
|
header.jid_len = ntohs(header.jid_len);
|
|
header.jid = malloc(header.jid_len+1);
|
|
fread(header.jid, sizeof(char), header.jid_len, ceb);
|
|
header.jid[header.jid_len] = 0;
|
|
|
|
// Read the reset of the struct
|
|
fread(&header.timestamp, sizeof(uint64_t)+12+16, 1, ceb);
|
|
|
|
printf("Version %d\n%s, %s\nCreated at %llu\n", header.version, header.app, header.jid, header.timestamp);
|
|
|
|
// Get password
|
|
char* pw = getpass("Password: ");
|
|
|
|
// Derive key
|
|
uint8_t key[128];
|
|
PKCS5_PBKDF2_HMAC_SHA1(pw, strlen(pw), header.salt, 16, 1024, 128, key);
|
|
|
|
// Read the whole file now
|
|
uint8_t* encrypted = malloc(READ_BUFFER);
|
|
if (encrypted == NULL) {
|
|
printf("Error allocating..\n");
|
|
return 1;
|
|
}
|
|
size_t bs = READ_BUFFER;
|
|
size_t pos = 0;
|
|
size_t nread = 0;
|
|
|
|
do {
|
|
// Perform read
|
|
nread = fread(encrypted+pos, sizeof(uint8_t), READ_BUFFER, ceb);
|
|
// Move position over by nread
|
|
pos += nread;
|
|
|
|
// If the position has reached the buffer size
|
|
if (pos >= bs) {
|
|
// Reallocate
|
|
encrypted = realloc(encrypted, pos+READ_BUFFER);
|
|
// Increase tracked buffer size
|
|
bs += READ_BUFFER;
|
|
if (encrypted == NULL) {
|
|
printf("Error allocating..\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
} while(nread != 0);
|
|
|
|
printf("Total read %ld bytes\n", pos);
|
|
|
|
// Reallocate
|
|
encrypted = realloc(encrypted, pos);
|
|
|
|
|
|
// Try perform decryption
|
|
uint8_t* plaintext = malloc(pos);
|
|
|
|
EVP_CIPHER_CTX *ctx;
|
|
|
|
// Create cipher context
|
|
if(!(ctx = EVP_CIPHER_CTX_new())) {
|
|
printf("Error creating decryption context\n");
|
|
ERR_print_errors_fp(stderr);
|
|
exit(1);
|
|
}
|
|
|
|
// Load key and iv
|
|
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, key, header.iv)){
|
|
printf("Could not DecryptInit!\n");
|
|
ERR_print_errors_fp(stderr);
|
|
exit(1);
|
|
}
|
|
|
|
// No padding
|
|
EVP_CIPHER_CTX_set_padding(ctx, 0);
|
|
|
|
// decryption
|
|
int dec_length = 0;
|
|
int plaintext_len = 0;
|
|
if (1 != EVP_DecryptUpdate(ctx, plaintext, &dec_length, encrypted, pos)){
|
|
printf("Could not DecryptUpdate!\n");
|
|
ERR_print_errors_fp(stderr);
|
|
exit(1);
|
|
}
|
|
plaintext_len += dec_length;
|
|
|
|
|
|
// finalize decryption
|
|
//if (1 != EVP_DecryptFinal_ex(ctx, plaintext+plaintext_len, &dec_length)) {
|
|
// printf("Could not DecryptFinal!\n");
|
|
// ERR_print_errors_fp(stderr);
|
|
// exit(1);
|
|
//}
|
|
|
|
// Cleanup
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
|
|
printf("Decrypted %d bytes\n", plaintext_len);
|
|
|
|
fclose(ceb);
|
|
|
|
// Write output file
|
|
FILE* outputf = fopen(output, "w");
|
|
if (outputf == NULL) {
|
|
perror("Couldn't open output file");
|
|
exit(errno);
|
|
}
|
|
|
|
fwrite(plaintext, sizeof(uint8_t), plaintext_len, outputf);
|
|
|
|
fclose(outputf);
|
|
|
|
return 0;
|
|
}
|