Add new aesgcm.c and script, modify README

This commit is contained in:
Travis Burtrum 2016-04-19 00:37:45 -04:00
parent b78982dac4
commit ab577eccef
3 changed files with 103 additions and 23 deletions

View File

@ -3,25 +3,10 @@ When [Conversations](https://conversations.im) uploads an encrypted image with [
The anchor is made of 96 characters which represent 48 bytes in HEX. The first 16 bytes are the IV the last 32 bytes are the key.
The encryption mode is ```aes-gcm```. The authentcation tag of 16 bytes is appended to the file.
The encryption mode is ```aes-256-gcm```. The authentication tag of 16 bytes is appended to the file.
This Java project provides sample code on how to download and dercypt a file. Output is to stdout. Redirect to file or pipe to image viewer.
This C project provides sample code on how to decrypt a file. Output is to stdout. Redirect to file or pipe to image viewer.
Compile with ```mvn package```
Compile with ```gcc aesgcm.c -lcrypto -o aesgcm```, openbrowser.sh also tries to compile it if the executable not already exist.
Find a compiled version [here](https://gultsch.de/ImageDownloader-0.1.jar)
Usage: ```java -jar ImageDownloader.jar http://host.tld/path/to/file.jpg#theivandkey```
If you change your browser in gajim to something like this script it will automatically open image links in your image viewer if you click on them.
```
#!/bin/bash
URL=$1
BROWSER=firefox
JAVA=/usr/lib/jvm/java-8-openjdk/bin/java
IMAGE_DOWNLOADER=/home/daniel/Projects/ImageDownloader/t
if [ ${URL: -97:1} == "#" ]; then
$JAVA -jar $IMAGE_DOWNLOADER $URL | feh -. -
else
$BROWSER $URL
```
Set openbrowser.sh as your browser in gajim or another XMPP client to automatically decrypt http uploads encrypted with OMEMO or PGP with Conversations.

90
aesgcm.c Normal file
View File

@ -0,0 +1,90 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <openssl/evp.h>
#define BYTES_PER_READ 32 * 1024 // 32kb
#define INITIAL_BUFFER_SIZE 256 * 1024 // 256kb, must be at least 2*BYTES_PER_READ
void hex2string(char *src, unsigned char **dst_p)
{
*dst_p = malloc(strlen(src)/2);
unsigned char *dst = *dst_p;
unsigned char *end = dst + (strlen(src)/2);
unsigned int u;
while (dst < end && sscanf(src, "%2x", &u) == 1) {
*dst++ = u;
src += 2;
}
}
int main(int argc, char **argv)
{
unsigned char *gcm_ivkey, *gcm_ct, *gcm_pt;
int outlen, rv, final_outlen;
size_t read, actual_size = 0, total_size = INITIAL_BUFFER_SIZE;
if (argc < 2) {
printf("Usage: %s <key>\n", argv[0]);
return 1;
}
hex2string(argv[1], &gcm_ivkey);
gcm_ct = malloc(total_size);
while ((read = fread(gcm_ct + actual_size, 1, BYTES_PER_READ, stdin)) > 0) {
actual_size += read;
if ((actual_size + BYTES_PER_READ) > total_size) {
total_size = total_size * 1.5;
gcm_ct = realloc(gcm_ct,total_size);
}
}
if (actual_size < 32) {
fprintf(stderr, "File too small for decryption\n");
return 1;
}
actual_size -= 16;
gcm_pt = malloc(actual_size);
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
/* Select cipher */
EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
/* Set IV length, omit for 96 bits */
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL);
/* Specify key and IV */
EVP_DecryptInit_ex(ctx, NULL, NULL, gcm_ivkey+16, gcm_ivkey);
/* Decrypt plaintext */
EVP_DecryptUpdate(ctx, gcm_pt, &outlen, gcm_ct, actual_size);
/* Set expected tag value. */
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, gcm_ct + actual_size);
/* Finalise: note get no output for GCM */
rv = EVP_DecryptFinal_ex(ctx, gcm_pt, &final_outlen);
EVP_CIPHER_CTX_free(ctx);
free(gcm_ivkey);
free(gcm_ct);
if (rv > 0) {
// success!
fwrite(gcm_pt, 1, outlen, stdout);
free(gcm_pt);
return 0;
} else {
fprintf(stderr, "File integrity check failed\n");
free(gcm_pt);
return 1;
}
}
// compile with: gcc aesgcm.c -lcrypto -o aesgcm

View File

@ -1,10 +1,15 @@
#!/bin/bash
set -e
URL=$1
BROWSER=firefox
JAVA=/usr/lib/jvm/java-8-openjdk/bin/java
IMAGE_DOWNLOADER=/home/daniel/Projects/ImageDownloader/target/ImageDownloader-0.1.jar
if [ ${URL: -97:1} == "#" ]; then
$JAVA -jar $IMAGE_DOWNLOADER $URL | feh -. -
AES_GCM="$(dirname $(readlink -f $0))/aesgcm"
if [ ${URL: -97:1} == "#" ]
then
[ -e "$AES_GCM" ] || gcc "$(dirname $(readlink -f $0))/aesgcm.c" -lcrypto -o "$AES_GCM"
curl "$URL" | "$AES_GCM" "${URL: -96}" | feh -. -
elif echo $URL | grep -i '\.pgp$'
then
curl "$URL" | gpg2 -d | feh -. -
else
$BROWSER $URL
fi