mirror of
https://gitlab.kit.edu/kit/scc/sys/mail/exim-encrypt-dlfunc.git
synced 2025-12-06 08:33:56 +01:00
First working version of sodium_crypto_secretbox_encrypt_password() and
sodium_crypto_secretbox_decrypt_password().
This commit is contained in:
@ -3,67 +3,131 @@
|
|||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
|
|
||||||
/* Local encryption key */
|
|
||||||
#include "recipient_pk.h"
|
|
||||||
|
|
||||||
/* Exim4 dlfunc API header */
|
/* Exim4 dlfunc API header */
|
||||||
#include <local_scan.h>
|
#include <local_scan.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encrypt the second argument with password from the first argument
|
* Encrypt the second argument with password string from the first argument
|
||||||
|
* using crypto_secretbox_easy().
|
||||||
*/
|
*/
|
||||||
int sodium_crypto_secretbox(uschar ** yield, int argc, uschar * argv[])
|
int sodium_crypto_secretbox_encrypt_password(uschar **yield, int argc, uschar *argv[]) {
|
||||||
{
|
// ensure libsodium is initialized
|
||||||
if (sodium_init() == -1) {
|
if (sodium_init() == -1) {
|
||||||
*yield = string_copy(US "Unable to initialize libsodium");
|
*yield = string_copy(US
|
||||||
return ERROR;
|
"Unable to initialize libsodium");
|
||||||
}
|
return ERROR;
|
||||||
if (argc != 2) {
|
}
|
||||||
*yield =
|
// check argument count
|
||||||
string_sprintf
|
if (argc != 2) {
|
||||||
("Wrong number of arguments (got %i, expected 2)", argc);
|
*yield = string_sprintf("Wrong number of arguments (got %i, expected 2)", argc);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
// get password
|
// get password argument
|
||||||
unsigned char *password = argv[0];
|
unsigned char *password = argv[0];
|
||||||
size_t passwordlen = strlen((const char *)password);
|
size_t passwordlen = strlen((const char *) password);
|
||||||
|
|
||||||
// get cleartext message
|
// get cleartext message argument
|
||||||
unsigned char *message = argv[1];
|
unsigned char *message = argv[1];
|
||||||
size_t messagelen = strlen((const char *)message);
|
size_t messagelen = strlen((const char *) message);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Derive a key from the password.
|
* Derive a key from the password using a generic hash.
|
||||||
* This operations needs to be fast (exim holds no state, this might be called once or mutliple times per email).
|
* This operations needs to be fast (exim holds no state, this might be called once or multiple times per email).
|
||||||
* Collisions avoidance or brute force arracks are not a concern here.
|
* Collisions avoidance or brute force attacks are not a concern here.
|
||||||
*/
|
*/
|
||||||
unsigned char keybytes[crypto_secretbox_KEYBYTES];
|
unsigned char keybytes[crypto_secretbox_KEYBYTES];
|
||||||
sodium_memzero(keybytes, crypto_secretbox_KEYBYTES);
|
sodium_memzero(keybytes, crypto_secretbox_KEYBYTES);
|
||||||
crypto_generichash(keybytes, crypto_secretbox_KEYBYTES,
|
crypto_generichash(keybytes, crypto_secretbox_KEYBYTES,
|
||||||
password, passwordlen, NULL, 0);
|
password, passwordlen, NULL, 0);
|
||||||
|
|
||||||
// prepare buffer for ciphertext
|
// prepare buffer for ciphertext
|
||||||
unsigned int cipherlen = messagelen + crypto_secretbox_MACBYTES;
|
unsigned int cipherlen = messagelen + crypto_secretbox_MACBYTES;
|
||||||
unsigned char *ciphertext = malloc(cipherlen);
|
unsigned char *ciphertext = (unsigned char *) store_get(cipherlen);
|
||||||
sodium_memzero(ciphertext, cipherlen);
|
sodium_memzero(ciphertext, cipherlen);
|
||||||
|
|
||||||
// encrypt message
|
// encrypt message
|
||||||
unsigned char nonce[crypto_secretbox_NONCEBYTES];
|
unsigned char nonce[crypto_secretbox_NONCEBYTES];
|
||||||
randombytes_buf(nonce, sizeof nonce);
|
randombytes_buf(nonce, sizeof nonce);
|
||||||
crypto_secretbox_easy(ciphertext, message, messagelen, nonce, keybytes);
|
crypto_secretbox_easy(ciphertext, message, messagelen, nonce, keybytes);
|
||||||
|
|
||||||
// base64-encode the ciphertext
|
// combine nonce and ciphertext
|
||||||
unsigned int outputsize = sodium_base64_ENCODED_LEN(cipherlen,
|
size_t combined_message_len = crypto_secretbox_NONCEBYTES + cipherlen;
|
||||||
sodium_base64_VARIANT_ORIGINAL);
|
unsigned char * combined_message = store_get(combined_message_len);
|
||||||
unsigned char *outstring = malloc(outputsize);
|
memcpy(combined_message, nonce, crypto_secretbox_NONCEBYTES);
|
||||||
sodium_memzero(outstring, outputsize);
|
memcpy(&combined_message[crypto_secretbox_NONCEBYTES], ciphertext, cipherlen);
|
||||||
sodium_bin2base64((char *const)outstring, outputsize,
|
|
||||||
ciphertext, cipherlen,
|
|
||||||
sodium_base64_VARIANT_ORIGINAL);
|
|
||||||
free(ciphertext);
|
|
||||||
|
|
||||||
// return base64-encoded ciphertext
|
// base64-encode the ciphertext
|
||||||
*yield = string_copy(outstring);
|
unsigned int outputsize = sodium_base64_ENCODED_LEN(combined_message_len,
|
||||||
free(outstring);
|
sodium_base64_VARIANT_ORIGINAL);
|
||||||
return OK;
|
unsigned char *outstring = (unsigned char *) store_get(outputsize);
|
||||||
|
sodium_memzero(outstring, outputsize);
|
||||||
|
sodium_bin2base64((char *const) outstring, outputsize,
|
||||||
|
combined_message, combined_message_len,
|
||||||
|
sodium_base64_VARIANT_ORIGINAL);
|
||||||
|
|
||||||
|
// return base64-encoded ciphertext
|
||||||
|
*yield = string_copy(outstring);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decrypt the second argument with password string from the first argument
|
||||||
|
* using crypto_secretbox_open_easy().
|
||||||
|
*/
|
||||||
|
int sodium_crypto_secretbox_decrypt_password(uschar ** yield, int argc, uschar * argv[])
|
||||||
|
{
|
||||||
|
// ensure libsodium is initialized
|
||||||
|
if (sodium_init() == -1) {
|
||||||
|
*yield = string_copy(US "Unable to initialize libsodium");
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
// check argument count
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Derive key from the password.
|
||||||
|
unsigned char keybytes[crypto_secretbox_KEYBYTES];
|
||||||
|
sodium_memzero(keybytes, crypto_secretbox_KEYBYTES);
|
||||||
|
crypto_generichash(keybytes, crypto_secretbox_KEYBYTES,
|
||||||
|
password, passwordlen, NULL, 0);
|
||||||
|
|
||||||
|
// get base64 encoded ciphertext message
|
||||||
|
unsigned char *ciphertextb64 = argv[1];
|
||||||
|
size_t ciphertextb64len = strlen((const char *) ciphertextb64);
|
||||||
|
|
||||||
|
// base64-decode the ciphertext
|
||||||
|
unsigned int combined_message_len = ciphertextb64len / 4 * 3;
|
||||||
|
unsigned char *combined_message = (unsigned char *) store_get(combined_message_len);
|
||||||
|
sodium_memzero(combined_message, combined_message_len);
|
||||||
|
sodium_base642bin(combined_message, combined_message_len,
|
||||||
|
(const char *) ciphertextb64, ciphertextb64len,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
sodium_base64_VARIANT_ORIGINAL);
|
||||||
|
|
||||||
|
// extract nonce
|
||||||
|
unsigned char nonce[crypto_secretbox_NONCEBYTES];
|
||||||
|
memcpy(nonce, combined_message, crypto_secretbox_NONCEBYTES);
|
||||||
|
|
||||||
|
// prepare buffer for cleartext
|
||||||
|
unsigned int cleartextlen = combined_message_len - crypto_secretbox_NONCEBYTES - crypto_secretbox_MACBYTES;
|
||||||
|
unsigned char *cleartext = (unsigned char *) store_get(cleartextlen+1);
|
||||||
|
sodium_memzero(cleartext, cleartextlen+1);
|
||||||
|
|
||||||
|
// decrypt message
|
||||||
|
if (crypto_secretbox_open_easy(cleartext, &combined_message[crypto_secretbox_NONCEBYTES],
|
||||||
|
combined_message_len - crypto_secretbox_NONCEBYTES, nonce, keybytes) != 0) {
|
||||||
|
*yield = string_copy((unsigned char *) "Unable to decrypt.");
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return base64-encoded ciphertext
|
||||||
|
*yield = string_copy(cleartext);
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,34 +3,36 @@
|
|||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
|
|
||||||
/* Local encryption key */
|
|
||||||
#include "recipient_pk.h"
|
|
||||||
|
|
||||||
/* Exim4 dlfunc API header */
|
/* Exim4 dlfunc API header */
|
||||||
#include <local_scan.h>
|
#include <local_scan.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Encrypt first argument with fixed public key from recipient_pk.h
|
* Encrypt the second argument with the public key from the first argument
|
||||||
*/
|
*/
|
||||||
int sodium_crypto_box_seal_kit(uschar ** yield, int argc, uschar * argv[])
|
|
||||||
|
/*
|
||||||
|
int sodium_crypto_box_seal(uschar ** yield, int argc, uschar * argv[])
|
||||||
{
|
{
|
||||||
size_t messagelen;
|
size_t messagelen;
|
||||||
unsigned char *message;
|
unsigned char *message, *key;
|
||||||
|
|
||||||
if (sodium_init() == -1) {
|
if (sodium_init() == -1) {
|
||||||
*yield = string_copy(US "Unable to initialize libsodium");
|
*yield = string_copy(US "Unable to initialize libsodium");
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
if (argc != 1) {
|
if (argc != 2) {
|
||||||
*yield =
|
*yield =
|
||||||
string_sprintf
|
string_sprintf
|
||||||
("Wrong number of arguments (got %i, expected 1)", argc);
|
("Wrong number of arguments (got %i, expected 2)", argc);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
// get cleartext message
|
// get cleartext message
|
||||||
message = argv[0];
|
message = argv[0];
|
||||||
messagelen = strlen((const char *)message);
|
messagelen = strlen((const char *)message);
|
||||||
|
|
||||||
|
// get key
|
||||||
|
key = argv[1];
|
||||||
|
|
||||||
// prepare buffer for ciphertext
|
// prepare buffer for ciphertext
|
||||||
unsigned int cipherlen = messagelen + crypto_box_SEALBYTES;
|
unsigned int cipherlen = messagelen + crypto_box_SEALBYTES;
|
||||||
unsigned char *ciphertext = malloc(cipherlen);
|
unsigned char *ciphertext = malloc(cipherlen);
|
||||||
@ -56,3 +58,4 @@ int sodium_crypto_box_seal_kit(uschar ** yield, int argc, uschar * argv[])
|
|||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
Reference in New Issue
Block a user