diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..06ab994 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +src/secretkey.h +src/secretkey.bin +src/keygen diff --git a/src/exim4encrypt.c b/src/exim4encrypt.c index 26e0769..9f910f5 100644 --- a/src/exim4encrypt.c +++ b/src/exim4encrypt.c @@ -1,8 +1,49 @@ +#include +#include +#include #include "exim4encrypt.h" +#include "secretkey.h" -__attribute__((constructor)) static void init() { - sodium_init(); -} +int kitencrypt(uschar **yield, int argc, uschar *argv[]) { + int sinit; + size_t inputlen; + unsigned char * input; -int dlfunction(uschar **yield, int argc, uschar *argv[]) { + sinit = sodium_init(); + if (sinit == -1 ) { + *yield = string_sprintf("Unable to initialize libsodium"); + return ERROR; + } + if (argc != 1) { + *yield = string_sprintf("Wrong number of arguments (got %i, expected 1)", argc); + return ERROR; + } + + input = argv[0]; + inputlen = strlen(input); + + unsigned char nonce[crypto_secretbox_NONCEBYTES]; + randombytes_buf(nonce, sizeof nonce); + + unsigned int cipherlen = inputlen + crypto_secretbox_MACBYTES; + unsigned char * ciphertext = malloc(cipherlen); + explicit_bzero(ciphertext, cipherlen); + + crypto_secretbox_easy(ciphertext, input, inputlen, nonce, key); + + unsigned int outputsize = sodium_base64_ENCODED_LEN(cipherlen, sodium_base64_VARIANT_URLSAFE); + unsigned char * outstring = malloc(outputsize); + explicit_bzero(outstring, outputsize); + + sodium_bin2base64(outstring, outputsize, + ciphertext, cipherlen, + sodium_base64_VARIANT_URLSAFE); + + free(ciphertext); + + *yield = string_sprintf(outstring); + + free(outstring); + + return OK; } diff --git a/src/genkey.c b/src/genkey.c new file mode 100644 index 0000000..2b2062f --- /dev/null +++ b/src/genkey.c @@ -0,0 +1,49 @@ +#include + +void dumpkey(FILE* f, unsigned char * name, unsigned char * key, unsigned int keylen) { + fprintf(f, "const unsigned char %s[] = { ", name); + for(int i=0; i < keylen; i++) { + fprintf(f, "0x%02X", key[i]); + if (i < keylen-1) { + fprintf(f, ", "); + } + } + fprintf(f, " };\n"); +} + +int main(void) +{ + if (sodium_init() < 0) { + fputs("Unable to initialize libsodium", stderr); + exit(128); + } + + unsigned char key[crypto_secretbox_KEYBYTES]; + crypto_secretbox_keygen(key); + + FILE *keyfile = fopen("secretkey.h", "w+"); + if (keyfile == NULL) { + fputs("Unable to open secretkey.h", stderr); + exit(129); + } + + fputs("#ifndef EXIM4ENCRYPTSECRETKEY_H\n#define EXIM4ENCRYPTSECRETKEY_H\n\n", keyfile); + dumpkey(keyfile, "key", key, crypto_secretbox_KEYBYTES); + fprintf(keyfile, "unsigned int keylen = %u;\n", crypto_secretbox_KEYBYTES); + fputs("#endif // EXIM4ENCRYPTSECRETKEY_H\n", keyfile); + + fclose(keyfile); + + FILE *keyfilebin = fopen("secretkey.bin", "w+"); + if (keyfilebin == NULL) { + fputs("Unable to open secretkey.bin", stderr); + exit(129); + } + + fwrite(key, sizeof(key[0]), crypto_secretbox_KEYBYTES, keyfilebin); + + fclose(keyfilebin); + + exit(EXIT_SUCCESS); +} +