fish: Misc test cleanups

This commit is contained in:
Patrick Griffis 2021-07-15 20:30:45 -05:00
parent 91439f04c0
commit fee86de499
6 changed files with 62 additions and 267 deletions

View File

@ -1,17 +1,15 @@
subdir('old_version')
fishlim_test_sources = [ fishlim_test_sources = [
'tests.c', 'tests.c',
'fake/keystore.c', 'mock-keystore.c',
'../fish.c', '../fish.c',
'../utils.c', '../utils.c',
] ]
fishlim_tests = executable('fishlim_tests', fishlim_test_sources, fishlim_tests = executable('fishlim_tests', fishlim_test_sources,
dependencies: [libgio_dep, libssl_dep], dependencies: [libgio_dep, libssl_dep, hexchat_plugin_dep],
link_with : fishlim_old_lib include_directories: include_directories('..'),
) )
test('Fishlim Tests', fishlim_tests, test('Fishlim Tests', fishlim_tests,
timeout: 90 protocol: 'tap',
) )

View File

@ -1,5 +1,4 @@
/* /*
Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se> Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
@ -22,26 +21,31 @@
*/ */
#include "../../fish.h" #include "fish.h"
/** /**
* Extracts a key from the key store file. * Extracts a key from the key store file.
*/ */
char *keystore_get_key(const char *nick, enum fish_mode *mode) { char *
keystore_get_key(const char *nick, enum fish_mode *mode)
{
return NULL; return NULL;
} }
/** /**
* Sets a key in the key store file. * Sets a key in the key store file.
*/ */
gboolean keystore_store_key(const char *nick, const char *key, enum fish_mode mode) { gboolean
keystore_store_key(const char *nick, const char *key, enum fish_mode mode)
{
return TRUE; return TRUE;
} }
/** /**
* Deletes a nick from the key store. * Deletes a nick from the key store.
*/ */
gboolean keystore_delete_nick(const char *nick) { gboolean
keystore_delete_nick(const char *nick)
{
return TRUE; return TRUE;
} }

View File

@ -1,155 +0,0 @@
/*
Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifdef __APPLE__
#define __AVAILABILITYMACROS__
#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
#endif
#include <stdlib.h>
#include <string.h>
#include <openssl/blowfish.h>
#include "fish.h"
#define IB 64
static const char fish_base64[64] = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const signed char fish_unbase64[256] = {
IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB,IB,IB,
IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB,IB,IB,
/* ! " # $ % & ' ( ) * + , - . / */
IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB, 0, 1,
/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
2, 3, 4, 5, 6, 7, 8, 9, 10,11,IB,IB,IB,IB,IB,IB,
/* @ A B C D E F G H I J K L M N O */
IB,38,39,40,41,42,43,44, 45,46,47,48,49,50,51,52,
/* P Q R S T U V W X Y Z [ \ ] ^ _*/
53,54,55,56,57,58,59,60, 61,62,63,IB,IB,IB,IB,IB,
/* ` a b c d e f g h i j k l m n o */
IB,12,13,14,15,16,17,18, 19,20,21,22,23,24,25,26,
/* p q r s t u v w x y z { | } ~ <del> */
27,28,29,30,31,32,33,34, 35,36,37,IB,IB,IB,IB,IB,
};
#define GET_BYTES(dest, source) do { \
*((dest)++) = ((source) >> 24) & 0xFF; \
*((dest)++) = ((source) >> 16) & 0xFF; \
*((dest)++) = ((source) >> 8) & 0xFF; \
*((dest)++) = (source) & 0xFF; \
} while (0);
char *__old_fish_encrypt(const char *key, size_t keylen, const char *message) {
BF_KEY bfkey;
size_t messagelen;
size_t i;
int j;
char *encrypted;
char *end;
unsigned char bit;
unsigned char word;
unsigned char d;
BF_set_key(&bfkey, keylen, (const unsigned char*)key);
messagelen = strlen(message);
if (messagelen == 0) return NULL;
encrypted = g_malloc(((messagelen - 1) / 8) * 12 + 12 + 1); /* each 8-byte block becomes 12 bytes */
end = encrypted;
while (*message) {
/* Read 8 bytes (a Blowfish block) */
BF_LONG binary[2] = { 0, 0 };
unsigned char c;
for (i = 0; i < 8; i++) {
c = message[i];
binary[i >> 2] |= c << 8*(3 - (i&3));
if (c == '\0') break;
}
message += 8;
/* Encrypt block */
BF_encrypt(binary, &bfkey);
/* Emit FiSH-BASE64 */
bit = 0;
word = 1;
for (j = 0; j < 12; j++) {
d = fish_base64[(binary[word] >> bit) & 63];
*(end++) = d;
bit += 6;
if (j == 5) {
bit = 0;
word = 0;
}
}
/* Stop if a null terminator was found */
if (c == '\0') break;
}
*end = '\0';
return encrypted;
}
char *__old_fish_decrypt(const char *key, size_t keylen, const char *data) {
BF_KEY bfkey;
size_t i;
char *decrypted;
char *end;
unsigned char bit;
unsigned char word;
unsigned char d;
BF_set_key(&bfkey, keylen, (const unsigned char*)key);
decrypted = g_malloc(strlen(data) + 1);
end = decrypted;
while (*data) {
/* Convert from FiSH-BASE64 */
BF_LONG binary[2] = { 0, 0 };
bit = 0;
word = 1;
for (i = 0; i < 12; i++) {
d = fish_unbase64[(const unsigned char)*(data++)];
if (d == IB) goto decrypt_end;
binary[word] |= (unsigned long)d << bit;
bit += 6;
if (i == 5) {
bit = 0;
word = 0;
}
}
/* Decrypt block */
BF_decrypt(binary, &bfkey);
/* Copy to buffer */
GET_BYTES(end, binary[0]);
GET_BYTES(end, binary[1]);
}
decrypt_end:
*end = '\0';
return decrypted;
}

View File

@ -1,37 +0,0 @@
/*
Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef FISH_OLD_H
#define FISH_OLD_H
#include <stddef.h>
#include <glib.h>
char *__old_fish_encrypt(const char *key, size_t keylen, const char *message);
char *__old_fish_decrypt(const char *key, size_t keylen, const char *data);
#endif

View File

@ -1,4 +0,0 @@
fishlim_old_lib = shared_library('fishlim_old_lib',
['fish.c'],
dependencies: [libgio_dep, libssl_dep],
)

View File

@ -1,5 +1,4 @@
/* /*
Copyright (c) 2020 <bakasura@protonmail.ch> Copyright (c) 2020 <bakasura@protonmail.ch>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
@ -22,22 +21,19 @@
*/ */
#ifndef PLUGIN_HEXCHAT_FISHLIM_TEST_H
#define PLUGIN_HEXCHAT_FISHLIM_TEST_H
// Libs
#include <glib.h> #include <glib.h>
// Project Libs
#include "../fish.h" #include "fish.h"
#include "../utils.h" #include "utils.h"
#include "old_version/fish.h"
/** /**
* Auxiliary function: Generate a random string * Auxiliary function: Generate a random string
* @param out Preallocated string to fill * @param out Preallocated string to fill
* @param len Size of bytes to fill * @param len Size of bytes to fill
*/ */
void random_string(char *out, size_t len) { static void
random_string(char *out, size_t len)
{
GRand *rand = NULL; GRand *rand = NULL;
int i = 0; int i = 0;
@ -51,13 +47,14 @@ void random_string(char *out, size_t len) {
g_rand_free(rand); g_rand_free(rand);
} }
/** /**
* Check encrypt and decrypt in ECB mode and compare with old implementation * Check encrypt and decrypt in ECB mode
*/ */
void __ecb(void) { static void
char *bo64 = NULL, *b64 = NULL; test_ecb(void)
char *deo = NULL, *de = NULL; {
char *b64 = NULL;
char *de = NULL;
int key_len, message_len = 0; int key_len, message_len = 0;
char key[57]; char key[57];
char message[1000]; char message[1000];
@ -71,36 +68,20 @@ void __ecb(void) {
random_string(message, message_len); random_string(message, message_len);
/* Encrypt */ /* Encrypt */
bo64 = __old_fish_encrypt(key, key_len, message);
g_assert_nonnull(bo64);
b64 = fish_encrypt(key, key_len, message, message_len, FISH_ECB_MODE); b64 = fish_encrypt(key, key_len, message, message_len, FISH_ECB_MODE);
g_assert_nonnull(b64); g_assert_nonnull(b64);
g_assert_cmpuint(g_strcmp0(b64, bo64), == , 0);
/* Decrypt */ /* Decrypt */
/* Linear */ /* Linear */
deo = __old_fish_decrypt(key, key_len, bo64);
de = fish_decrypt_str(key, key_len, b64, FISH_ECB_MODE); de = fish_decrypt_str(key, key_len, b64, FISH_ECB_MODE);
g_assert_nonnull(deo); g_assert_cmpstr (de, ==, message);
g_assert_nonnull(de); g_free(de);
g_assert_cmpuint(g_strcmp0(de, message), == , 0);
g_assert_cmpuint(g_strcmp0(deo, message), == , 0); /* Mixed */
g_assert_cmpuint(g_strcmp0(de, deo), == , 0); de = fish_decrypt_str(key, key_len, b64, FISH_ECB_MODE);
g_free(deo); g_assert_cmpstr (de, ==, message);
g_free(de);
/* Mixed */
deo = __old_fish_decrypt(key, key_len, b64);
de = fish_decrypt_str(key, key_len, bo64, FISH_ECB_MODE);
g_assert_nonnull(deo);
g_assert_nonnull(de);
g_assert_cmpuint(g_strcmp0(de, message), == , 0);
g_assert_cmpuint(g_strcmp0(deo, message), == , 0);
g_assert_cmpuint(g_strcmp0(de, deo), == , 0);
g_free(deo);
g_free(de); g_free(de);
/* Free */
g_free(bo64);
g_free(b64); g_free(b64);
} }
} }
@ -109,7 +90,9 @@ void __ecb(void) {
/** /**
* Check encrypt and decrypt in CBC mode * Check encrypt and decrypt in CBC mode
*/ */
void __cbc(void) { static void
test_cbc(void)
{
char *b64 = NULL; char *b64 = NULL;
char *de = NULL; char *de = NULL;
int key_len, message_len = 0; int key_len, message_len = 0;
@ -131,11 +114,9 @@ void __cbc(void) {
/* Decrypt */ /* Decrypt */
/* Linear */ /* Linear */
de = fish_decrypt_str(key, key_len, b64, FISH_CBC_MODE); de = fish_decrypt_str(key, key_len, b64, FISH_CBC_MODE);
g_assert_nonnull(de); g_assert_cmpstr (de, ==, message);
g_assert_cmpuint(g_strcmp0(de, message), == , 0);
g_free(de); g_free(de);
/* Free */
g_free(b64); g_free(b64);
} }
} }
@ -144,13 +125,14 @@ void __cbc(void) {
/** /**
* Check the calculation of final length from an encoded string in Base64 * Check the calculation of final length from an encoded string in Base64
*/ */
void __base64_len(void) { static void
test_base64_len (void)
{
char *b64 = NULL; char *b64 = NULL;
int i, message_len = 0; int i, message_len = 0;
char message[1000]; char message[1000];
for (i = 0; i < 10; ++i) { for (i = 0; i < 10; ++i) {
for (message_len = 1; message_len < 1000; ++message_len) { for (message_len = 1; message_len < 1000; ++message_len) {
random_string(message, message_len); random_string(message, message_len);
b64 = g_base64_encode((const unsigned char *) message, message_len); b64 = g_base64_encode((const unsigned char *) message, message_len);
@ -164,7 +146,9 @@ void __base64_len(void) {
/** /**
* Check the calculation of final length from an encoded string in BlowcryptBase64 * Check the calculation of final length from an encoded string in BlowcryptBase64
*/ */
void __base64_fish_len(void) { static void
test_base64_fish_len (void)
{
char *b64 = NULL; char *b64 = NULL;
int i, message_len = 0; int i, message_len = 0;
char message[1000]; char message[1000];
@ -181,11 +165,12 @@ void __base64_fish_len(void) {
} }
} }
/** /**
* Check the calculation of final length from an encrypted string in ECB mode * Check the calculation of final length from an encrypted string in ECB mode
*/ */
void __base64_ecb_len(void) { static void
test_base64_ecb_len(void)
{
char *b64 = NULL; char *b64 = NULL;
int key_len, message_len = 0; int key_len, message_len = 0;
char key[57]; char key[57];
@ -209,7 +194,9 @@ void __base64_ecb_len(void) {
/** /**
* Check the calculation of final length from an encrypted string in CBC mode * Check the calculation of final length from an encrypted string in CBC mode
*/ */
void __base64_cbc_len(void) { static void
test_base64_cbc_len(void)
{
char *b64 = NULL; char *b64 = NULL;
int key_len, message_len = 0; int key_len, message_len = 0;
char key[57]; char key[57];
@ -233,7 +220,9 @@ void __base64_cbc_len(void) {
/** /**
* Check the calculation of length limit for a plaintext in each encryption mode * Check the calculation of length limit for a plaintext in each encryption mode
*/ */
void __max_text_command_len(void) { static void
test_max_text_command_len(void)
{
int max_encoded_len, plaintext_len; int max_encoded_len, plaintext_len;
enum fish_mode mode; enum fish_mode mode;
@ -248,7 +237,9 @@ void __max_text_command_len(void) {
/** /**
* Check the calculation of length limit for a plaintext in each encryption mode * Check the calculation of length limit for a plaintext in each encryption mode
*/ */
void __foreach_utf8_data_chunks(void) { static void
test_foreach_utf8_data_chunks(void)
{
GRand *rand = NULL; GRand *rand = NULL;
GString *chunks = NULL; GString *chunks = NULL;
int tests, max_chunks_len, chunks_len; int tests, max_chunks_len, chunks_len;
@ -277,21 +268,19 @@ void __foreach_utf8_data_chunks(void) {
} }
} }
int
int main(int argc, char *argv[]) { main(int argc, char *argv[]) {
g_test_init(&argc, &argv, NULL); g_test_init(&argc, &argv, NULL);
g_test_add_func("/fishlim/__ecb", __ecb); g_test_add_func("/fishlim/ecb", test_ecb);
g_test_add_func("/fishlim/__cbc", __ecb); g_test_add_func("/fishlim/cbc", test_cbc);
g_test_add_func("/fishlim/__base64_len", __base64_len); g_test_add_func("/fishlim/base64_len", test_base64_len);
g_test_add_func("/fishlim/__base64_fish_len", __base64_fish_len); g_test_add_func("/fishlim/base64_fish_len", test_base64_fish_len);
g_test_add_func("/fishlim/__base64_ecb_len", __base64_ecb_len); g_test_add_func("/fishlim/base64_ecb_len", test_base64_ecb_len);
g_test_add_func("/fishlim/__base64_cbc_len", __base64_cbc_len); g_test_add_func("/fishlim/base64_cbc_len", test_base64_cbc_len);
g_test_add_func("/fishlim/__max_text_command_len", __max_text_command_len); g_test_add_func("/fishlim/max_text_command_len", test_max_text_command_len);
g_test_add_func("/fishlim/__foreach_utf8_data_chunks", __foreach_utf8_data_chunks); g_test_add_func("/fishlim/foreach_utf8_data_chunks", test_foreach_utf8_data_chunks);
return g_test_run(); return g_test_run();
} }
#endif //PLUGIN_HEXCHAT_FISHLIM_TEST_H