diff --git a/.gitignore b/.gitignore index 7f031d8..efd22c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ src/genkey -src/libexim-kitencrypt-dlfunc.so -src/recipient_sk.raw -src/recipient_sk.h +src/*.so +src/recipient_sk.* +src/recipient_pk.* +src/*.c~ diff --git a/src/Makefile b/src/Makefile index e8d2158..98543f6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,15 +3,20 @@ CFLAGS=-Wall LDFLAGS=-lsodium LDFLAGS_LIB=-I/usr/include/exim4 -fpic -shared -export-dynamic -.PHONY: clean +.PHONY: clean libs -.DEFAULT_GOAL := libexim-kitencrypt-dlfunc.so +.DEFAULT_GOAL := libs libexim-kitencrypt-dlfunc.so: libexim-kitencrypt-dlfunc.c recipient_pk.h $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_LIB) -o $@ $< +libexim-encrypt-dlfunc.so: libexim-encrypt-dlfunc.c + $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_LIB) -o $@ $< + genkey: genkey.c $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< clean: - rm -f libexim-kitencrypt-dlfunc.so + rm -f libexim-kitencrypt-dlfunc.so libexim-encrypt-dlfunc.so + +libs: libexim-kitencrypt-dlfunc.so libexim-encrypt-dlfunc.so diff --git a/src/libexim-encrypt-dlfunc.c b/src/libexim-encrypt-dlfunc.c new file mode 100644 index 0000000..1cfff78 --- /dev/null +++ b/src/libexim-encrypt-dlfunc.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include + +/* Local encryption key */ +#include "recipient_pk.h" + +/* Exim4 dlfunc API header */ +#include + +/* + * Encrypt the second argument with password from the first argument + */ +int sodium_crypto_secretbox(uschar ** yield, int argc, uschar * argv[]) +{ + if (sodium_init() == -1) { + *yield = string_copy(US "Unable to initialize libsodium"); + return ERROR; + } + if (argc != 2) { + *yield = + string_sprintf + ("Wrong number of arguments (got %i, expected 2)", argc); + return ERROR; + } + // get password + unsigned char *password = argv[0]; + size_t passwordlen = strlen((const char *)password); + + // get cleartext message + unsigned char *message = argv[1]; + size_t messagelen = strlen((const char *)message); + + /* + * Derive a key from the password. + * This operations needs to be fast (exim holds no state, this might be called once or mutliple times per email). + * Collisions avoidance or brute force arracks are not a concern here. + */ + unsigned char keybytes[crypto_secretbox_KEYBYTES]; + sodium_memzero(keybytes, crypto_secretbox_KEYBYTES); + crypto_generichash(keybytes, crypto_secretbox_KEYBYTES, + password, passwordlen, NULL, 0); + + // prepare buffer for ciphertext + unsigned int cipherlen = messagelen + crypto_secretbox_MACBYTES; + unsigned char *ciphertext = malloc(cipherlen); + sodium_memzero(ciphertext, cipherlen); + + // encrypt message + unsigned char nonce[crypto_secretbox_NONCEBYTES]; + randombytes_buf(nonce, sizeof nonce); + crypto_secretbox_easy(ciphertext, message, messagelen, nonce, keybytes); + + // base64-encode the ciphertext + unsigned int outputsize = sodium_base64_ENCODED_LEN(cipherlen, + sodium_base64_VARIANT_ORIGINAL); + unsigned char *outstring = malloc(outputsize); + sodium_memzero(outstring, outputsize); + sodium_bin2base64((char *const)outstring, outputsize, + ciphertext, cipherlen, + sodium_base64_VARIANT_ORIGINAL); + free(ciphertext); + + // return base64-encoded ciphertext + *yield = string_copy(outstring); + free(outstring); + return OK; +} diff --git a/src/libexim-kitencrypt-dlfunc.c b/src/libexim-kitencrypt-dlfunc.c index f341012..7020f49 100644 --- a/src/libexim-kitencrypt-dlfunc.c +++ b/src/libexim-kitencrypt-dlfunc.c @@ -40,9 +40,8 @@ int sodium_crypto_box_seal_kit(uschar ** yield, int argc, uschar * argv[]) crypto_box_seal(ciphertext, message, messagelen, recipient_pk); // base64-encode the ciphertext - unsigned int outputsize = - sodium_base64_ENCODED_LEN(cipherlen, - sodium_base64_VARIANT_ORIGINAL); + unsigned int outputsize = sodium_base64_ENCODED_LEN(cipherlen, + sodium_base64_VARIANT_ORIGINAL); unsigned char *outstring = malloc(outputsize); sodium_memzero(outstring, outputsize); @@ -57,51 +56,3 @@ int sodium_crypto_box_seal_kit(uschar ** yield, int argc, uschar * argv[]) return OK; } - -/* - * Encrypt first argument with passworf from the second argument - */ -/* -// https://libsodium.gitbook.io/doc/hashing/short-input_hashing -int sodium_crypto_box_seal_password(uschar **yield, int argc, uschar *argv[]) { - size_t messagelen; - unsigned char * message; - - if (sodium_init() == -1 ) { - *yield = string_copy(US"Unable to initialize libsodium"); - return ERROR; - } - if (argc != 2) { - *yield = string_sprintf("Wrong number of arguments (got %i, expected 1)", argc); - return ERROR; - } - - // get cleartext message - message = argv[0]; - messagelen = strlen((const char *) message); - - // prepare buffer for ciphertext - unsigned int cipherlen = messagelen + crypto_box_SEALBYTES; - unsigned char * ciphertext = malloc(cipherlen); - explicit_bzero(ciphertext, cipherlen); - - // encrypt message - crypto_box_seal(ciphertext, message, messagelen, recipient_pk); - - // base64-encode the ciphertext - unsigned int outputsize = sodium_base64_ENCODED_LEN(cipherlen, sodium_base64_VARIANT_ORIGINAL); - unsigned char * outstring = malloc(outputsize); - explicit_bzero(outstring, outputsize); - - sodium_bin2base64((char * const) outstring, outputsize, - ciphertext, cipherlen, - sodium_base64_VARIANT_ORIGINAL); - free(ciphertext); - - // return base64-encoded ciphertext - *yield = string_copy(outstring); - free(outstring); - - return OK; -} -*/