@@ -3,6 +3,7 @@ | |||
#include <sys/param.h> | |||
#include <arpa/inet.h> | |||
#include <sodium.h> | |||
#include "../inc/libchat6.h" | |||
#include "../inc/lc6_helpers.h" | |||
@@ -11,17 +12,31 @@ | |||
#include "../inc/lc6_debug.h" | |||
#endif | |||
#define LC6_CRYPTO_HASHLEN crypto_generichash_BYTES | |||
#define LC6_CRYPTO_HASHSIGNLEN (crypto_secretbox_NONCEBYTES+crypto_box_MACBYTES+crypto_generichash_BYTES) | |||
#define LC6_CRYPTO_PUBLEN crypto_kx_PUBLICKEYBYTES | |||
#define LC6_CRYPTO_PRIVLEN crypto_kx_SECRETKEYBYTES | |||
#define LC6_CRYPTO_RXLEN crypto_kx_SESSIONKEYBYTES | |||
#define LC6_CRYPTO_TXLEN crypto_kx_SESSIONKEYBYTES | |||
typedef struct LC6_NODE { | |||
unsigned char *pub_key; | |||
unsigned char *priv_key; | |||
} LC6_NODE; | |||
typedef struct LC6_PEER { | |||
int sock; | |||
LC6_NODE keys; | |||
unsigned char bufi[65536]; | |||
unsigned char bufo[65536]; | |||
} LC6_PEER; | |||
typedef struct LC6_USER { | |||
struct LC6_USER *prev; | |||
struct LC6_USER *next; | |||
unsigned char nickname[256]; | |||
unsigned char pub_key[32]; | |||
unsigned char priv_key[32]; | |||
unsigned char pub_key[LC6_CRYPTO_PUBLEN]; | |||
unsigned char priv_key[LC6_CRYPTO_PRIVLEN]; | |||
uint8_t status; | |||
} LC6_USER; | |||
@@ -29,7 +44,9 @@ typedef struct LC6_FRIEND { | |||
struct LC6_FRIEND *prev; | |||
struct LC6_FRIEND *next; | |||
unsigned char nickname[256]; | |||
unsigned char pub_key[32]; | |||
unsigned char pub_key[LC6_CRYPTO_PUBLEN]; | |||
unsigned char key_rx[LC6_CRYPTO_RXLEN]; | |||
unsigned char key_tx[LC6_CRYPTO_TXLEN]; | |||
uint8_t status; | |||
} LC6_FRIEND; | |||
@@ -49,10 +66,10 @@ enum LC6_MSG_TYPE_ENUM { | |||
LC6_MSG_TYPE_CLIENT_ONLINE, | |||
LC6_MSG_TYPE_CLIENT_UPDATE, | |||
LC6_MSG_TYPE_CLIENT_OFFLINE, | |||
LC6_MSG_TYPE_KEEPALIVE_QUERY, | |||
LC6_MSG_TYPE_KEEPALIVE_REQUEST, | |||
LC6_MSG_TYPE_KEEPALIVE_RESPONSE, | |||
LC6_MSG_TYPE_FRIEND_REQUEST, | |||
LC6_MSG_TYPE_FRIEND_CONFIRM, | |||
LC6_MSG_TYPE_FRIEND_RESPONSE, | |||
LC6_MSG_TYPE_MESSAGE_SEND, | |||
LC6_MSG_TYPE_MESSAGE_RECV, | |||
LC6_MSG_TYPE_MESSAGE_READ, | |||
@@ -102,8 +119,9 @@ typedef struct LC6_BOOTSTRAP { | |||
typedef struct LC6_CTX { | |||
char path[MAXPATHLEN-LC6_CONFIG_MAXLEN]; | |||
LIBCHAT_CB *callback; | |||
LC6_USER *user; | |||
LC6_USER *node; | |||
LC6_NODE *node; | |||
LC6_FRIEND *friend; | |||
LC6_BOOTSTRAP *bootstrap; | |||
} LC6_CTX; |
@@ -6,6 +6,9 @@ | |||
int lc6crypto_init(void); | |||
int lc6crypto_genrequestsessionkey(LC6_USER *user, LC6_FRIEND *friend); | |||
int lc6crypto_genresponsesessionkey(LC6_USER *user, LC6_FRIEND *friend); | |||
int lc6crypto_encrypt( | |||
const unsigned char *data, | |||
const int data_len, | |||
@@ -35,12 +38,10 @@ int lc6crypto_writefile( | |||
const int data_len); | |||
LC6_USER* lc6crypto_genuserkey(LC6_USER*); | |||
LC6_NODE* lc6crypto_gennodekey(LC6_NODE*); | |||
unsigned char* lc6crypto_hash(unsigned char*, int); | |||
void lc6crypto_random(unsigned char*, int); | |||
#define LC6_CRYPTO_HASHLEN crypto_generichash_BYTES | |||
#define LC6_CRYPTO_HASHSIGNLEN (crypto_secretbox_NONCEBYTES+crypto_box_MACBYTES+crypto_generichash_BYTES) | |||
#endif |
@@ -8,8 +8,19 @@ enum LIBCHAT_USER_STATUS { | |||
LC6_STATUS_TYPING | |||
}; | |||
typedef struct LIBCHAT_EVENT { | |||
int event_type; | |||
union { | |||
int a; | |||
int b; | |||
} event; | |||
} LIBCHAT_EVENT; | |||
typedef void *LIBCHAT; | |||
typedef int(*LIBCHAT_CB)(LIBCHAT_EVENT*); | |||
LIBCHAT* libchat_init(char *path, unsigned char *password); | |||
int libchat_event_reg(LIBCHAT *ctx, LIBCHAT_CB *cb); | |||
int libchat_start(LIBCHAT *ctx); | |||
#endif |
@@ -26,6 +26,7 @@ LIBDIR := ../lib | |||
TARGETS:= $(LIBDIR)/libchat6.so $(LIBDIR)/libchat6.a | |||
MAINS := $(.o, $(TARGETS) ) | |||
OBJ := \ | |||
lc6_event.o \ | |||
lc6_msg.o \ | |||
lc6_common.o \ | |||
lc6_debug.o \ |
@@ -29,7 +29,7 @@ LC6_CTX* lc6config_load(char *path, unsigned char *password) { | |||
// the neighbours. | |||
conf->node = malloc(sizeof(LC6_USER)); | |||
assert(conf->node); | |||
lc6crypto_genuserkey(conf->node); | |||
lc6crypto_gennodekey(conf->node); | |||
// conf->user may stay NULL | |||
@@ -11,13 +11,60 @@ int lc6crypto_init(void) { | |||
return sodium_init(); | |||
} | |||
LC6_USER* lc6crypto_genuserkey(LC6_USER *user) { | |||
assert(user); | |||
crypto_box_keypair(user->pub_key, user->priv_key); | |||
return user; | |||
} | |||
LC6_NODE* lc6crypto_gennodekey(LC6_NODE *node) { | |||
assert(node); | |||
crypto_box_keypair(node->pub_key, node->priv_key); | |||
return node; | |||
} | |||
int lc6crypto_genrequestsessionkey(LC6_USER *user, LC6_FRIEND *friend) { | |||
assert(user); | |||
assert(friend); | |||
// client = me | |||
// server = friend | |||
if ( | |||
crypto_kx_client_session_keys( | |||
friend->key_rx, | |||
friend->key_tx, | |||
user->pub_key, | |||
user->priv_key, | |||
friend->pub_key | |||
) != 0 ) | |||
{ | |||
return -1; | |||
} | |||
return 0; | |||
} | |||
int lc6crypto_genresponsesessionkey(LC6_USER *user, LC6_FRIEND *friend) { | |||
assert(user); | |||
assert(friend); | |||
// server = me | |||
// client = friend | |||
if ( | |||
crypto_kx_server_session_keys( | |||
friend->key_rx, | |||
friend->key_tx, | |||
user->pub_key, | |||
user->priv_key, | |||
friend->pub_key | |||
) != 0 ) | |||
{ | |||
return -1; | |||
} | |||
return 0; | |||
} | |||
int lc6crypto_encrypt( | |||
const unsigned char *data, | |||
const int data_len, |
@@ -10,16 +10,41 @@ | |||
#include "../inc/lc6_time.h" | |||
#include "../inc/lc6_crypto.h" | |||
unsigned char* lc6msg_peer_encrypt(LC6_NODE *node, LC6_NODE *peer, unsigned char *msg) { | |||
unsigned char *encrypted = NULL; | |||
unsigned char nonce[crypto_box_NONCEBYTES]; | |||
int msglen = strlen((char*)msg); | |||
unsigned char* lc6msg_compose(unsigned char *srckey, unsigned char *dstkey, LC6_MSG *msg) { | |||
randombytes_buf(nonce, sizeof nonce); | |||
encrypted = malloc(crypto_box_MACBYTES + msglen); | |||
assert(encrypted); | |||
if ( crypto_box_easy(encrypted, msg, msglen, nonce, peer->pub_key, node->priv_key) != 0 ) { | |||
free(encrypted); | |||
return NULL; | |||
} | |||
return encrypted; | |||
} | |||
unsigned char* lc6msg_peer_decrypt(LC6_NODE *node, LC6_NODE *peer, unsigned char *encrypted) { | |||
unsigned char *msg = encrypted; | |||
unsigned char *nonce = encrypted; | |||
int encryptedlen = strlen((char*)encrypted); | |||
if ( crypto_box_open_easy(msg, encrypted, encryptedlen, nonce, peer->pub_key, node->priv_key) != 0 ) { | |||
return NULL; | |||
} | |||
return msg; | |||
} | |||
unsigned char* lc6msg_compose(LC6_USER *user, LC6_FRIEND *friend, LC6_MSG *msg) { | |||
unsigned char *ret = NULL; | |||
unsigned char *timestamp = lc6time_getstr(); | |||
unsigned char *type = NULL; | |||
LC6_MSG_TLV *tlv = NULL; | |||
int total_len = 0; | |||
assert(srckey); | |||
assert(dstkey); | |||
assert(msg); | |||
/* <proof> |
@@ -6,6 +6,7 @@ | |||
#include "../inc/lc6_config.h" | |||
#include "../inc/lc6_user.h" | |||
#include "../inc/lc6_crypto.h" | |||
#include "../inc/lc6_event.h" | |||
LIBCHAT* libchat_init(char *path, unsigned char *password) { | |||
LC6_CTX *conf; | |||
@@ -23,3 +24,23 @@ LIBCHAT* libchat_init(char *path, unsigned char *password) { | |||
return (LIBCHAT*)conf; | |||
} | |||
int libchat_event_reg(LIBCHAT *ctx, LIBCHAT_CB *cb) { | |||
LC6_CTX *conf = (LC6_CTX*)ctx; | |||
assert(conf); | |||
assert(cb); | |||
conf->callback = cb; | |||
return 0; | |||
} | |||
int libchat_start(LIBCHAT *ctx) { | |||
LC6_CTX *conf = (LC6_CTX*)ctx; | |||
return lc6_event_start(conf); | |||
} | |||
int libchat_stop(LIBCHAT *ctx) { | |||
LC6_CTX *conf = (LC6_CTX*)ctx; | |||
return lc6_event_stop(conf); | |||
} |