mirror of
https://gitlab.kit.edu/kit/scc/sys/mail/exim-encrypt-dlfunc.git
synced 2025-12-06 07:23:56 +01:00
Merge branch 'decryption_tools' into 'main'
Add decryption tools Closes #1 See merge request mail/exim-encrypt-dlfunc!4
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
/build
|
/build
|
||||||
|
debian/*.ex
|
||||||
|
|
||||||
|
|||||||
@ -21,8 +21,10 @@ stages:
|
|||||||
- cd ..
|
- cd ..
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- build/src/generate_encryption_keys
|
|
||||||
- build/src/libexim-encrypt-dlfunc.so
|
- build/src/libexim-encrypt-dlfunc.so
|
||||||
|
- build/src/libexim-encrypt-dlfunc-genkeys
|
||||||
|
- build/src/libexim-encrypt-dlfunc-decrypt-secretbox
|
||||||
|
#- build/src/libexim-encrypt-dlfunc-decrypt-sealedtbox
|
||||||
|
|
||||||
.debian-package:
|
.debian-package:
|
||||||
stage: debian-package
|
stage: debian-package
|
||||||
@ -37,31 +39,23 @@ stages:
|
|||||||
- ./*.changes
|
- ./*.changes
|
||||||
- ./*.buildinfo
|
- ./*.buildinfo
|
||||||
|
|
||||||
build:buster:
|
|
||||||
extends:
|
|
||||||
- .build
|
|
||||||
- .image-buster
|
|
||||||
needs: []
|
|
||||||
|
|
||||||
build:bullseye:
|
build:bullseye:
|
||||||
extends:
|
extends:
|
||||||
- .image-bullseye
|
- .image-bullseye
|
||||||
- .build
|
- .build
|
||||||
needs: []
|
needs: [ ]
|
||||||
|
|
||||||
build:focal:
|
build:focal:
|
||||||
extends:
|
extends:
|
||||||
- .image-focal
|
- .image-focal
|
||||||
- .build
|
- .build
|
||||||
needs: []
|
needs: [ ]
|
||||||
|
|
||||||
debian-package:buster:
|
build:buster:
|
||||||
extends:
|
extends:
|
||||||
|
- .build
|
||||||
- .image-buster
|
- .image-buster
|
||||||
- .debian-package
|
needs: [ ]
|
||||||
dependencies:
|
|
||||||
- build:buster
|
|
||||||
needs: ["build:buster"]
|
|
||||||
|
|
||||||
debian-package:bullseye:
|
debian-package:bullseye:
|
||||||
extends:
|
extends:
|
||||||
@ -69,7 +63,7 @@ debian-package:bullseye:
|
|||||||
- .debian-package
|
- .debian-package
|
||||||
dependencies:
|
dependencies:
|
||||||
- build:bullseye
|
- build:bullseye
|
||||||
needs: ["build:bullseye"]
|
needs: [ "build:bullseye" ]
|
||||||
|
|
||||||
debian-package:focal:
|
debian-package:focal:
|
||||||
extends:
|
extends:
|
||||||
@ -77,4 +71,12 @@ debian-package:focal:
|
|||||||
- .debian-package
|
- .debian-package
|
||||||
dependencies:
|
dependencies:
|
||||||
- build:focal
|
- build:focal
|
||||||
needs: ["build:focal"]
|
needs: [ "build:focal" ]
|
||||||
|
|
||||||
|
debian-package:buster:
|
||||||
|
extends:
|
||||||
|
- .image-buster
|
||||||
|
- .debian-package
|
||||||
|
dependencies:
|
||||||
|
- build:buster
|
||||||
|
needs: [ "build:buster" ]
|
||||||
|
|||||||
76
README.md
76
README.md
@ -44,7 +44,10 @@ meson compile -C build
|
|||||||
meson test -C build
|
meson test -C build
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Copy to final destination (feel free to pick another place than `/usr/local/lib/`):
|
The `ci_container` directory contains a [script](ci_container/build.sh) (and a [short README](ci_container/README.md))
|
||||||
|
which creates the images used in continous integration for this project.
|
||||||
|
|
||||||
|
5. Copy to final destination (feel free to pick another place than `/usr/lib/x86_64-linux-gnu/`):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
meson install -C build
|
meson install -C build
|
||||||
@ -54,9 +57,18 @@ meson install -C build
|
|||||||
|
|
||||||
Not every build of exim is able to load libraries at runtime. Please refer to the
|
Not every build of exim is able to load libraries at runtime. Please refer to the
|
||||||
[documentation](https://www.exim.org/exim-html-current/doc/html/spec_html/ch-string_expansions.html)
|
[documentation](https://www.exim.org/exim-html-current/doc/html/spec_html/ch-string_expansions.html)
|
||||||
of the `${dlfunc{…}}` function for details. The Debian package [`exim4-daemon-heavy`](https://packages.debian.org/exim4-daemon-heavy)
|
of the `${dlfunc{…}}` function for details. The Debian
|
||||||
|
package [`exim4-daemon-heavy`](https://packages.debian.org/exim4-daemon-heavy)
|
||||||
meets these requirements.
|
meets these requirements.
|
||||||
|
|
||||||
|
Try
|
||||||
|
|
||||||
|
```shell
|
||||||
|
exim4 --version | egrep -i --color 'Expand_dlfunc|Content_Scanning'
|
||||||
|
```
|
||||||
|
|
||||||
|
for a preliminary test.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
There are currently two pairs of complementary functions:
|
There are currently two pairs of complementary functions:
|
||||||
@ -74,11 +86,11 @@ Public key encryption that uses a key pair which needs to be created beforehand:
|
|||||||
* `sodium_crypto_box_seal_open(private key, public key, ciphertext) → cleartext`
|
* `sodium_crypto_box_seal_open(private key, public key, ciphertext) → cleartext`
|
||||||
|
|
||||||
The second pair needs a proper key pair in the correct format. This is what the
|
The second pair needs a proper key pair in the correct format. This is what the
|
||||||
`generate_encryption_keys` utility is for. Simply run it once to generate a pair. Be aware that every invocation will
|
`libexim-encrypt-dlfunc-genkeys` utility is for. Simply run it once to generate a pair. Be aware that every invocation will
|
||||||
overwrite the previous key pair file without confirmation! Make sure to store your production keys in a safe place.
|
overwrite the previous key pair file without confirmation! Make sure to store your production keys in a safe place.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ ./generate_encryption_keys
|
$ libexim-encrypt-dlfunc-genkeys
|
||||||
=== Creating cryptobox key pair ===
|
=== Creating cryptobox key pair ===
|
||||||
Wrote »cryptobox_recipient_pk_exim.conf«
|
Wrote »cryptobox_recipient_pk_exim.conf«
|
||||||
Wrote »cryptobox_recipient_pk.raw«
|
Wrote »cryptobox_recipient_pk.raw«
|
||||||
@ -107,11 +119,11 @@ original header is usually provided in these cases). Add this snippet to your DA
|
|||||||
```
|
```
|
||||||
warn log_message = Removing X-Originating-IP: header
|
warn log_message = Removing X-Originating-IP: header
|
||||||
condition = ${if def:h_X-originating-IP: {1}{0}}
|
condition = ${if def:h_X-originating-IP: {1}{0}}
|
||||||
add_header = X-Orig-IP-PKK: ${dlfunc{/usr/local/lib/libexim-encrypt-dlfunc.so} \
|
add_header = X-Orig-IP-PKK: ${dlfunc{/usr/lib/x86_64-linux-gnu/libexim-encrypt-dlfunc.so} \
|
||||||
{sodium_crypto_box_seal} \
|
{sodium_crypto_box_seal} \
|
||||||
{ktp1OEEItrgvSfpVTtu+ybyNjzuuN8OzCdfrGAJt4j8=} \
|
{ktp1OEEItrgvSfpVTtu+ybyNjzuuN8OzCdfrGAJt4j8=} \
|
||||||
{$h_X-originating-IP:}}
|
{$h_X-originating-IP:}}
|
||||||
add_header = X-Orig-IP-Pass: ${dlfunc{/usr/local/lib/libexim-encrypt-dlfunc.so} \
|
add_header = X-Orig-IP-Pass: ${dlfunc{/usr/lib/x86_64-linux-gnu/libexim-encrypt-dlfunc.so} \
|
||||||
{sodium_crypto_secretbox_encrypt_password} \
|
{sodium_crypto_secretbox_encrypt_password} \
|
||||||
{Insert your password here} \
|
{Insert your password here} \
|
||||||
{$h_X-originating-IP:}}
|
{$h_X-originating-IP:}}
|
||||||
@ -120,3 +132,55 @@ warn log_message = Removing X-Originating-IP: header
|
|||||||
```
|
```
|
||||||
|
|
||||||
Pick one of the `add_header` lines depending on which kind of encryption you want.
|
Pick one of the `add_header` lines depending on which kind of encryption you want.
|
||||||
|
|
||||||
|
### Decryption Tools
|
||||||
|
|
||||||
|
Two additional programs are included:
|
||||||
|
|
||||||
|
* `libexim-encrypt-dlfunc-decrypt-secretbox`
|
||||||
|
* `libexim-encrypt-dlfunc-decrypt-sealedbox`
|
||||||
|
|
||||||
|
They can decrypt strings that were encrypted by the two respective functions. Please refer to their `--help` message
|
||||||
|
(reproduced below) for usage information and to the [test](src/test_libexim-encrypt-dlfunc-decrypt-secretbox.sh)
|
||||||
|
[scripts](src/test_libexim-encrypt-dlfunc-decrypt-sealedbox.sh) for usage examples.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ libexim-encrypt-dlfunc-decrypt-secretbox -h
|
||||||
|
Usage: libexim-encrypt-dlfunc-decrypt-secretbox [OPTIONS] [CIPHERTEXT]
|
||||||
|
|
||||||
|
Password:
|
||||||
|
-p, --password PASSWORD Decrypt using PASSWORD
|
||||||
|
|
||||||
|
If the environment variable LIBEXIM_PASSWORD is set the password is read from there.
|
||||||
|
Setting a password with -p/--password overwrites this mechanism.
|
||||||
|
|
||||||
|
Select input:
|
||||||
|
-f, --infile FILE Decrypt contents of the first line of file FILE (use - for stdin)
|
||||||
|
|
||||||
|
Output:
|
||||||
|
-n, --no-newline Do not append a newline to the output
|
||||||
|
|
||||||
|
Password and ciphertext are expected to be base64-encoded (as produced by the library).
|
||||||
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ libexim-encrypt-dlfunc-decrypt-sealedbox -h
|
||||||
|
Usage: libexim-encrypt-dlfunc-decrypt-sealedbox [OPTIONS] [CIPHERTEXT]
|
||||||
|
|
||||||
|
Secret and public key:
|
||||||
|
-s, --secret-key SECRETKEY Secret key (base64-encoded)
|
||||||
|
-p, --public-key PUBLICKEY Public key (base64-encoded)
|
||||||
|
-S, --secret-key-file FILE Read secret key (raw) from file FILE (use - for stdin)
|
||||||
|
-P, --public-key-file FILE Read public key (raw) from file FILE (use - for stdin)
|
||||||
|
|
||||||
|
The environment variables LIBEXIM_SECRETKEY and LIBEXIM_PUBLICKEY may contain base64-encoded secret/public keys.
|
||||||
|
|
||||||
|
Select input:
|
||||||
|
-f, --infile FILE Decrypt contents of the first line of file FILE (use - for stdin)
|
||||||
|
|
||||||
|
Output:
|
||||||
|
-n, --no-newline Do not append a newline to the output
|
||||||
|
|
||||||
|
Keys in arguments and environment variables are expected to be base64 encoded (as produced by the library).
|
||||||
|
Keys in files need to be raw bytes with no encoding, ciphertext should always be base64-encoded.
|
||||||
|
```
|
||||||
@ -3,7 +3,7 @@
|
|||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
* [buildah](https://buildah.io/)
|
* [buildah](https://buildah.io/)
|
||||||
* {podman](https://podman.io/)
|
* [podman](https://podman.io/)
|
||||||
|
|
||||||
## Build and upload
|
## Build and upload
|
||||||
|
|
||||||
|
|||||||
@ -61,11 +61,14 @@ for i in "${images[@]}"; do
|
|||||||
openssl; \
|
openssl; \
|
||||||
DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical apt-get install -y \
|
DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical apt-get install -y \
|
||||||
debhelper \
|
debhelper \
|
||||||
dh-make \
|
|
||||||
devscripts \
|
|
||||||
git-buildpackage \
|
|
||||||
debsigs \
|
debsigs \
|
||||||
gpgv1; \
|
devscripts \
|
||||||
|
dh-make \
|
||||||
|
git-buildpackage \
|
||||||
|
gpgv1 \
|
||||||
|
meson; \
|
||||||
|
DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical apt-get install -y \
|
||||||
|
vim; \
|
||||||
rm -rf /var/lib/apt/lists/*;'
|
rm -rf /var/lib/apt/lists/*;'
|
||||||
buildah run "$ctr" /bin/sh -c \
|
buildah run "$ctr" /bin/sh -c \
|
||||||
'pip3 install meson ninja; \
|
'pip3 install meson ninja; \
|
||||||
|
|||||||
89
src/common.c
Normal file
89
src/common.c
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sodium.h>
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
//#define MIN_KEY_SIZE (crypto_box_SECRETKEYBYTES < crypto_box_PUBLICKEYBYTES ? crypto_box_SECRETKEYBYTES : crypto_box_PUBLICKEYBYTES)
|
||||||
|
//#define MAX_KEY_SIZE (crypto_box_SECRETKEYBYTES > crypto_box_PUBLICKEYBYTES ? crypto_box_SECRETKEYBYTES : crypto_box_PUBLICKEYBYTES)
|
||||||
|
|
||||||
|
char *read_first_line(const char *filename) {
|
||||||
|
FILE *stream;
|
||||||
|
char *cipherstring;
|
||||||
|
size_t len = 0;
|
||||||
|
ssize_t nread;
|
||||||
|
bool input_is_stdin = false;
|
||||||
|
|
||||||
|
// open file (use stdin for '-')
|
||||||
|
if (!strncmp(filename, "-", 1)) {
|
||||||
|
stream = stdin;
|
||||||
|
input_is_stdin = true;
|
||||||
|
} else {
|
||||||
|
stream = fopen(filename, "r");
|
||||||
|
if (stream == NULL) {
|
||||||
|
fprintf(stderr, "[ERROR] Error opening file %s\n\n", filename);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nread = getline(&cipherstring, &len, stream);
|
||||||
|
|
||||||
|
if (nread == -1 && !feof(stream)) {
|
||||||
|
perror("getline: ");
|
||||||
|
}
|
||||||
|
if (input_is_stdin == false) {
|
||||||
|
fclose(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove trailing newline
|
||||||
|
cipherstring[strcspn(cipherstring, "\r\n")] = 0;
|
||||||
|
|
||||||
|
return cipherstring;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *read_password_file(const char *filename, size_t keysize, size_t *length) {
|
||||||
|
FILE *stream;
|
||||||
|
char *contents;
|
||||||
|
ssize_t nread;
|
||||||
|
bool input_is_stdin = false;
|
||||||
|
|
||||||
|
contents = malloc(keysize + 1);
|
||||||
|
sodium_memzero(contents, keysize + 1);
|
||||||
|
|
||||||
|
// open file (use stdin for '-')
|
||||||
|
if (!strncmp(filename, "-", 1)) {
|
||||||
|
stream = stdin;
|
||||||
|
input_is_stdin = true;
|
||||||
|
} else {
|
||||||
|
stream = fopen(filename, "r");
|
||||||
|
if (stream == NULL) {
|
||||||
|
fprintf(stderr, "[ERROR] Error opening file %s\n\n", filename);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nread = fread(contents, sizeof(char), keysize, stream);
|
||||||
|
|
||||||
|
if (nread < 0) {
|
||||||
|
fprintf(stderr, "[ERROR] reading from %s failed\n\n", filename);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else {
|
||||||
|
*length = (size_t) nread;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input_is_stdin == false) {
|
||||||
|
fclose(stream);
|
||||||
|
}
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
int base64_decode_string(const char *input, unsigned char **outstring, size_t *outlen) {
|
||||||
|
size_t input_len = strlen(input);
|
||||||
|
size_t outmaxlen = input_len / 4 * 3;
|
||||||
|
*outstring = malloc(outmaxlen * sizeof(unsigned char));
|
||||||
|
return sodium_base642bin(*outstring, outmaxlen, (const char *) input, input_len,
|
||||||
|
NULL, outlen, NULL, sodium_base64_VARIANT_ORIGINAL);
|
||||||
|
}
|
||||||
14
src/common.h
Normal file
14
src/common.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// Created by sprawl on 08/09/2021.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef EXIM_ENCRYPT_DLFUNC_COMMON_H
|
||||||
|
#define EXIM_ENCRYPT_DLFUNC_COMMON_H
|
||||||
|
|
||||||
|
char *read_first_line(const char *filename);
|
||||||
|
|
||||||
|
char *read_password_file(const char *filename, size_t keysize, size_t *length);
|
||||||
|
|
||||||
|
int base64_decode_string(const char *input, unsigned char **outstring, size_t *outlen);
|
||||||
|
|
||||||
|
#endif //EXIM_ENCRYPT_DLFUNC_COMMON_H
|
||||||
@ -20,7 +20,7 @@ char *string2hex(unsigned char *input, size_t length) {
|
|||||||
* 1. Add this code to the first “breakpoint”:
|
* 1. Add this code to the first “breakpoint”:
|
||||||
* log_write(0, LOG_MAIN, "pid: %d", getpid()); int busywait = 0; while (busywait == 0) {}
|
* log_write(0, LOG_MAIN, "pid: %d", getpid()); int busywait = 0; while (busywait == 0) {}
|
||||||
* 2. Compile.
|
* 2. Compile.
|
||||||
* 3. Run “exim -be […]” to call the lib; see simple_exim_test.sh for details.
|
* 3. Run “exim -be […]” to call the lib; see test_libexim-encrypt-dlfunc.sh for details.
|
||||||
* 4. Read exim pid from log output. Attach to the looping exim process with “gdb -p PID”
|
* 4. Read exim pid from log output. Attach to the looping exim process with “gdb -p PID”
|
||||||
* 5. Prepare breakpoints, watches, etc. Set busywait to 1 and continue.
|
* 5. Prepare breakpoints, watches, etc. Set busywait to 1 and continue.
|
||||||
*/
|
*/
|
||||||
203
src/libexim-encrypt-dlfunc-decrypt-sealedbox.c
Normal file
203
src/libexim-encrypt-dlfunc-decrypt-sealedbox.c
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <sodium.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "common.c"
|
||||||
|
|
||||||
|
#define ENVVAR_SK_NAME "LIBEXIM_SECRETKEY"
|
||||||
|
#define ENVVAR_PK_NAME "LIBEXIM_PUBLICKEY"
|
||||||
|
|
||||||
|
void print_usage(char *progname) {
|
||||||
|
printf("Usage: %s [OPTIONS] [CIPHERTEXT]\n\n", progname);
|
||||||
|
printf("Secret and public key:\n");
|
||||||
|
printf(" -s, --secret-key SECRETKEY Secret key (base64-encoded)\n");
|
||||||
|
printf(" -p, --public-key PUBLICKEY Public key (base64-encoded)\n");
|
||||||
|
printf(" -S, --secret-key-file FILE Read secret key (raw) from file FILE (use - for stdin)\n");
|
||||||
|
printf(" -P, --public-key-file FILE Read public key (raw) from file FILE (use - for stdin)\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("The environment variables %s and %s may contain base64-encoded secret/public keys. \n", ENVVAR_SK_NAME,
|
||||||
|
ENVVAR_PK_NAME);
|
||||||
|
printf("\n");
|
||||||
|
printf("Select input:\n");
|
||||||
|
printf(" -f, --infile FILE Decrypt contents of the first line of file FILE (use - for stdin)\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Output:\n");
|
||||||
|
printf(" -n, --no-newline Do not append a newline to the output\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Keys in arguments and environment variables are expected to be base64 encoded (as produced by the library).\n");
|
||||||
|
printf("Keys in files need to be raw bytes with no encoding, ciphertext should always be base64-encoded.\n");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NONE = 0,
|
||||||
|
SK = 1,
|
||||||
|
PK = 2,
|
||||||
|
SKENV = 4,
|
||||||
|
PKENV = 8,
|
||||||
|
SKFILE = 16,
|
||||||
|
PKFILE = 32,
|
||||||
|
INFILE = 64,
|
||||||
|
INSTRING = 128
|
||||||
|
} seen_sb_args;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
char *prog_basename = basename(argv[0]);
|
||||||
|
int opt = 0;
|
||||||
|
unsigned char *secretkey, *publickey;
|
||||||
|
size_t secretkey_len = 0, publickey_len = 0;
|
||||||
|
char *b64cipherstring;
|
||||||
|
unsigned char *cipherstring;
|
||||||
|
size_t cipherstring_len;
|
||||||
|
bool add_newline = true;
|
||||||
|
|
||||||
|
seen_sb_args publickey_mode = NONE;
|
||||||
|
seen_sb_args secretkey_mode = NONE;
|
||||||
|
seen_sb_args input = NONE;
|
||||||
|
|
||||||
|
if (sodium_init() < 0) {
|
||||||
|
fputs("Unable to initialize libsodium", stderr);
|
||||||
|
exit(128);
|
||||||
|
}
|
||||||
|
|
||||||
|
// define arguments
|
||||||
|
const char *shortargs = "s:p:S:P:f:nh";
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"secret-key", required_argument, NULL, 's'},
|
||||||
|
{"public-key", required_argument, NULL, 'p'},
|
||||||
|
{"secret-key-file", required_argument, NULL, 'S'},
|
||||||
|
{"public-key-file", required_argument, NULL, 'P'},
|
||||||
|
{"infile", required_argument, NULL, 'f'},
|
||||||
|
{"no-newline", required_argument, NULL, 'n'},
|
||||||
|
{"help", no_argument, NULL, 'h'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
// check environment for LIBEXIM_SECRETKEY variable
|
||||||
|
char *sk_env = getenv(ENVVAR_SK_NAME);
|
||||||
|
if (sk_env != NULL && strlen(sk_env) > 0) {
|
||||||
|
if (base64_decode_string(sk_env, &secretkey, &secretkey_len) != 0) {
|
||||||
|
fprintf(stderr, "[ERROR] Unable to base64-decode secret key.\n\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
secretkey_mode |= SKENV;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check environment for LIBEXIM_PUBLICKEY variable
|
||||||
|
char *pk_env = getenv(ENVVAR_PK_NAME);
|
||||||
|
if (pk_env != NULL && strlen(pk_env) > 0) {
|
||||||
|
if (base64_decode_string(pk_env, &publickey, &publickey_len) != 0) {
|
||||||
|
fprintf(stderr, "[ERROR] Unable to base64-decode public key.\n\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
publickey_mode |= PKENV;
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse arguments
|
||||||
|
int long_index = 0;
|
||||||
|
while ((opt = getopt_long(argc, argv, shortargs,
|
||||||
|
long_options, &long_index)) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 's':
|
||||||
|
if (base64_decode_string(optarg, &secretkey, &secretkey_len) != 0) {
|
||||||
|
fprintf(stderr, "[ERROR] Unable to base64-decode secret key.\n\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
secretkey_mode |= SK;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
if (base64_decode_string(optarg, &publickey, &publickey_len) != 0) {
|
||||||
|
fprintf(stderr, "[ERROR] Unable to base64-decode public key.\n\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
publickey_mode |= PK;
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
secretkey = (unsigned char *) read_password_file(optarg, crypto_box_SECRETKEYBYTES, &secretkey_len);
|
||||||
|
secretkey_mode |= SKFILE;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
publickey = (unsigned char *) read_password_file(optarg, crypto_box_PUBLICKEYBYTES, &publickey_len);
|
||||||
|
publickey_mode |= PKFILE;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
b64cipherstring = read_first_line(optarg);
|
||||||
|
input |= INFILE;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
add_newline = false;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
print_usage(prog_basename);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// read first non-option argument as ciphertext if present
|
||||||
|
if (optind < argc) {
|
||||||
|
size_t b64cipherstring_len = strlen(argv[optind]);
|
||||||
|
b64cipherstring = malloc(b64cipherstring_len);
|
||||||
|
sodium_memzero(b64cipherstring, b64cipherstring_len);
|
||||||
|
strncpy(b64cipherstring, argv[optind], b64cipherstring_len);
|
||||||
|
input |= INSTRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if a secret key was provided
|
||||||
|
if (secretkey_mode == NONE) {
|
||||||
|
fprintf(stderr, "[ERROR] Please specify a secret key.\n\n");
|
||||||
|
print_usage(prog_basename);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
// check if the secret key has the correct size
|
||||||
|
if (secretkey_len != crypto_box_SECRETKEYBYTES) {
|
||||||
|
fprintf(stderr, "[ERROR] Secret key has wrong size %zu; expected %d.\n\n", secretkey_len,
|
||||||
|
crypto_box_SECRETKEYBYTES);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if a public key was provided
|
||||||
|
if (publickey_mode == NONE) {
|
||||||
|
fprintf(stderr, "[ERROR] Please specify a public key.\n\n");
|
||||||
|
print_usage(prog_basename);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
// check if the public key has the correct size
|
||||||
|
if (publickey_len != crypto_box_PUBLICKEYBYTES) {
|
||||||
|
fprintf(stderr, "[ERROR] Secret key has wrong size %zu; expected %d.\n\n", publickey_len,
|
||||||
|
crypto_box_PUBLICKEYBYTES);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if a ciphertext was provided
|
||||||
|
if (input == NONE) {
|
||||||
|
fprintf(stderr, "[ERROR] Please specify a ciphertext source.\n\n");
|
||||||
|
print_usage(prog_basename);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
// base64-decode ciphertext
|
||||||
|
if (base64_decode_string(b64cipherstring, &cipherstring, &cipherstring_len) != 0) {
|
||||||
|
fprintf(stderr, "[ERROR] Unable to base64-decode ciphertext.\n\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
// prepare buffer for cleartext
|
||||||
|
size_t cleartext_len = cipherstring_len - crypto_box_SEALBYTES;
|
||||||
|
unsigned char *cleartext = (unsigned char *) malloc(cleartext_len + 1);
|
||||||
|
sodium_memzero(cleartext, cleartext_len + 1);
|
||||||
|
|
||||||
|
// decrypt message
|
||||||
|
if (crypto_box_seal_open(cleartext, cipherstring, cipherstring_len, publickey, secretkey) != 0) {
|
||||||
|
fprintf(stderr, "[ERROR] Unable to decrypt ciphertext.\n\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// print cleartext to stdout
|
||||||
|
if (add_newline == true) {
|
||||||
|
fprintf(stdout, "%s\n", (const char *) cleartext);
|
||||||
|
} else {
|
||||||
|
fprintf(stdout, "%s", (const char *) cleartext);
|
||||||
|
}
|
||||||
|
}
|
||||||
161
src/libexim-encrypt-dlfunc-decrypt-secretbox.c
Normal file
161
src/libexim-encrypt-dlfunc-decrypt-secretbox.c
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <sodium.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "common.c"
|
||||||
|
|
||||||
|
#define ENVVAR_PASSWORD_NAME "LIBEXIM_PASSWORD"
|
||||||
|
|
||||||
|
void print_usage(char *progname) {
|
||||||
|
printf("Usage: %s [OPTIONS] [CIPHERTEXT]\n\n", progname);
|
||||||
|
printf("Password:\n");
|
||||||
|
printf(" -p, --password PASSWORD Decrypt using PASSWORD\n");
|
||||||
|
printf("\n");
|
||||||
|
printf(" If the environment variable LIBEXIM_PASSWORD is set the password is read from there.\n");
|
||||||
|
printf(" Setting a password with -p/--password overwrites this mechanism.\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Select input:\n");
|
||||||
|
printf(" -f, --infile FILE Decrypt contents of the first line of file FILE (use - for stdin)\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Output:\n");
|
||||||
|
printf(" -n, --no-newline Do not append a newline to the output\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Password and ciphertext are expected to be base64-encoded (as produced by the library).\n");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NONE = 0,
|
||||||
|
PASSARG = 1,
|
||||||
|
PASSENV = 2,
|
||||||
|
INSTRING = 4,
|
||||||
|
INFILE = 8
|
||||||
|
} seen_args;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
char *prog_basename = basename(argv[0]);
|
||||||
|
int opt;
|
||||||
|
char *cipherstring;
|
||||||
|
size_t password_len;
|
||||||
|
char *password;
|
||||||
|
char *password_env;
|
||||||
|
bool add_newline = true;
|
||||||
|
|
||||||
|
seen_args mode = NONE;
|
||||||
|
seen_args input = NONE;
|
||||||
|
|
||||||
|
if (sodium_init() < 0) {
|
||||||
|
fputs("Unable to initialize libsodium", stderr);
|
||||||
|
exit(128);
|
||||||
|
}
|
||||||
|
|
||||||
|
// define arguments
|
||||||
|
const char *shortargs = "p:f:nh";
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"password", required_argument, NULL, 'p'},
|
||||||
|
{"infile", required_argument, NULL, 'f'},
|
||||||
|
{"no-newline", no_argument, NULL, 'n'},
|
||||||
|
{"help", no_argument, NULL, 'h'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
// check environment for LIBEXIM_PASSWORD
|
||||||
|
password_env = getenv(ENVVAR_PASSWORD_NAME);
|
||||||
|
if (password_env != NULL && strlen(password_env) > 0) {
|
||||||
|
password = password_env;
|
||||||
|
password_len = strlen(password);
|
||||||
|
mode |= PASSENV;
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse arguments
|
||||||
|
int long_index = 0;
|
||||||
|
while ((opt = getopt_long(argc, argv, shortargs,
|
||||||
|
long_options, &long_index)) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'p':
|
||||||
|
password_len = strlen((const char *) optarg);
|
||||||
|
password = malloc(password_len + 1);
|
||||||
|
strncpy(password, optarg, password_len);
|
||||||
|
mode |= PASSARG;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
cipherstring = read_first_line(optarg);
|
||||||
|
input |= INFILE;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
add_newline = false;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
print_usage(prog_basename);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// read first non-option argument as ciphertext if present
|
||||||
|
if (optind < argc) {
|
||||||
|
size_t cipherstring_len = strlen(argv[optind]) + 1;
|
||||||
|
cipherstring = malloc(cipherstring_len + 1);
|
||||||
|
strncpy(cipherstring, argv[optind], cipherstring_len);
|
||||||
|
input |= INSTRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if a password was provided
|
||||||
|
if (mode == NONE) {
|
||||||
|
fprintf(stderr, "[ERROR] Please specify a password.\n\n");
|
||||||
|
print_usage(prog_basename);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fail if neither argument nor filename for ciphertext is present
|
||||||
|
if (input == NONE) {
|
||||||
|
fprintf(stderr, "[ERROR] Please specify a ciphertext source.\n\n");
|
||||||
|
print_usage(prog_basename);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Derive key from the password.
|
||||||
|
unsigned char keybytes[crypto_secretbox_KEYBYTES];
|
||||||
|
sodium_memzero(keybytes, crypto_secretbox_KEYBYTES);
|
||||||
|
crypto_generichash(keybytes, crypto_secretbox_KEYBYTES,
|
||||||
|
(unsigned char *) password, password_len, NULL, 0);
|
||||||
|
|
||||||
|
// base64-decode input
|
||||||
|
unsigned char *ciphertext;
|
||||||
|
size_t ciphertext_len;
|
||||||
|
if (base64_decode_string(cipherstring, &ciphertext, &ciphertext_len) != 0) {
|
||||||
|
fprintf(stderr, "[ERROR] Unable to base64-decode ciphertext.\n\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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
|
||||||
|
if (add_newline == true) {
|
||||||
|
fprintf(stdout, "%s\n", (const char *) cleartext);
|
||||||
|
} else {
|
||||||
|
fprintf(stdout, "%s", (const char *) cleartext);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,14 @@
|
|||||||
configure_file(output: 'config.h', configuration: conf_data)
|
configure_file(output: 'config.h', configuration: conf_data)
|
||||||
|
|
||||||
executable('generate_encryption_keys', 'generate_encryption_keys.c',
|
executable('libexim-encrypt-dlfunc-genkeys', 'libexim-encrypt-dlfunc-genkeys.c',
|
||||||
|
dependencies : [ sodium_deps ],
|
||||||
|
install: true)
|
||||||
|
|
||||||
|
executable('libexim-encrypt-dlfunc-decrypt-sealedbox', 'libexim-encrypt-dlfunc-decrypt-sealedbox.c',
|
||||||
|
dependencies : [ sodium_deps ],
|
||||||
|
install: true)
|
||||||
|
|
||||||
|
executable('libexim-encrypt-dlfunc-decrypt-secretbox', 'libexim-encrypt-dlfunc-decrypt-secretbox.c',
|
||||||
dependencies : [ sodium_deps ],
|
dependencies : [ sodium_deps ],
|
||||||
install: true)
|
install: true)
|
||||||
|
|
||||||
@ -8,7 +16,14 @@ shared_library('exim-encrypt-dlfunc', 'libexim-encrypt-dlfunc.c',
|
|||||||
dependencies : [ sodium_deps ],
|
dependencies : [ sodium_deps ],
|
||||||
install: true)
|
install: true)
|
||||||
|
|
||||||
|
test('libexim-encrypt-dlfunc',
|
||||||
|
find_program('test_libexim-encrypt-dlfunc.sh'),
|
||||||
|
protocol: 'tap')
|
||||||
|
|
||||||
simple_exim_test = find_program('simple_exim_test.sh')
|
test('decrypt-secretbox',
|
||||||
test('simple test', simple_exim_test)
|
find_program('test_libexim-encrypt-dlfunc-decrypt-secretbox.sh'),
|
||||||
|
protocol: 'tap')
|
||||||
|
|
||||||
|
test('decrypt-sealedbox',
|
||||||
|
find_program('test_libexim-encrypt-dlfunc-decrypt-sealedbox.sh'),
|
||||||
|
protocol: 'tap')
|
||||||
46
src/test_libexim-encrypt-dlfunc-decrypt-sealedbox.sh
Executable file
46
src/test_libexim-encrypt-dlfunc-decrypt-sealedbox.sh
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
# this script implements the TAP protocol (https://testanything.org)
|
||||||
|
echo 1..3
|
||||||
|
|
||||||
|
TEST_PUBLICKEY='z7+GlUWgoiXJ4VK6cdLikCF7M6Mj9i4eXNE6Jh1m9yw='
|
||||||
|
TEST_SECRETKEY='h5C/V2nzhILRmJ6UZrNK/6G8Xc4KWzLq/Qr8Xj42jus='
|
||||||
|
TEST_CLEARTEXT='There is nothing in the middle of the road but a yellow stripe and dead armadillos. ~ Jim Hightower'
|
||||||
|
TEST_CIPHERTEXT='+UgXgarCuX3dUobgt8rRnjnxPNWHpsw98GjLZy8+2m5e/v9K/acMq+0UsFW7lwAZIRqj1F55n78y73Y6XCBEVSt8G6nntV8WuDYlr1BHcBIXNr5toUbE+CxtLoGqfD3c3nw1NkJDO1NYGzK/cG43TEEBLrQJCRLRBXOZmxG6ugFo4FtYl297/B1xNtkd9IR4TY5C'
|
||||||
|
CIPHERTEXT_FILE="$(mktemp)"
|
||||||
|
TEST_PUBLICKEY_FILE="$(mktemp)"
|
||||||
|
TEST_SECRETKEY_FILE="$(mktemp)"
|
||||||
|
echo -n "${TEST_CIPHERTEXT}" > "${CIPHERTEXT_FILE}"
|
||||||
|
echo -n "${TEST_PUBLICKEY}" | base64 -d > "${TEST_PUBLICKEY_FILE}"
|
||||||
|
echo -n "${TEST_SECRETKEY}" | base64 -d > "${TEST_SECRETKEY_FILE}"
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
rm -rf "${CIPHERTEXT_FILE}" "${TEST_PUBLICKEY_FILE}" "${TEST_SECRETKEY_FILE}"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
|
export LIBEXIM_PUBLICKEY="${TEST_PUBLICKEY}"
|
||||||
|
export LIBEXIM_SECRETKEY="${TEST_SECRETKEY}"
|
||||||
|
|
||||||
|
DECRYPTED="$(src/libexim-encrypt-dlfunc-decrypt-sealedbox "${TEST_CIPHERTEXT}")"
|
||||||
|
if [ "${DECRYPTED}" == "${TEST_CLEARTEXT}" ] ; then
|
||||||
|
echo "ok 1 - decrypt commandline argument with keys from environment successful"
|
||||||
|
else
|
||||||
|
echo "not ok 1 - decrypt commandline argument with keys from environment unsuccessful"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export -n LIBEXIM_PUBLICKEY LIBEXIM_SECRETKEY
|
||||||
|
|
||||||
|
DECRYPTED="$(src/libexim-encrypt-dlfunc-decrypt-sealedbox --secret-key "${TEST_SECRETKEY}" --public-key "${TEST_PUBLICKEY}" --infile "${CIPHERTEXT_FILE}")"
|
||||||
|
if [ "${DECRYPTED}" == "${TEST_CLEARTEXT}" ] ; then
|
||||||
|
echo "ok 2 - decrypt file contents with keys from commandline"
|
||||||
|
else
|
||||||
|
echo "not ok 2 - decrypt file contents with keys from commandline"
|
||||||
|
fi
|
||||||
|
|
||||||
|
DECRYPTED="$(src/libexim-encrypt-dlfunc-decrypt-sealedbox --secret-key-file "${TEST_SECRETKEY_FILE}" --public-key-file "${TEST_PUBLICKEY_FILE}" --infile - < "${CIPHERTEXT_FILE}")"
|
||||||
|
if [ "${DECRYPTED}" == "${TEST_CLEARTEXT}" ] ; then
|
||||||
|
echo "ok 3 - decrypt stdin contents with keys from files"
|
||||||
|
else
|
||||||
|
echo "not ok 3 - decrypt stdin contents with keys from files"
|
||||||
|
fi
|
||||||
57
src/test_libexim-encrypt-dlfunc-decrypt-secretbox.sh
Executable file
57
src/test_libexim-encrypt-dlfunc-decrypt-secretbox.sh
Executable file
@ -0,0 +1,57 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
# this script implements the TAP protocol (https://testanything.org)
|
||||||
|
echo 1..5
|
||||||
|
|
||||||
|
TEST_PASSWORD='be6rahqu3bukee3Aengohgoopheeyis5'
|
||||||
|
TEST_CLEARTEXT='The great thing about attackers is that there are so many to choose from! - Daniel J. Bernstein'
|
||||||
|
TEST_CIPHERTEXT01='K+TOzrbkni7wydNvF1gMRwZWQPNnNIXRG9iQgkFhszBu8ImqIrAK4wWWP02UmclITi8DZbr3sg/EVWurDzAYK+pjkcDAa78glz4qXIqrPbYvEIEHPEExFzCtwi5hqOR+KF7tsqbPvdAOIqwf/2KBomX0GS1I/1CxQMrbJd1VgXc51M4hI0I8'
|
||||||
|
TEST_CIPHERTEXT02='lAod5UhfW6fQCxd4PSktnrzwyWzcw05Svio5XqPOr/p/Ts4Pr0eEjj2TgmT2K85T2xrxCiqmE/OUcODRldEWeSqBSxx0Z6PzXqOzz5ZL6Iq1tggjihMydGz9mNS4jRF9f52k5t2i7xFrMMCRrfq/rer/ngp1h3pposCds+OmX0u+1f4Urj0b'
|
||||||
|
CIPHERTEXT_FILE01="$(mktemp)"
|
||||||
|
CIPHERTEXT_FILE02="$(mktemp)"
|
||||||
|
echo -n "${TEST_CIPHERTEXT01}" > "${CIPHERTEXT_FILE01}"
|
||||||
|
echo -n "${TEST_CIPHERTEXT02}" > "${CIPHERTEXT_FILE02}"
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
rm -rf "${CIPHERTEXT_FILE01}" "${CIPHERTEXT_FILE02}"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
|
||||||
|
export LIBEXIM_PASSWORD="${TEST_PASSWORD}"
|
||||||
|
|
||||||
|
DECRYPTED01="$(src/libexim-encrypt-dlfunc-decrypt-secretbox ${TEST_CIPHERTEXT01})"
|
||||||
|
if [ "${DECRYPTED01}" == "${TEST_CLEARTEXT}" ] ; then
|
||||||
|
echo "ok 1 - decrypt commandline argument with password from environment successful"
|
||||||
|
else
|
||||||
|
echo "not ok 1 - decrypt commandline argument with password from environment unsuccessful"
|
||||||
|
fi
|
||||||
|
|
||||||
|
DECRYPTED02="$(src/libexim-encrypt-dlfunc-decrypt-secretbox --infile ${CIPHERTEXT_FILE01})"
|
||||||
|
if [ "${DECRYPTED02}" == "${TEST_CLEARTEXT}" ] ; then
|
||||||
|
echo "ok 2 - decrypt file contents with password from environment successful"
|
||||||
|
else
|
||||||
|
echo "not ok 2 - decrypt file contents with password from environment unsuccessful"
|
||||||
|
fi
|
||||||
|
|
||||||
|
DECRYPTED03="$(echo -n ${TEST_CIPHERTEXT01} | src/libexim-encrypt-dlfunc-decrypt-secretbox --infile -)"
|
||||||
|
if [ "${DECRYPTED03}" == "${TEST_CLEARTEXT}" ] ; then
|
||||||
|
echo "ok 3 - decrypt stdin contents with password from environment successful"
|
||||||
|
else
|
||||||
|
echo "not ok 3 - decrypt stdin file contents with password from environment unsuccessful"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export -n LIBEXIM_PASSWORD
|
||||||
|
|
||||||
|
DECRYPTED04="$(src/libexim-encrypt-dlfunc-decrypt-secretbox -p ${TEST_PASSWORD} ${TEST_CIPHERTEXT02})"
|
||||||
|
if [ "${DECRYPTED04}" == "${TEST_CLEARTEXT}" ] ; then
|
||||||
|
echo "ok 4 - decrypt commandline argument with password from commandline successful"
|
||||||
|
else
|
||||||
|
echo "not ok 4 - decrypt commandline argument with password from commandline unsuccessful"
|
||||||
|
fi
|
||||||
|
|
||||||
|
DECRYPTED05="$(src/libexim-encrypt-dlfunc-decrypt-secretbox -p ${TEST_PASSWORD} --infile ${CIPHERTEXT_FILE02})"
|
||||||
|
if [ "${DECRYPTED05}" == "${TEST_CLEARTEXT}" ] ; then
|
||||||
|
echo "ok 5 - decrypt file contents with password from commandline successful"
|
||||||
|
else
|
||||||
|
echo "not ok 5 - decrypt file contents with password from commandline unsuccessful"
|
||||||
|
fi
|
||||||
@ -1,24 +1,24 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
PATH=/sbin:/usr/sbin:$PATH
|
PATH=/sbin:/usr/sbin:$PATH
|
||||||
|
|
||||||
|
# this script implements the TAP protocol (https://testanything.org)
|
||||||
|
echo 1..2
|
||||||
|
|
||||||
# copy to /tmp to keep call to exim under 256 chars (prevent problems on Ubuntu)
|
# copy to /tmp to keep call to exim under 256 chars (prevent problems on Ubuntu)
|
||||||
install -t /tmp src/libexim-encrypt-dlfunc.so
|
install -t /tmp src/libexim-encrypt-dlfunc.so
|
||||||
|
|
||||||
LIB=/tmp/libexim-encrypt-dlfunc.so
|
LIB=/tmp/libexim-encrypt-dlfunc.so
|
||||||
CLEARTEXT="127.88.99.23" # keep short; see above
|
CLEARTEXT="127.88.99.23" # keep short; see above
|
||||||
PASSWORD="`openssl rand -base64 32`"
|
PASSWORD="$(openssl rand -base64 32)"
|
||||||
|
|
||||||
CIPHERTEXT=$(exim -be "\${dlfunc{${LIB}}{sodium_crypto_secretbox_encrypt_password}{${PASSWORD}}{${CLEARTEXT}}}")
|
CIPHERTEXT=$(exim -be "\${dlfunc{${LIB}}{sodium_crypto_secretbox_encrypt_password}{${PASSWORD}}{${CLEARTEXT}}}")
|
||||||
DECRYPTED=$(exim -be "\${dlfunc{${LIB}}{sodium_crypto_secretbox_decrypt_password}{${PASSWORD}}{${CIPHERTEXT}}}")
|
DECRYPTED=$(exim -be "\${dlfunc{${LIB}}{sodium_crypto_secretbox_decrypt_password}{${PASSWORD}}{${CIPHERTEXT}}}")
|
||||||
|
|
||||||
if [ "${CLEARTEXT}" == "${DECRYPTED}" ] ; then
|
if [ "${CLEARTEXT}" == "${DECRYPTED}" ] ; then
|
||||||
echo "secretbox test successful"
|
echo "ok 1 - secretbox test successful"
|
||||||
else
|
else
|
||||||
echo "secretbox test unsuccessful"
|
echo "not ok 1 - secretbox test unsuccessful"
|
||||||
exit 127
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# { 0xb6, 0x01, 0x45, 0x20, 0x9f, 0x55, 0x06, 0x74, 0x29, 0x71, 0x7b, 0x5e, 0xa9, 0x68, 0x60, 0x5e, 0x81, 0x1a, 0x54, 0x6b, 0xc9, 0x80, 0x97, 0x78, 0x41, 0xc6, 0x20, 0xae, 0x66, 0x9f, 0xd9, 0x53 };
|
# { 0xb6, 0x01, 0x45, 0x20, 0x9f, 0x55, 0x06, 0x74, 0x29, 0x71, 0x7b, 0x5e, 0xa9, 0x68, 0x60, 0x5e, 0x81, 0x1a, 0x54, 0x6b, 0xc9, 0x80, 0x97, 0x78, 0x41, 0xc6, 0x20, 0xae, 0x66, 0x9f, 0xd9, 0x53 };
|
||||||
@ -30,8 +30,7 @@ CIPHERTEXT=$(exim -be "\${dlfunc{${LIB}}{sodium_crypto_box_seal}{${PK}}{${CLEART
|
|||||||
DECRYPTED=$(exim -be "\${dlfunc{${LIB}}{sodium_crypto_box_seal_open}{${SK}}{${PK}}{${CIPHERTEXT}}}")
|
DECRYPTED=$(exim -be "\${dlfunc{${LIB}}{sodium_crypto_box_seal_open}{${SK}}{${PK}}{${CIPHERTEXT}}}")
|
||||||
|
|
||||||
if [ "${CLEARTEXT}" == "${DECRYPTED}" ] ; then
|
if [ "${CLEARTEXT}" == "${DECRYPTED}" ] ; then
|
||||||
echo "sealed_box test successful"
|
echo "ok 2 - sealed_box test successful"
|
||||||
else
|
else
|
||||||
echo "sealed_box test unsuccessful"
|
echo "ok 2 - sealed_box test unsuccessful"
|
||||||
exit 128
|
|
||||||
fi
|
fi
|
||||||
Reference in New Issue
Block a user