mirror of
https://gitlab.kit.edu/kit/scc/sys/mail/exim-encrypt-dlfunc.git
synced 2025-12-06 07:53:56 +01:00
Working version of libexim-encrypt-dlfunc-decrypt-secretbox
This commit is contained in:
11
src/common.c
11
src/common.c
@ -58,17 +58,14 @@ typedef struct {
|
|||||||
size_t length;
|
size_t length;
|
||||||
} Password;
|
} Password;
|
||||||
|
|
||||||
Password base64_decode_string(const char *input) {
|
void base64_decode_string(const char *input, unsigned char **outstring, size_t *outlen) {
|
||||||
Password p;
|
|
||||||
size_t input_len = strlen(input);
|
size_t input_len = strlen(input);
|
||||||
size_t outmaxlen = input_len / 4 * 3;
|
size_t outmaxlen = input_len / 4 * 3;
|
||||||
p.string = malloc(outmaxlen);
|
*outstring = malloc(outmaxlen * sizeof(unsigned char));
|
||||||
int b64err = sodium_base642bin(p.string, outmaxlen, (const char *) input, input_len,
|
int b64err = sodium_base642bin(*outstring, outmaxlen, (const char *) input, input_len,
|
||||||
NULL, &p.length, NULL, sodium_base64_VARIANT_ORIGINAL);
|
NULL, outlen, NULL, sodium_base64_VARIANT_ORIGINAL);
|
||||||
if (b64err != 0) {
|
if (b64err != 0) {
|
||||||
fprintf(stderr, "[ERROR] Unable to base64-decode the password\n");
|
fprintf(stderr, "[ERROR] Unable to base64-decode the password\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
@ -30,11 +30,11 @@ typedef enum {
|
|||||||
} seen_args;
|
} seen_args;
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
char* prog_basename = basename(argv[0]);
|
char *prog_basename = basename(argv[0]);
|
||||||
int opt;
|
int opt;
|
||||||
char *cipherstring;
|
char *cipherstring;
|
||||||
size_t pwlen;
|
size_t password_len;
|
||||||
char *b64password;
|
char *password;
|
||||||
char *password_env;
|
char *password_env;
|
||||||
|
|
||||||
seen_args mode = NONE;
|
seen_args mode = NONE;
|
||||||
@ -57,9 +57,9 @@ int main(int argc, char *argv[]) {
|
|||||||
// check environment for LIBEXIM_PASSWORD
|
// check environment for LIBEXIM_PASSWORD
|
||||||
password_env = getenv(ENVVAR_PASSWORD_NAME);
|
password_env = getenv(ENVVAR_PASSWORD_NAME);
|
||||||
if (password_env != NULL && strlen(password_env) > 0) {
|
if (password_env != NULL && strlen(password_env) > 0) {
|
||||||
pwlen = strlen(password_env);
|
password_len = strlen((const char *) password_env);
|
||||||
b64password = malloc(pwlen + 1);
|
password = malloc(password_len + 1);
|
||||||
strncpy(b64password, password_env, pwlen);
|
strncpy(password, password_env, password_len);
|
||||||
mode |= PASSENV;
|
mode |= PASSENV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,9 +69,9 @@ int main(int argc, char *argv[]) {
|
|||||||
long_options, &long_index)) != -1) {
|
long_options, &long_index)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'p':
|
case 'p':
|
||||||
pwlen = strlen(optarg);
|
password_len = strlen((const char *) optarg);
|
||||||
b64password = malloc(pwlen + 1);
|
password = malloc(password_len + 1);
|
||||||
strncpy(b64password, optarg, pwlen);
|
strncpy(password, optarg, password_len);
|
||||||
mode |= PASSARG;
|
mode |= PASSARG;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
@ -96,16 +96,45 @@ int main(int argc, char *argv[]) {
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fail if neither argument nor filename is present
|
// fail if neither argument nor filename for ciphertext is present
|
||||||
if (input == NONE) {
|
if (input == NONE) {
|
||||||
fprintf(stderr, "[ERROR] Please specify a ciphertext source.\n\n");
|
fprintf(stderr, "[ERROR] Please specify a ciphertext source.\n\n");
|
||||||
print_usage(prog_basename);
|
print_usage(prog_basename);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// base64-decode password
|
// Derive key from the password.
|
||||||
Password p;
|
unsigned char keybytes[crypto_secretbox_KEYBYTES];
|
||||||
p = base64_decode_string(b64password);
|
sodium_memzero(keybytes, crypto_secretbox_KEYBYTES);
|
||||||
|
crypto_generichash(keybytes, crypto_secretbox_KEYBYTES,
|
||||||
|
(unsigned char *) password, password_len, NULL, 0);
|
||||||
|
|
||||||
printf("»%s« [%zu]\n", p.string, p.length);
|
// base64-decode input
|
||||||
|
unsigned char *ciphertext;
|
||||||
|
size_t ciphertext_len;
|
||||||
|
base64_decode_string(cipherstring, &ciphertext, &ciphertext_len);
|
||||||
|
|
||||||
|
// extract nonce
|
||||||
|
unsigned char nonce[crypto_secretbox_NONCEBYTES];
|
||||||
|
memcpy(nonce, ciphertext, crypto_secretbox_NONCEBYTES);
|
||||||
|
|
||||||
|
// prepare buffer for cleartext
|
||||||
|
if (ciphertext_len < crypto_secretbox_NONCEBYTES + crypto_secretbox_MACBYTES) {
|
||||||
|
fprintf(stderr, "[ERROR] Ciphertext is too small to contain any data.\n\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
size_t cleartext_len = ciphertext_len - crypto_secretbox_NONCEBYTES - crypto_secretbox_MACBYTES;
|
||||||
|
unsigned char *cleartext = (unsigned char *) malloc(cleartext_len + 1);
|
||||||
|
sodium_memzero(cleartext, cleartext_len + 1);
|
||||||
|
|
||||||
|
// decrypt
|
||||||
|
if (crypto_secretbox_open_easy(cleartext, &ciphertext[crypto_secretbox_NONCEBYTES],
|
||||||
|
ciphertext_len - crypto_secretbox_NONCEBYTES, nonce, keybytes) == 0) {
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "[ERROR] Unable to decrypt message.\n\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// print cleartext to stdout
|
||||||
|
fprintf(stdout, "%s", (const char *) cleartext);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user