aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOmar Tarabai <tarabai@devegypt.com>2014-08-19 14:13:55 +0000
committerOmar Tarabai <tarabai@devegypt.com>2014-08-19 14:13:55 +0000
commitd276b7a5610430cc1e5fe24c21a9957a892b6eaa (patch)
treeea3eee8b0f882ed291d3f68d3a4493e48395299d /src
parent482d0a0e2045302b4ffacebfa1e48178f6bded55 (diff)
downloadgnunet-d276b7a5610430cc1e5fe24c21a9957a892b6eaa.tar.gz
gnunet-d276b7a5610430cc1e5fe24c21a9957a892b6eaa.zip
sensor: proof-of-work and signing library functions
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_sensor_util_lib.h81
-rw-r--r--src/include/gnunet_signatures.h5
-rw-r--r--src/sensor/Makefile.am3
-rw-r--r--src/sensor/gnunet-service-sensor_reporting.c3
-rw-r--r--src/sensor/sensor_util_lib.c2
-rw-r--r--src/sensor/sensor_util_lib_crypto.c273
6 files changed, 360 insertions, 7 deletions
diff --git a/src/include/gnunet_sensor_util_lib.h b/src/include/gnunet_sensor_util_lib.h
index 897fbbaad..d1b1a925e 100644
--- a/src/include/gnunet_sensor_util_lib.h
+++ b/src/include/gnunet_sensor_util_lib.h
@@ -20,7 +20,7 @@
20 20
21/** 21/**
22 * @file sensor/sensor_util_lib.c 22 * @file sensor/sensor_util_lib.c
23 * @brief senor utilities 23 * @brief sensor utilities
24 * @author Omar Tarabai 24 * @author Omar Tarabai
25 */ 25 */
26 26
@@ -210,11 +210,10 @@ struct GNUNET_SENSOR_DashboardAnomalyEntry
210}; 210};
211 211
212GNUNET_NETWORK_STRUCT_BEGIN 212GNUNET_NETWORK_STRUCT_BEGIN
213
214/** 213/**
215 * Used to communicate brief information about a sensor. 214 * Used to communicate brief information about a sensor.
216 */ 215 */
217struct GNUNET_SENSOR_SensorBriefMessage 216 struct GNUNET_SENSOR_SensorBriefMessage
218{ 217{
219 218
220 /** 219 /**
@@ -281,7 +280,7 @@ struct GNUNET_SENSOR_SensorFullMessage
281 * Used to communicate sensor values to 280 * Used to communicate sensor values to
282 * collection points (SENSORDASHBAORD service) 281 * collection points (SENSORDASHBAORD service)
283 */ 282 */
284 struct GNUNET_SENSOR_ValueMessage 283struct GNUNET_SENSOR_ValueMessage
285{ 284{
286 285
287 /** 286 /**
@@ -355,7 +354,6 @@ struct GNUNET_SENSOR_AnomalyReportMessage
355}; 354};
356 355
357GNUNET_NETWORK_STRUCT_END 356GNUNET_NETWORK_STRUCT_END
358
359/** 357/**
360 * Given two version numbers as major and minor, compare them. 358 * Given two version numbers as major and minor, compare them.
361 * 359 *
@@ -397,6 +395,79 @@ GNUNET_SENSOR_get_default_sensor_dir ();
397void 395void
398GNUNET_SENSOR_destroy_sensors (struct GNUNET_CONTAINER_MultiHashMap *sensors); 396GNUNET_SENSOR_destroy_sensors (struct GNUNET_CONTAINER_MultiHashMap *sensors);
399 397
398
399struct GNUNET_SENSOR_crypto_pow_context;
400
401/**
402 * Block carrying arbitrary data + its proof-of-work + signature
403 */
404struct GNUNET_SENSOR_crypto_pow_block
405{
406
407 /**
408 * Proof-of-work value
409 */
410 uint64_t pow;
411
412 /**
413 * Data signature
414 */
415 struct GNUNET_CRYPTO_EddsaSignature signature;
416
417 /**
418 * Purpose of signing, data is allocated after this.
419 */
420 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
421
422};
423
424
425/**
426 * Continuation called with a status result.
427 *
428 * @param cls closure
429 * @param pow Proof-of-work value
430 * @param purpose Signed block (size, purpose, data)
431 * @param signature Signature, NULL on error
432 */
433typedef void (*GNUNET_SENSOR_UTIL_pow_callback) (void *cls,
434 struct
435 GNUNET_SENSOR_crypto_pow_block
436 * block);
437
438
439/**
440 * Cancel an operation started by #GNUNET_SENSOR_crypto_pow_sign().
441 * Call only before callback function passed to #GNUNET_SENSOR_crypto_pow_sign()
442 * is called with the result.
443 */
444void
445GNUNET_SENSOR_crypto_pow_sign_cancel (struct GNUNET_SENSOR_crypto_pow_context
446 *cx);
447
448
449/**
450 * Calculate proof-of-work and sign a message.
451 *
452 * @param msg Message to calculate pow and sign
453 * @param msg_size size of msg
454 * @param timestamp Timestamp to add to the message to protect against replay attacks
455 * @param public_key Public key of the origin peer, to protect against redirect attacks
456 * @param private_key Private key of the origin peer to sign the result
457 * @param matching_bits Number of leading zeros required in the result hash
458 * @param callback Callback function to call with the result
459 * @param callback_cls Closure for callback
460 * @return Operation context
461 */
462struct GNUNET_SENSOR_crypto_pow_context *
463GNUNET_SENSOR_crypto_pow_sign (void *msg, size_t msg_size,
464 struct GNUNET_TIME_Absolute *timestamp,
465 struct GNUNET_CRYPTO_EddsaPublicKey *public_key,
466 struct GNUNET_CRYPTO_EddsaPrivateKey
467 *private_key, int matching_bits,
468 GNUNET_SENSOR_UTIL_pow_callback callback,
469 void *callback_cls);
470
400#if 0 /* keep Emacsens' auto-indent happy */ 471#if 0 /* keep Emacsens' auto-indent happy */
401{ 472{
402#endif 473#endif
diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h
index a2a41a256..5c1abb5ff 100644
--- a/src/include/gnunet_signatures.h
+++ b/src/include/gnunet_signatures.h
@@ -171,6 +171,11 @@ extern "C"
171 */ 171 */
172#define GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST 24 172#define GNUNET_SIGNATURE_PURPOSE_MULTICAST_REQUEST 24
173 173
174/**
175 * Signature for a sensor anomaly report message.
176 */
177#define GNUNET_SIGNATURE_PURPOSE_SENSOR_ANOMALY_REPORT 25
178
174 179
175#if 0 /* keep Emacsens' auto-indent happy */ 180#if 0 /* keep Emacsens' auto-indent happy */
176{ 181{
diff --git a/src/sensor/Makefile.am b/src/sensor/Makefile.am
index 305b91aad..d6577ee63 100644
--- a/src/sensor/Makefile.am
+++ b/src/sensor/Makefile.am
@@ -57,7 +57,8 @@ libgnunetsensor_la_LDFLAGS = \
57 $(GN_LIB_LDFLAGS) 57 $(GN_LIB_LDFLAGS)
58 58
59libgnunetsensorutil_la_SOURCES = \ 59libgnunetsensorutil_la_SOURCES = \
60 sensor_util_lib.c 60 sensor_util_lib.c \
61 sensor_util_lib_crypto.c
61libgnunetsensorutil_la_LIBADD = \ 62libgnunetsensorutil_la_LIBADD = \
62 $(top_builddir)/src/util/libgnunetutil.la \ 63 $(top_builddir)/src/util/libgnunetutil.la \
63 $(top_builddir)/src/statistics/libgnunetstatistics.la 64 $(top_builddir)/src/statistics/libgnunetstatistics.la
diff --git a/src/sensor/gnunet-service-sensor_reporting.c b/src/sensor/gnunet-service-sensor_reporting.c
index 6267e9f2a..562768ff1 100644
--- a/src/sensor/gnunet-service-sensor_reporting.c
+++ b/src/sensor/gnunet-service-sensor_reporting.c
@@ -607,6 +607,9 @@ handle_anomaly_report (void *cls, const struct GNUNET_PeerIdentity *other,
607 GNUNET_CONTAINER_multipeermap_contains 607 GNUNET_CONTAINER_multipeermap_contains
608 (my_anomaly_info->anomalous_neighbors, other); 608 (my_anomaly_info->anomalous_neighbors, other);
609 peer_anomalous = ntohs (arm->anomalous); 609 peer_anomalous = ntohs (arm->anomalous);
610 LOG (GNUNET_ERROR_TYPE_DEBUG,
611 "Received an anomaly update from neighbour `%s' (%d).\n",
612 GNUNET_i2s (other), peer_anomalous);
610 if (GNUNET_YES == peer_anomalous) 613 if (GNUNET_YES == peer_anomalous)
611 { 614 {
612 if (GNUNET_YES == peer_in_anomalous_list) /* repeated positive report */ 615 if (GNUNET_YES == peer_in_anomalous_list) /* repeated positive report */
diff --git a/src/sensor/sensor_util_lib.c b/src/sensor/sensor_util_lib.c
index 136bb288a..d3ed8c408 100644
--- a/src/sensor/sensor_util_lib.c
+++ b/src/sensor/sensor_util_lib.c
@@ -20,7 +20,7 @@
20 20
21/** 21/**
22 * @file sensor/sensor_util_lib.c 22 * @file sensor/sensor_util_lib.c
23 * @brief senor utilities 23 * @brief sensor utilities
24 * @author Omar Tarabai 24 * @author Omar Tarabai
25 */ 25 */
26#include <inttypes.h> 26#include <inttypes.h>
diff --git a/src/sensor/sensor_util_lib_crypto.c b/src/sensor/sensor_util_lib_crypto.c
new file mode 100644
index 000000000..bccbe74f9
--- /dev/null
+++ b/src/sensor/sensor_util_lib_crypto.c
@@ -0,0 +1,273 @@
1/*
2 This file is part of GNUnet.
3 (C)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file sensor/sensor_util_lib_crypto.c
23 * @brief senor utilities - crpyto related functions
24 * @author Omar Tarabai
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_sensor_util_lib.h"
30#include "gnunet_signatures.h"
31
32#define LOG(kind,...) GNUNET_log_from (kind, "sensor-util-crypto",__VA_ARGS__)
33
34/**
35 * Context of an operation performed by #GNUNET_SENSOR_crypto_pow_sign()
36 */
37struct GNUNET_SENSOR_crypto_pow_context
38{
39
40 /**
41 * Buffer of the complete message to calculate the pow for
42 */
43 void *buf;
44
45 /**
46 * Size of buf
47 */
48 size_t buf_size;
49
50 /**
51 * Proof-of-work number
52 */
53 uint64_t pow;
54
55 /**
56 * Private key to be used for signing
57 */
58 struct GNUNET_CRYPTO_EddsaPrivateKey private_key;
59
60 /**
61 * Number of leading zeros required in the result hash
62 */
63 int matching_bits;
64
65 /**
66 * Callback function to call with the result
67 */
68 GNUNET_SENSOR_UTIL_pow_callback callback;
69
70 /**
71 * Closure for callback
72 */
73 void *callback_cls;
74
75 /**
76 * Task that calculates the proof-of-work
77 */
78 GNUNET_SCHEDULER_TaskIdentifier calculate_pow_task;
79
80};
81
82
83/**
84 * Calculate the scrypt hash
85 */
86static void
87pow_hash (const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
88{
89 GNUNET_break (0 ==
90 gcry_kdf_derive (buf, buf_len, GCRY_KDF_SCRYPT,
91 1 /* subalgo */ ,
92 "gnunet-sensor-util-proof-of-work",
93 strlen ("gnunet-sensor-util-proof-of-work"), 2
94 /* iterations; keep cost of individual op small */
95 , sizeof (struct GNUNET_HashCode), result));
96}
97
98
99/**
100 * Count the leading zeroes in hash.
101 *
102 * @param hash to count leading zeros in
103 * @return the number of leading zero bits.
104 */
105static unsigned int
106count_leading_zeroes (const struct GNUNET_HashCode *hash)
107{
108 unsigned int hash_count;
109
110 hash_count = 0;
111 while ((0 == GNUNET_CRYPTO_hash_get_bit (hash, hash_count)))
112 hash_count++;
113 return hash_count;
114}
115
116
117/**
118 * Check if the given proof-of-work is valid
119 */
120static int
121check_pow (void *msg, size_t msg_size, uint64_t pow, int matching_bits)
122{
123 char buf[msg_size + sizeof (pow)] GNUNET_ALIGN;
124 struct GNUNET_HashCode result;
125
126 memcpy (buf, &pow, sizeof (pow));
127 memcpy (&buf[sizeof (pow)], msg, msg_size);
128 pow_hash (buf, sizeof (buf), &result);
129 return (count_leading_zeroes (&result) >=
130 matching_bits) ? GNUNET_YES : GNUNET_NO;
131}
132
133
134/**
135 * Task that checks if pow is correct, otherwise increments and reschedules itself
136 */
137static void
138calculate_pow (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
139{
140 struct GNUNET_SENSOR_crypto_pow_context *cx = cls;
141 struct GNUNET_SENSOR_crypto_pow_block *result_block;
142 GNUNET_SENSOR_UTIL_pow_callback callback;
143 void *callback_cls;
144 int sign_result;
145
146 if (GNUNET_YES ==
147 check_pow (cx->buf, cx->buf_size, cx->pow, cx->matching_bits))
148 {
149 cx->calculate_pow_task = GNUNET_SCHEDULER_NO_TASK;
150 result_block =
151 GNUNET_malloc (sizeof (struct GNUNET_SENSOR_crypto_pow_block) +
152 cx->buf_size);
153 result_block->purpose.purpose =
154 GNUNET_SIGNATURE_PURPOSE_SENSOR_ANOMALY_REPORT;
155 result_block->purpose.size =
156 sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + cx->buf_size;
157 memcpy (&result_block[1], cx->buf, cx->buf_size);
158 sign_result =
159 GNUNET_CRYPTO_eddsa_sign (&cx->private_key, &result_block->purpose,
160 &result_block->signature);
161 callback = cx->callback;
162 callback_cls = cx->callback_cls;
163 GNUNET_SENSOR_crypto_pow_sign_cancel (cx);
164 if (NULL != callback)
165 callback (callback_cls, (GNUNET_OK == sign_result) ? result_block : NULL);
166 }
167 cx->pow++;
168 cx->calculate_pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, cx);
169}
170
171
172/**
173 * Cancel an operation started by #GNUNET_SENSOR_crypto_pow_sign().
174 * Call only before callback function passed to #GNUNET_SENSOR_crypto_pow_sign()
175 * is called with the result.
176 */
177void
178GNUNET_SENSOR_crypto_pow_sign_cancel (struct GNUNET_SENSOR_crypto_pow_context
179 *cx)
180{
181 if (NULL != cx->buf)
182 {
183 GNUNET_free (cx->buf);
184 cx->buf = NULL;
185 }
186 GNUNET_free (cx);
187}
188
189
190/**
191 * Calculate proof-of-work and sign a message.
192 * The result of all operations will be returned via the callback passed to this
193 * function. Note that the payload (msg) is copied to the result block.
194 *
195 * @param msg Message to calculate pow and sign
196 * @param msg_size size of msg
197 * @param timestamp Timestamp to add to the message to protect against replay attacks
198 * @param public_key Public key of the origin peer, to protect against redirect attacks
199 * @param private_key Private key of the origin peer to sign the result
200 * @param matching_bits Number of leading zeros required in the result hash
201 * @param callback Callback function to call with the result
202 * @param callback_cls Closure for callback
203 * @return Operation context
204 */
205struct GNUNET_SENSOR_crypto_pow_context *
206GNUNET_SENSOR_crypto_pow_sign (void *msg, size_t msg_size,
207 struct GNUNET_TIME_Absolute *timestamp,
208 struct GNUNET_CRYPTO_EddsaPublicKey *public_key,
209 struct GNUNET_CRYPTO_EddsaPrivateKey
210 *private_key, int matching_bits,
211 GNUNET_SENSOR_UTIL_pow_callback callback,
212 void *callback_cls)
213{
214 struct GNUNET_SENSOR_crypto_pow_context *cx;
215 void *buf;
216 size_t buf_size;
217
218 buf_size = msg_size + sizeof (*timestamp) + sizeof (*public_key);
219 buf = GNUNET_malloc (buf_size);
220 cx = GNUNET_new (struct GNUNET_SENSOR_crypto_pow_context);
221
222 cx->buf = buf;
223 cx->buf_size = buf_size;
224 cx->pow = 0;
225 cx->private_key = *private_key;
226 cx->matching_bits = matching_bits;
227 cx->callback = callback;
228 cx->callback_cls = callback_cls;
229 cx->calculate_pow_task = GNUNET_SCHEDULER_add_now (&calculate_pow, cx);
230 return cx;
231}
232
233
234/**
235 * Verify that proof-of-work and signature in the given block are valid.
236 * If all valid, a pointer to the payload within the block is set and the size
237 * of the payload is returned.
238 *
239 * @param block The block received and needs to be verified
240 * @param matching_bits Number of leading zeros in the hash used to verify pow
241 * @param public_key Public key of the peer that sent this block
242 * @param payload Where to store the pointer to the payload
243 * @return Size of the payload
244 */
245size_t
246GNUNET_SENSOR_crypto_verify_pow_sign (struct GNUNET_SENSOR_crypto_pow_block *
247 block, int matching_bits,
248 struct GNUNET_CRYPTO_EddsaPublicKey *
249 public_key, void **payload)
250{
251 void *msg;
252 size_t msg_size;
253
254 /* Check signature */
255 if (GNUNET_OK !=
256 GNUNET_CRYPTO_eddsa_verify (block->purpose.purpose, &block->purpose,
257 &block->signature, public_key))
258 {
259 LOG (GNUNET_ERROR_TYPE_WARNING, "Invalid signature.\n");
260 return 0;
261 }
262 /* Check pow */
263 msg = &block[1];
264 msg_size =
265 block->purpose.size - sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose);
266 if (GNUNET_NO == check_pow (msg, msg_size, block->pow, matching_bits))
267 {
268 LOG (GNUNET_ERROR_TYPE_WARNING, "Invalid proof-of-work.\n");
269 return 0;
270 }
271 *payload = msg;
272 return msg_size;
273}