Commit 49b420dd authored by xpetrak2's avatar xpetrak2
Browse files

Parser adjustment, daemon messages and crypto

parent a37e5691
......@@ -5,7 +5,8 @@ bin_PROGRAMS = src/coincerd src/coincer
src_coincerd_SOURCES = \
src/coincerd.c \
src/configuration.c src/configuration.h \
src/daemon_messages.h \
src/crypto.c src/crypto.h \
src/daemon_messages.c src/daemon_messages.h \
src/hosts.c src/hosts.h \
src/json_parser.c src/json_parser.h \
src/linkedlist.c src/linkedlist.h \
......
/*
* Coincer
* Copyright (C) 2017-2018 Coincer Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sodium.h>
#include <stdint.h>
#include <string.h>
#include "crypto.h"
/**
* Generate a keypair.
*
* @param keypair Store the generated keypair in here.
*/
void generate_keypair(keypair_t *keypair)
{
crypto_box_keypair(keypair->public_key, keypair->secret_key);
}
/**
* Generate random 32-bit unsigned integer.
*
* @param upper_bound The random number upper bound
* (excluded).
*
* @return <0; upper_bound) The random number.
*/
uint32_t get_random_uint32_t(uint32_t upper_bound)
{
return randombytes_uniform(upper_bound);
}
/**
* Generate random 64-bit unsigned integer.
*
* @return <0; UINT64_MAX) The random number.
*/
uint64_t get_random_uint64_t(void)
{
uint64_t number;
randombytes_buf(&number, sizeof(uint64_t));
return number;
}
/**
* Create a hash of a string.
*
* @param string_message Create a hash of this string.
* @param hash Store the hash in here.
*
* @return 0 Hash successfully created.
* @return -1 Hashing failed.
*/
int hash_message(const char *string_message,
unsigned char hash[crypto_generichash_BYTES])
{
/* from libsodium doc: 'key can be NULL and keylen can be 0. In this
* case, a message will always have the same fingerprint, similar to
* the MD5 or SHA-1 functions for which crypto_generichash() is a
* faster and more secure alternative.'
*/
return crypto_generichash(hash,
crypto_generichash_BYTES,
(const unsigned char *) string_message,
strlen(string_message),
NULL,
0);
}
/**
* Sign a string message with a secret key.
*
* @param string_message Sign this message.
* @param secret_key With this key.
* @param signature Store the result in here.
*/
void sign_message(const char *string_message,
const unsigned char secret_key[crypto_box_SECRETKEYBYTES],
unsigned char signature[crypto_sign_BYTES])
{
/* from libsodium doc: It is safe to ignore siglen and always consider
* a signature as crypto_sign_BYTES bytes long: shorter signatures
* will be transparently padded with zeros if necessary.
*/
crypto_sign_detached(signature,
NULL,
(const unsigned char *) string_message,
strlen(string_message) * sizeof(char),
secret_key);
}
/**
* Verify string message signature.
*
* @param string_message The message to be verified.
* @param public_key Verify with this public key.
* @param signature The signature to be verified.
*
* @param 0 The signature is valid.
* @param 1 Invalid signature.
*/
int verify_signature(const char *string_message,
const unsigned char public_key[crypto_box_PUBLICKEYBYTES],
const unsigned char signature[crypto_sign_BYTES])
{
return crypto_sign_verify_detached(signature,
(const unsigned char *) string_message,
crypto_sign_BYTES,
public_key);
}
/*
* Coincer
* Copyright (C) 2017-2018 Coincer Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CRYPTO_H
#define CRYPTO_H
#include <sodium.h>
#include <stdint.h>
/** A Pair of public and secret key. */
typedef struct s_keypair {
/** Public key. */
unsigned char public_key[crypto_box_PUBLICKEYBYTES];
/** Secret key. */
unsigned char secret_key[crypto_box_SECRETKEYBYTES];
} keypair_t;
void generate_keypair(keypair_t *keypair);
uint32_t get_random_uint32_t(uint32_t upper_bound);
uint64_t get_random_uint64_t(void);
int hash_message(const char *string_message,
unsigned char hash[crypto_generichash_BYTES]);
void sign_message(const char *string_message,
const unsigned char secret_key[crypto_box_SECRETKEYBYTES],
unsigned char signature[crypto_sign_BYTES]);
int verify_signature(const char *string_message,
const unsigned char public_key[crypto_box_PUBLICKEYBYTES],
const unsigned char signature[crypto_sign_BYTES]);
#endif /* CRYPTO_H */
/*
* Coincer
* Copyright (C) 2017-2018 Coincer Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sodium.h>
#include <stdlib.h>
#include <string.h>
#include "autoconfig.h"
#include "daemon_messages.h"
#include "hosts.h"
#include "log.h"
/**
* Create a p2p.bye and store it in a message.
*
* @param message Store p2p.bye in this message.
*
* @return 0 Successfully created.
*/
int create_p2p_bye(message_t *message)
{
message->body.type = P2P_BYE;
message->body.data = NULL;
return 0;
}
/**
* Create a p2p.hello and store it in a message.
*
* @param message Store p2p.hello in this message.
* @param port Our listening port.
*
* @return 0 Successfully created.
* @return 1 Failure.
*/
int create_p2p_hello(message_t *message, unsigned short port)
{
char *client;
p2p_hello_t *hello;
hello = (p2p_hello_t *) malloc(sizeof(p2p_hello_t));
if (hello == NULL) {
log_error("Creating p2p.hello");
return 1;
}
client = (char *) malloc(sizeof("/" PACKAGE_NAME ":"
PACKAGE_VERSION "/"));
if (client == NULL) {
log_error("Creating p2p.hello");
return 1;
}
strcpy(client, "/" PACKAGE_NAME ":" PACKAGE_VERSION "/");
hello->client = client;
hello->port = port;
message->body.type = P2P_HELLO;
message->body.data = hello;
return 0;
}
/**
* Create a p2p.peers.adv and store it in a message.
*
* @param message Store p2p.peers.adv in this message.
* @param host List of known hosts.
*
* @return 0 Successfully created.
* @return 1 Failure.
*/
int create_p2p_peers_adv(message_t *message, const linkedlist_t *hosts)
{
p2p_peers_adv_t *peers_adv;
peers_adv = (p2p_peers_adv_t *) malloc(sizeof(p2p_peers_adv_t));
if (peers_adv == NULL) {
log_error("Creating p2p.peers.adv");
return 1;
}
hosts_to_str(hosts, &peers_adv->addresses);
message->body.type = P2P_PEERS_ADV;
message->body.data = peers_adv;
return 0;
}
/**
* Create a p2p.peers.sol and store it in a message.
*
* @param message Store p2p.peers.sol in this message.
*
* @return 0 Successfully created.
*/
int create_p2p_peers_sol(message_t *message)
{
message->body.type = P2P_PEERS_SOL;
message->body.data = NULL;
return 0;
}
/**
* Create a p2p.ping and store it in a message.
*
* @param message Store p2p.ping in this message.
*
* @return 0 Successfully created.
*/
int create_p2p_ping(message_t *message)
{
message->body.type = P2P_PING;
message->body.data = NULL;
return 0;
}
/**
* Create a p2p.pong and store it in a message.
*
* @param message Store p2p.pong in this message.
*
* @return 0 Successfully created.
*/
int create_p2p_pong(message_t *message)
{
message->body.type = P2P_PONG;
message->body.data = NULL;
return 0;
}
/**
* Create a p2p.route.adv and store it in a message.
*
* @param message Store p2p.route.adv in this message.
*
* @return 0 Successfully created.
*/
int create_p2p_route_adv(message_t *message)
{
message->body.type = P2P_ROUTE_ADV;
message->body.data = NULL;
return 0;
}
/**
* Create a p2p.route.sol and store it in a message.
*
* @param message Store p2p.route.sol in this message.
* @param target Looking for a peer with this identifier.
*
* @return 0 Successfully created.
* @return 1 Failure.
*/
int create_p2p_route_sol(message_t *message, const unsigned char *target)
{
p2p_route_sol_t *route_sol;
route_sol = (p2p_route_sol_t *) malloc(sizeof(p2p_route_sol_t));
if (route_sol == NULL) {
log_error("Creating p2p.route.sol");
return 1;
}
memcpy(route_sol->target, target, crypto_box_PUBLICKEYBYTES);
message->body.type = P2P_ROUTE_SOL;
message->body.data = route_sol;
return 0;
}
/**
* Safely delete a message.
*
* @param message Delete this message.
*/
void message_delete(message_t *message)
{
message_body_t *body = &message->body;
switch (body->type) {
case P2P_BYE:
break;
case P2P_HELLO:
free(((p2p_hello_t *) body->data)->client);
free(body->data);
break;
case P2P_PEERS_ADV:
free(((p2p_peers_adv_t *) body->data)->addresses);
free(body->data);
break;
case P2P_PEERS_SOL:
break;
case P2P_PING:
break;
case P2P_PONG:
break;
case P2P_ROUTE_ADV:
break;
case P2P_ROUTE_SOL:
free(body->data);
break;
default:
break;
}
}
......@@ -22,27 +22,85 @@
#include <sodium.h>
#include <stdint.h>
#include "linkedlist.h"
/** Current version of coincer daemon protocol. */
#define PROTOCOL_VERSION 1
/** Types of daemon messages. */
enum message_type {
P2P_PING,
P2P_PONG
/* TODO: and other message types */
P2P_BYE, /**< Peer departure announcement. */
P2P_HELLO, /**< Initial message between two neighbours. */
P2P_PEERS_ADV, /**< Known hosts addresses advertisement.*/
P2P_PEERS_SOL, /**< Known hosts addresses solicitation. */
P2P_PING, /**< Test of connectivity between two neighbours. */
P2P_PONG, /**< Response to a p2p.ping. */
P2P_ROUTE_ADV, /**< Peer reachability advertisement. */
P2P_ROUTE_SOL /**< Peer reachability solicitation. */
};
/* TODO: define all structs of daemon messages in here */
/**
* p2p.hello data holder.
*/
typedef struct s_p2p_hello {
/** Peer's software info, the format is like BIP14: /Coincer:1.0.0/. */
char *client;
/** Peer's listening port. */
unsigned short port;
} p2p_hello_t;
/**
* p2p.peers.adv data holder.
*/
typedef struct s_p2p_peers_adv {
/** List of some hosts in readable format: [ [ addr, port ], ... ]. */
char *addresses;
} p2p_peers_adv_t;
/**
* p2p.route.sol data holder.
*/
typedef struct s_p2p_route_sol {
/** The peer's identifier. */
unsigned char target[crypto_box_PUBLICKEYBYTES];
} p2p_route_sol_t;
/**
* Internal message body representation.
*/
typedef struct s_message_body {
unsigned char to[crypto_box_PUBLICKEYBYTES];
enum message_type type;
void *data;
uint64_t nonce;
unsigned char to[crypto_box_PUBLICKEYBYTES]; /**< Destination. */
enum message_type type; /**< Message type. */
void *data; /**< Message content. */
uint64_t nonce; /**< Message's nonce. */
} message_body_t;
/**
* Internal message representation.
*/
typedef struct s_message {
int version;
unsigned char from[crypto_box_PUBLICKEYBYTES];
message_body_t body;
unsigned char sig[crypto_sign_BYTES];
int version; /**< Protocol version. */
unsigned char from[crypto_box_PUBLICKEYBYTES]; /**< Sender. */
message_body_t body; /**< Message body. */
unsigned char sig[crypto_sign_BYTES]; /**< Signature. */
} message_t;
int create_p2p_bye(message_t *message);
int create_p2p_hello(message_t *message, unsigned short port);
int create_p2p_peers_adv(message_t *message, const linkedlist_t *hosts);
int create_p2p_peers_sol(message_t *message);
int create_p2p_ping(message_t *message);
int create_p2p_pong(message_t *message);
int create_p2p_route_adv(message_t *message);
int create_p2p_route_sol(message_t *msg_body, const unsigned char *target);
void message_delete(message_t *message);
#endif /* DAEMON_MESSAGES_H */
......@@ -86,6 +86,21 @@ int decode_message(const char *json_message, message_t *message)
return 0;
}
/* TODO: Implement */
/**
* Decode a JSON format message body into a daemon message body.
*
* @param json_body Decode this JSON message body.
* @param message Store decoded body in here.
*
* @return 0 Decoding successful.
* @return 1 Failure.
*/
int decode_message_body(const char *json_body, message_body_t *body)
{
return 0;
}
/* TODO: Implement */
/**
* Encode a daemon message into JSON format output.
......@@ -136,16 +151,16 @@ int encode_message(const message_t *message, char **json_message)
/* TODO: Implement */
/**
* Fetch a JSON message body from a JSON message.
* Encode a daemon message body into JSON format message body.
*
* @param json_message JSON message.
* @param json_message_body Dynamically allocated message body
* retrieved from json_message.
* @param body Message body to be encoded.
* @param json_body Dynamically allocated string
* of JSON message body.
*
* @return 0 Successfully fetched.
* @return 1 Failure.
* @return 0 Encoding successful.
* @return 1 Failure.
*/
int fetch_json_message_body(const char *json_message, char **json_message_body)
int encode_message_body(const message_body_t *body, char **json_body)
{
return 0;
}
......@@ -22,13 +22,19 @@
#include "daemon_messages.h"
static const char *msg_type_str[] = {
"p2p.bye",
"p2p.hello",
"p2p.peers.adv",
"p2p.peers.sol"
"p2p.ping",
"p2p.pong"
/* TODO: and other string representations of daemon type messages */
"p2p.pong",
"p2p.route.adv",
"p2p.route.sol"
};
int decode_message(const char *json_message, message_t *message);
int decode_message_body(const char *json_body, message_body_t *body);
int encode_message(const message_t *message, char **json_message);
int fetch_json_message_body(const char *json_message, char **json_message_body);
int encode_message_body(const message_body_t *body, char **json_body);
#endif /* JSON_PARSER_H */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment