Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Michal Zima
coincer
Commits
49b420dd
Commit
49b420dd
authored
Sep 03, 2018
by
xpetrak2
Browse files
Parser adjustment, daemon messages and crypto
parent
a37e5691
Changes
7
Hide whitespace changes
Inline
Side-by-side
Makefile.am
View file @
49b420dd
...
...
@@ -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
\
...
...
src/crypto.c
0 → 100644
View file @
49b420dd
/*
* 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
);
}
src/crypto.h
0 → 100644
View file @
49b420dd
/*
* 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 */
src/daemon_messages.c
0 → 100644
View file @
49b420dd
/*
* 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
;
}
}
src/daemon_messages.h
View file @
49b420dd
...
...
@@ -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 */
src/json_parser.c
View file @
49b420dd
...
...
@@ -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
;
}
src/json_parser.h
View file @
49b420dd
...
...
@@ -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 */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment