diff options
author | Omar Tarabai <tarabai@devegypt.com> | 2014-08-19 14:13:55 +0000 |
---|---|---|
committer | Omar Tarabai <tarabai@devegypt.com> | 2014-08-19 14:13:55 +0000 |
commit | d276b7a5610430cc1e5fe24c21a9957a892b6eaa (patch) | |
tree | ea3eee8b0f882ed291d3f68d3a4493e48395299d /src | |
parent | 482d0a0e2045302b4ffacebfa1e48178f6bded55 (diff) | |
download | gnunet-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.h | 81 | ||||
-rw-r--r-- | src/include/gnunet_signatures.h | 5 | ||||
-rw-r--r-- | src/sensor/Makefile.am | 3 | ||||
-rw-r--r-- | src/sensor/gnunet-service-sensor_reporting.c | 3 | ||||
-rw-r--r-- | src/sensor/sensor_util_lib.c | 2 | ||||
-rw-r--r-- | src/sensor/sensor_util_lib_crypto.c | 273 |
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 | ||
212 | GNUNET_NETWORK_STRUCT_BEGIN | 212 | GNUNET_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 | */ |
217 | struct 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 | 283 | struct GNUNET_SENSOR_ValueMessage |
285 | { | 284 | { |
286 | 285 | ||
287 | /** | 286 | /** |
@@ -355,7 +354,6 @@ struct GNUNET_SENSOR_AnomalyReportMessage | |||
355 | }; | 354 | }; |
356 | 355 | ||
357 | GNUNET_NETWORK_STRUCT_END | 356 | GNUNET_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 (); | |||
397 | void | 395 | void |
398 | GNUNET_SENSOR_destroy_sensors (struct GNUNET_CONTAINER_MultiHashMap *sensors); | 396 | GNUNET_SENSOR_destroy_sensors (struct GNUNET_CONTAINER_MultiHashMap *sensors); |
399 | 397 | ||
398 | |||
399 | struct GNUNET_SENSOR_crypto_pow_context; | ||
400 | |||
401 | /** | ||
402 | * Block carrying arbitrary data + its proof-of-work + signature | ||
403 | */ | ||
404 | struct 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 | */ | ||
433 | typedef 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 | */ | ||
444 | void | ||
445 | GNUNET_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 | */ | ||
462 | struct GNUNET_SENSOR_crypto_pow_context * | ||
463 | GNUNET_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 | ||
59 | libgnunetsensorutil_la_SOURCES = \ | 59 | libgnunetsensorutil_la_SOURCES = \ |
60 | sensor_util_lib.c | 60 | sensor_util_lib.c \ |
61 | sensor_util_lib_crypto.c | ||
61 | libgnunetsensorutil_la_LIBADD = \ | 62 | libgnunetsensorutil_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 | */ | ||
37 | struct 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 | */ | ||
86 | static void | ||
87 | pow_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 | */ | ||
105 | static unsigned int | ||
106 | count_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 | */ | ||
120 | static int | ||
121 | check_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 | */ | ||
137 | static void | ||
138 | calculate_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 | */ | ||
177 | void | ||
178 | GNUNET_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 | */ | ||
205 | struct GNUNET_SENSOR_crypto_pow_context * | ||
206 | GNUNET_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 | */ | ||
245 | size_t | ||
246 | GNUNET_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 | } | ||