diff options
author | t3sserakt <t3ss@posteo.de> | 2022-04-01 15:08:41 +0200 |
---|---|---|
committer | t3sserakt <t3ss@posteo.de> | 2022-04-03 14:29:27 +0200 |
commit | 8f5b71e500a10790bf72d42de03e2db4971bf772 (patch) | |
tree | 10507356b5df0d2d0ce0b3b60a91dc070ce1001d /src | |
parent | 027177be3bae0c60d530b0b88ed375b082c94d81 (diff) | |
parent | e6a0ea8cf388a05856aaedbc5444f266ae47a7ef (diff) | |
download | gnunet-8f5b71e500a10790bf72d42de03e2db4971bf772.tar.gz gnunet-8f5b71e500a10790bf72d42de03e2db4971bf772.zip |
Merge branch 'master' of ssh://git.gnunet.org/gnunet
Diffstat (limited to 'src')
29 files changed, 1642 insertions, 546 deletions
diff --git a/src/dhtu/Makefile.am b/src/dhtu/Makefile.am index ebffa9ecf..4d210b71f 100644 --- a/src/dhtu/Makefile.am +++ b/src/dhtu/Makefile.am | |||
@@ -13,10 +13,11 @@ endif | |||
13 | pkgcfg_DATA = \ | 13 | pkgcfg_DATA = \ |
14 | dhtu.conf | 14 | dhtu.conf |
15 | 15 | ||
16 | |||
17 | plugin_LTLIBRARIES = \ | 16 | plugin_LTLIBRARIES = \ |
18 | libgnunet_plugin_dhtu_gnunet.la \ | 17 | libgnunet_plugin_dhtu_gnunet.la |
19 | libgnunet_plugin_dhtu_ip.la | 18 | |
19 | if !OPENBSD | ||
20 | plugin_LTLIBRARIES += libgnunet_plugin_dhtu_ip.la | ||
20 | 21 | ||
21 | libgnunet_plugin_dhtu_ip_la_SOURCES = \ | 22 | libgnunet_plugin_dhtu_ip_la_SOURCES = \ |
22 | plugin_dhtu_ip.c | 23 | plugin_dhtu_ip.c |
@@ -26,7 +27,7 @@ libgnunet_plugin_dhtu_ip_la_LIBADD = \ | |||
26 | $(LTLIBINTL) | 27 | $(LTLIBINTL) |
27 | libgnunet_plugin_dhtu_ip_la_LDFLAGS = \ | 28 | libgnunet_plugin_dhtu_ip_la_LDFLAGS = \ |
28 | $(GN_PLUGIN_LDFLAGS) | 29 | $(GN_PLUGIN_LDFLAGS) |
29 | 30 | endif | |
30 | 31 | ||
31 | 32 | ||
32 | libgnunet_plugin_dhtu_gnunet_la_SOURCES = \ | 33 | libgnunet_plugin_dhtu_gnunet_la_SOURCES = \ |
diff --git a/src/fs/test_fs_uri.c b/src/fs/test_fs_uri.c index 30eafab9a..aac7b1b97 100644 --- a/src/fs/test_fs_uri.c +++ b/src/fs/test_fs_uri.c | |||
@@ -80,7 +80,7 @@ testLocation () | |||
80 | char *uric; | 80 | char *uric; |
81 | struct GNUNET_FS_Uri *uri2; | 81 | struct GNUNET_FS_Uri *uri2; |
82 | struct GNUNET_FS_Uri *baseURI; | 82 | struct GNUNET_FS_Uri *baseURI; |
83 | char *emsg; | 83 | char *emsg = NULL; |
84 | struct GNUNET_CRYPTO_EddsaPrivateKey pk; | 84 | struct GNUNET_CRYPTO_EddsaPrivateKey pk; |
85 | 85 | ||
86 | baseURI = | 86 | baseURI = |
diff --git a/src/fs/test_plugin_block_fs.c b/src/fs/test_plugin_block_fs.c index 727cc37c2..f15d10b17 100644 --- a/src/fs/test_plugin_block_fs.c +++ b/src/fs/test_plugin_block_fs.c | |||
@@ -43,7 +43,6 @@ test_fs (struct GNUNET_BLOCK_Context *ctx) | |||
43 | if (GNUNET_OK != | 43 | if (GNUNET_OK != |
44 | GNUNET_BLOCK_check_block (ctx, | 44 | GNUNET_BLOCK_check_block (ctx, |
45 | GNUNET_BLOCK_TYPE_FS_DBLOCK, | 45 | GNUNET_BLOCK_TYPE_FS_DBLOCK, |
46 | &key, | ||
47 | block, | 46 | block, |
48 | sizeof(block))) | 47 | sizeof(block))) |
49 | return 2; | 48 | return 2; |
@@ -54,7 +53,7 @@ test_fs (struct GNUNET_BLOCK_Context *ctx) | |||
54 | NULL, 0)) | 53 | NULL, 0)) |
55 | return 4; | 54 | return 4; |
56 | GNUNET_log_skip (1, GNUNET_NO); | 55 | GNUNET_log_skip (1, GNUNET_NO); |
57 | if (GNUNET_BLOCK_EVALUATION_REQUEST_INVALID != | 56 | if (GNUNET_NO != |
58 | GNUNET_BLOCK_check_query (ctx, | 57 | GNUNET_BLOCK_check_query (ctx, |
59 | GNUNET_BLOCK_TYPE_FS_DBLOCK, | 58 | GNUNET_BLOCK_TYPE_FS_DBLOCK, |
60 | &key, | 59 | &key, |
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index 72b228f33..9d26e1777 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c | |||
@@ -623,6 +623,19 @@ resolver_lookup_get_next_label (struct GNS_ResolverHandle *rh) | |||
623 | rp = rh->name; | 623 | rp = rh->name; |
624 | rh->name_resolution_pos = 0; | 624 | rh->name_resolution_pos = 0; |
625 | } | 625 | } |
626 | else if (('_' == dot[1]) && | ||
627 | ('_' == rh->name[0]) && | ||
628 | (dot == memchr (rh->name, (int) '.', rh->name_resolution_pos))) | ||
629 | { | ||
630 | /** | ||
631 | * Do not advance a label. This seems to be a name only consisting | ||
632 | * of a BOX indicator (_443,_tcp). | ||
633 | * Which means, it is a BOX under the empty label. | ||
634 | * leaving name_resolution_pos as is and returning empty label. | ||
635 | */ | ||
636 | rp = GNUNET_GNS_EMPTY_LABEL_AT; | ||
637 | len = strlen (GNUNET_GNS_EMPTY_LABEL_AT); | ||
638 | } | ||
626 | else | 639 | else |
627 | { | 640 | { |
628 | /* advance by one label */ | 641 | /* advance by one label */ |
@@ -683,7 +696,7 @@ resolver_lookup_get_next_label (struct GNS_ResolverHandle *rh) | |||
683 | } | 696 | } |
684 | else | 697 | else |
685 | { | 698 | { |
686 | rh->service = se->s_port; | 699 | rh->service = ntohs (se->s_port); |
687 | } | 700 | } |
688 | rh->protocol = pe->p_proto; | 701 | rh->protocol = pe->p_proto; |
689 | GNUNET_free (proto_name); | 702 | GNUNET_free (proto_name); |
@@ -2237,6 +2250,10 @@ handle_gns_resolution_result (void *cls, | |||
2237 | const struct GNUNET_GNSRECORD_BoxRecord *box; | 2250 | const struct GNUNET_GNSRECORD_BoxRecord *box; |
2238 | 2251 | ||
2239 | box = rd[i].data; | 2252 | box = rd[i].data; |
2253 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2254 | "Got BOX record, checking if parameters match... %u/%u vs %u/%u\n", | ||
2255 | ntohs (box->protocol), ntohs (box->service), | ||
2256 | rh->protocol, rh->service); | ||
2240 | if ((ntohs (box->protocol) == rh->protocol) && | 2257 | if ((ntohs (box->protocol) == rh->protocol) && |
2241 | (ntohs (box->service) == rh->service)) | 2258 | (ntohs (box->service) == rh->service)) |
2242 | { | 2259 | { |
diff --git a/src/gns/plugin_block_gns.c b/src/gns/plugin_block_gns.c index fd9c99cb4..ffca16b6f 100644 --- a/src/gns/plugin_block_gns.c +++ b/src/gns/plugin_block_gns.c | |||
@@ -181,7 +181,7 @@ block_plugin_gns_check_block (void *cls, | |||
181 | size_t block_size) | 181 | size_t block_size) |
182 | { | 182 | { |
183 | const struct GNUNET_GNSRECORD_Block *gblock; | 183 | const struct GNUNET_GNSRECORD_Block *gblock; |
184 | 184 | ||
185 | if (GNUNET_BLOCK_TYPE_GNS_NAMERECORD != type) | 185 | if (GNUNET_BLOCK_TYPE_GNS_NAMERECORD != type) |
186 | { | 186 | { |
187 | GNUNET_break (0); | 187 | GNUNET_break (0); |
@@ -243,7 +243,7 @@ block_plugin_gns_check_reply (void *cls, | |||
243 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; | 243 | return GNUNET_BLOCK_REPLY_TYPE_NOT_SUPPORTED; |
244 | } | 244 | } |
245 | GNUNET_assert (reply_block_size >= sizeof(struct GNUNET_GNSRECORD_Block)); | 245 | GNUNET_assert (reply_block_size >= sizeof(struct GNUNET_GNSRECORD_Block)); |
246 | GNUNET_assert (GNUNET_GNSRECORD_block_get_size (block) > reply_block_size); | 246 | GNUNET_assert (reply_block_size >= GNUNET_GNSRECORD_block_get_size (block)); |
247 | GNUNET_CRYPTO_hash (reply_block, | 247 | GNUNET_CRYPTO_hash (reply_block, |
248 | reply_block_size, | 248 | reply_block_size, |
249 | &chash); | 249 | &chash); |
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c index ff92911de..b5e8be82b 100644 --- a/src/gnsrecord/gnsrecord_crypto.c +++ b/src/gnsrecord/gnsrecord_crypto.c | |||
@@ -219,7 +219,6 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
219 | rd); | 219 | rd); |
220 | struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; | 220 | struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; |
221 | struct GNRBlockPS *gnr_block; | 221 | struct GNRBlockPS *gnr_block; |
222 | struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; | ||
223 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; | 222 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; |
224 | unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; | 223 | unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; |
225 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; | 224 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; |
@@ -270,11 +269,10 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
270 | gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire); | 269 | gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire); |
271 | ecblock->expiration_time = gnr_block->expiration_time; | 270 | ecblock->expiration_time = gnr_block->expiration_time; |
272 | /* encrypt and sign */ | 271 | /* encrypt and sign */ |
273 | dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key, | 272 | GNUNET_CRYPTO_ecdsa_public_key_derive (pkey, |
274 | label, | 273 | label, |
275 | "gns"); | 274 | "gns", |
276 | GNUNET_CRYPTO_ecdsa_key_get_public (dkey, | 275 | &ecblock->derived_key); |
277 | &ecblock->derived_key); | ||
278 | GNR_derive_block_aes_key (ctr, | 276 | GNR_derive_block_aes_key (ctr, |
279 | skey, | 277 | skey, |
280 | label, | 278 | label, |
@@ -289,18 +287,18 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | |||
289 | GNUNET_memcpy (&gnr_block[1], &ecblock[1], payload_len); | 287 | GNUNET_memcpy (&gnr_block[1], &ecblock[1], payload_len); |
290 | } | 288 | } |
291 | if (GNUNET_OK != | 289 | if (GNUNET_OK != |
292 | GNUNET_CRYPTO_ecdsa_sign_ (dkey, | 290 | GNUNET_CRYPTO_ecdsa_sign_derived (key, |
293 | &gnr_block->purpose, | 291 | label, |
294 | &ecblock->signature)) | 292 | "gns", |
293 | &gnr_block->purpose, | ||
294 | &ecblock->signature)) | ||
295 | { | 295 | { |
296 | GNUNET_break (0); | 296 | GNUNET_break (0); |
297 | GNUNET_free (*block); | 297 | GNUNET_free (*block); |
298 | GNUNET_free (dkey); | ||
299 | GNUNET_free (gnr_block); | 298 | GNUNET_free (gnr_block); |
300 | return GNUNET_SYSERR; | 299 | return GNUNET_SYSERR; |
301 | } | 300 | } |
302 | GNUNET_free (gnr_block); | 301 | GNUNET_free (gnr_block); |
303 | GNUNET_free (dkey); | ||
304 | return GNUNET_OK; | 302 | return GNUNET_OK; |
305 | } | 303 | } |
306 | 304 | ||
@@ -344,7 +342,6 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, | |||
344 | rd); | 342 | rd); |
345 | struct GNUNET_GNSRECORD_EddsaBlock *edblock; | 343 | struct GNUNET_GNSRECORD_EddsaBlock *edblock; |
346 | struct GNRBlockPS *gnr_block; | 344 | struct GNRBlockPS *gnr_block; |
347 | struct GNUNET_CRYPTO_EddsaPrivateScalar dkey; | ||
348 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; | 345 | unsigned char nonce[crypto_secretbox_NONCEBYTES]; |
349 | unsigned char skey[crypto_secretbox_KEYBYTES]; | 346 | unsigned char skey[crypto_secretbox_KEYBYTES]; |
350 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; | 347 | struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; |
@@ -402,12 +399,10 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, | |||
402 | gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire); | 399 | gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire); |
403 | edblock->expiration_time = gnr_block->expiration_time; | 400 | edblock->expiration_time = gnr_block->expiration_time; |
404 | /* encrypt and sign */ | 401 | /* encrypt and sign */ |
405 | GNUNET_CRYPTO_eddsa_private_key_derive (key, | 402 | GNUNET_CRYPTO_eddsa_public_key_derive (pkey, |
406 | label, | 403 | label, |
407 | "gns", | 404 | "gns", |
408 | &dkey); | 405 | &edblock->derived_key); |
409 | GNUNET_CRYPTO_eddsa_key_get_public_from_scalar (&dkey, | ||
410 | &edblock->derived_key); | ||
411 | GNR_derive_block_xsalsa_key (nonce, | 406 | GNR_derive_block_xsalsa_key (nonce, |
412 | skey, | 407 | skey, |
413 | label, | 408 | label, |
@@ -422,9 +417,11 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key, | |||
422 | GNUNET_memcpy (&gnr_block[1], &edblock[1], | 417 | GNUNET_memcpy (&gnr_block[1], &edblock[1], |
423 | payload_len + crypto_secretbox_MACBYTES); | 418 | payload_len + crypto_secretbox_MACBYTES); |
424 | 419 | ||
425 | GNUNET_CRYPTO_eddsa_sign_with_scalar (&dkey, | 420 | GNUNET_CRYPTO_eddsa_sign_derived (key, |
426 | &gnr_block->purpose, | 421 | label, |
427 | &edblock->signature); | 422 | "gns", |
423 | &gnr_block->purpose, | ||
424 | &edblock->signature); | ||
428 | } | 425 | } |
429 | return GNUNET_OK; | 426 | return GNUNET_OK; |
430 | } | 427 | } |
diff --git a/src/gnsrecord/gnunet-gnsrecord-tvg.c b/src/gnsrecord/gnunet-gnsrecord-tvg.c index 87de32066..7fef6f8e7 100644 --- a/src/gnsrecord/gnunet-gnsrecord-tvg.c +++ b/src/gnsrecord/gnunet-gnsrecord-tvg.c | |||
@@ -96,20 +96,22 @@ static void | |||
96 | print_record (const struct GNUNET_GNSRECORD_Data *rd) | 96 | print_record (const struct GNUNET_GNSRECORD_Data *rd) |
97 | { | 97 | { |
98 | uint16_t flags = htons (rd->flags); | 98 | uint16_t flags = htons (rd->flags); |
99 | fprintf (stdout, | 99 | uint64_t abs_nbo = GNUNET_htonll (rd->expiration_time); |
100 | "EXPIRATION: %" PRIu64 "\n", rd->expiration_time); | 100 | uint16_t size_nbo = htons (rd->data_size); |
101 | fprintf (stdout, | 101 | uint32_t type_nbo = htonl (rd->record_type); |
102 | "DATA_SIZE: %zu\n", rd->data_size); | 102 | printf ("EXPIRATION:\n"); |
103 | fprintf (stdout, | 103 | print_bytes (&abs_nbo, sizeof (abs_nbo), 8); |
104 | "TYPE: %d\n", rd->record_type); | 104 | printf ("\nDATA_SIZE:\n"); |
105 | fprintf (stdout, | 105 | print_bytes (&size_nbo, sizeof (size_nbo), 8); |
106 | "FLAGS: "); | 106 | printf ("\nTYPE:\n"); |
107 | print_bytes(&type_nbo, sizeof (type_nbo), 8); | ||
108 | printf ("\nFLAGS: "); | ||
107 | print_bytes ((void*) &flags, sizeof (flags), 8); | 109 | print_bytes ((void*) &flags, sizeof (flags), 8); |
108 | printf ("\n"); | 110 | printf ("\n"); |
109 | fprintf (stdout, | 111 | fprintf (stdout, |
110 | "DATA:\n"); | 112 | "DATA:\n"); |
111 | print_bytes ((char*) rd->data, rd->data_size, 8); | 113 | print_bytes ((char*) rd->data, rd->data_size, 8); |
112 | fprintf (stdout, "\n"); | 114 | printf ("\n"); |
113 | } | 115 | } |
114 | 116 | ||
115 | 117 | ||
@@ -133,6 +135,7 @@ run_pkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char *label) | |||
133 | struct GNUNET_IDENTITY_PublicKey pkey_data; | 135 | struct GNUNET_IDENTITY_PublicKey pkey_data; |
134 | struct GNUNET_HashCode query; | 136 | struct GNUNET_HashCode query; |
135 | char *rdata; | 137 | char *rdata; |
138 | char *conv_lbl; | ||
136 | size_t rdata_size; | 139 | size_t rdata_size; |
137 | char ztld[128]; | 140 | char ztld[128]; |
138 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; | 141 | unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; |
@@ -146,34 +149,37 @@ run_pkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char *label) | |||
146 | 149 | ||
147 | GNUNET_IDENTITY_key_get_public (&id_priv, | 150 | GNUNET_IDENTITY_key_get_public (&id_priv, |
148 | &id_pub); | 151 | &id_pub); |
149 | fprintf (stdout, | 152 | printf ("Zone private key (d, big-endian):\n"); |
150 | "Zone private key (d, big-endian):\n"); | ||
151 | print_bytes_ (&id_priv.ecdsa_key, | 153 | print_bytes_ (&id_priv.ecdsa_key, |
152 | sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), 8, 1); | 154 | sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), 8, 1); |
153 | fprintf (stdout, "\n"); | 155 | printf ("\n"); |
154 | fprintf (stdout, "Zone identifier (ztype|zkey):\n"); | 156 | printf ("Zone identifier (ztype|zkey):\n"); |
155 | GNUNET_assert (0 < GNUNET_IDENTITY_key_get_length (&id_pub)); | 157 | GNUNET_assert (0 < GNUNET_IDENTITY_key_get_length (&id_pub)); |
156 | print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8); | 158 | print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8); |
157 | GNUNET_STRINGS_data_to_string (&id_pub, | 159 | GNUNET_STRINGS_data_to_string (&id_pub, |
158 | GNUNET_IDENTITY_key_get_length (&id_pub), | 160 | GNUNET_IDENTITY_key_get_length (&id_pub), |
159 | ztld, | 161 | ztld, |
160 | sizeof (ztld)); | 162 | sizeof (ztld)); |
161 | fprintf (stdout, "\n"); | 163 | printf ("\n"); |
162 | fprintf (stdout, "zTLD:\n"); | 164 | printf ("zTLD:\n"); |
163 | fprintf (stdout, "%s\n", ztld); | 165 | printf ("%s\n", ztld); |
164 | fprintf (stdout, "\n"); | 166 | printf ("\n"); |
165 | 167 | ||
166 | pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); | 168 | pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); |
167 | GNUNET_CRYPTO_ecdsa_key_create (&pkey_data_p.ecdsa_key); | 169 | GNUNET_CRYPTO_ecdsa_key_create (&pkey_data_p.ecdsa_key); |
168 | GNUNET_IDENTITY_key_get_public (&pkey_data_p, | 170 | GNUNET_IDENTITY_key_get_public (&pkey_data_p, |
169 | &pkey_data); | 171 | &pkey_data); |
170 | fprintf (stdout, | 172 | conv_lbl = GNUNET_GNSRECORD_string_normalize (label); |
171 | "Label: %s\nRRCOUNT: %d\n\n", label, rd_count); | 173 | printf ("Label:\n"); |
174 | print_bytes (conv_lbl, strlen (conv_lbl), 8); | ||
175 | GNUNET_free (conv_lbl); | ||
176 | printf ("\nNumber of records (integer): %d\n\n", rd_count); | ||
172 | 177 | ||
173 | for (int i = 0; i < rd_count; i++) | 178 | for (int i = 0; i < rd_count; i++) |
174 | { | 179 | { |
175 | fprintf (stdout, "Record #%d\n", i); | 180 | printf ("Record #%d := (\n", i); |
176 | print_record (&rd[i]); | 181 | print_record (&rd[i]); |
182 | printf (")\n\n"); | ||
177 | } | 183 | } |
178 | 184 | ||
179 | rdata_size = GNUNET_GNSRECORD_records_get_size (rd_count, | 185 | rdata_size = GNUNET_GNSRECORD_records_get_size (rd_count, |
@@ -183,11 +189,11 @@ run_pkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char *label) | |||
183 | rd, | 189 | rd, |
184 | (size_t) rdata_size, | 190 | (size_t) rdata_size, |
185 | rdata); | 191 | rdata); |
186 | fprintf (stdout, "RDATA:\n"); | 192 | printf ("RDATA:\n"); |
187 | print_bytes (rdata, | 193 | print_bytes (rdata, |
188 | (size_t) rdata_size, | 194 | (size_t) rdata_size, |
189 | 8); | 195 | 8); |
190 | fprintf (stdout, "\n"); | 196 | printf ("\n"); |
191 | expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_count, rd, | 197 | expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_count, rd, |
192 | GNUNET_TIME_UNIT_ZERO_ABS); | 198 | GNUNET_TIME_UNIT_ZERO_ABS); |
193 | GNR_derive_block_aes_key (ctr, | 199 | GNR_derive_block_aes_key (ctr, |
@@ -197,18 +203,18 @@ run_pkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char *label) | |||
197 | expire).abs_value_us__, | 203 | expire).abs_value_us__, |
198 | &id_pub.ecdsa_key); | 204 | &id_pub.ecdsa_key); |
199 | 205 | ||
200 | fprintf (stdout, "Encryption NONCE|EXPIRATION|BLOCK COUNTER:\n"); | 206 | printf ("Encryption NONCE|EXPIRATION|BLOCK COUNTER:\n"); |
201 | print_bytes (ctr, sizeof (ctr), 8); | 207 | print_bytes (ctr, sizeof (ctr), 8); |
202 | fprintf (stdout, "\n"); | 208 | printf ("\n"); |
203 | fprintf (stdout, "Encryption key (K):\n"); | 209 | printf ("Encryption key (K):\n"); |
204 | print_bytes (skey, sizeof (skey), 8); | 210 | print_bytes (skey, sizeof (skey), 8); |
205 | fprintf (stdout, "\n"); | 211 | printf ("\n"); |
206 | GNUNET_GNSRECORD_query_from_public_key (&id_pub, | 212 | GNUNET_GNSRECORD_query_from_public_key (&id_pub, |
207 | label, | 213 | label, |
208 | &query); | 214 | &query); |
209 | fprintf (stdout, "Storage key (q):\n"); | 215 | printf ("Storage key (q):\n"); |
210 | print_bytes (&query, sizeof (query), 8); | 216 | print_bytes (&query, sizeof (query), 8); |
211 | fprintf (stdout, "\n"); | 217 | printf ("\n"); |
212 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv, | 218 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv, |
213 | expire, | 219 | expire, |
214 | label, | 220 | label, |
@@ -219,12 +225,12 @@ run_pkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char *label) | |||
219 | GNUNET_GNSRECORD_Block); | 225 | GNUNET_GNSRECORD_Block); |
220 | 226 | ||
221 | bdata = (char*) &(&rrblock->ecdsa_block)[1]; | 227 | bdata = (char*) &(&rrblock->ecdsa_block)[1]; |
222 | fprintf (stdout, "BDATA:\n"); | 228 | printf ("BDATA:\n"); |
223 | print_bytes (bdata, bdata_size, 8); | 229 | print_bytes (bdata, bdata_size, 8); |
224 | fprintf (stdout, "\n"); | 230 | printf ("\n"); |
225 | fprintf (stdout, "RRBLOCK:\n"); | 231 | printf ("RRBLOCK:\n"); |
226 | print_bytes (rrblock, ntohl (rrblock->size), 8); | 232 | print_bytes (rrblock, ntohl (rrblock->size), 8); |
227 | fprintf (stdout, "\n"); | 233 | printf ("\n"); |
228 | GNUNET_free (rdata); | 234 | GNUNET_free (rdata); |
229 | } | 235 | } |
230 | 236 | ||
@@ -249,6 +255,7 @@ run_edkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char*label) | |||
249 | struct GNUNET_IDENTITY_PublicKey pkey_data; | 255 | struct GNUNET_IDENTITY_PublicKey pkey_data; |
250 | struct GNUNET_HashCode query; | 256 | struct GNUNET_HashCode query; |
251 | char *rdata; | 257 | char *rdata; |
258 | char *conv_lbl; | ||
252 | size_t rdata_size; | 259 | size_t rdata_size; |
253 | 260 | ||
254 | char ztld[128]; | 261 | char ztld[128]; |
@@ -271,30 +278,35 @@ run_edkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char*label) | |||
271 | "Zone private key (d):\n"); | 278 | "Zone private key (d):\n"); |
272 | print_bytes (&id_priv.eddsa_key, sizeof (struct | 279 | print_bytes (&id_priv.eddsa_key, sizeof (struct |
273 | GNUNET_CRYPTO_EddsaPrivateKey), 8); | 280 | GNUNET_CRYPTO_EddsaPrivateKey), 8); |
274 | fprintf (stdout, "\n"); | 281 | printf ("\n"); |
275 | fprintf (stdout, "Zone identifier (ztype|zkey):\n"); | 282 | printf ("Zone identifier (ztype|zkey):\n"); |
276 | GNUNET_assert (0 < GNUNET_IDENTITY_key_get_length (&id_pub)); | 283 | GNUNET_assert (0 < GNUNET_IDENTITY_key_get_length (&id_pub)); |
277 | print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8); | 284 | print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8); |
278 | GNUNET_STRINGS_data_to_string (&id_pub, | 285 | GNUNET_STRINGS_data_to_string (&id_pub, |
279 | GNUNET_IDENTITY_key_get_length (&id_pub), | 286 | GNUNET_IDENTITY_key_get_length (&id_pub), |
280 | ztld, | 287 | ztld, |
281 | sizeof (ztld)); | 288 | sizeof (ztld)); |
282 | fprintf (stdout, "\n"); | 289 | printf ("\n"); |
283 | fprintf (stdout, "zTLD:\n"); | 290 | printf ("zTLD:\n"); |
284 | fprintf (stdout, "%s\n", ztld); | 291 | printf ("%s\n", ztld); |
285 | fprintf (stdout, "\n"); | 292 | printf ("\n"); |
286 | 293 | ||
287 | pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY); | 294 | pkey_data_p.type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY); |
288 | GNUNET_CRYPTO_eddsa_key_create (&pkey_data_p.eddsa_key); | 295 | GNUNET_CRYPTO_eddsa_key_create (&pkey_data_p.eddsa_key); |
289 | GNUNET_IDENTITY_key_get_public (&pkey_data_p, | 296 | GNUNET_IDENTITY_key_get_public (&pkey_data_p, |
290 | &pkey_data); | 297 | &pkey_data); |
298 | conv_lbl = GNUNET_GNSRECORD_string_normalize (label); | ||
299 | printf ("Label:\n"); | ||
300 | print_bytes (conv_lbl, strlen (conv_lbl), 8); | ||
301 | GNUNET_free (conv_lbl); | ||
291 | fprintf (stdout, | 302 | fprintf (stdout, |
292 | "Label: %s\nRRCOUNT: %d\n\n", label, rd_count); | 303 | "\nNumber of records (integer): %d\n\n", rd_count); |
293 | 304 | ||
294 | for (int i = 0; i < rd_count; i++) | 305 | for (int i = 0; i < rd_count; i++) |
295 | { | 306 | { |
296 | fprintf (stdout, "Record #%d\n", i); | 307 | printf ("Record #%d := (\n", i); |
297 | print_record (&rd[i]); | 308 | print_record (&rd[i]); |
309 | printf (")\n\n"); | ||
298 | } | 310 | } |
299 | 311 | ||
300 | rdata_size = GNUNET_GNSRECORD_records_get_size (rd_count, | 312 | rdata_size = GNUNET_GNSRECORD_records_get_size (rd_count, |
@@ -308,29 +320,29 @@ run_edkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char*label) | |||
308 | rd, | 320 | rd, |
309 | (size_t) rdata_size, | 321 | (size_t) rdata_size, |
310 | rdata); | 322 | rdata); |
311 | fprintf (stdout, "RDATA:\n"); | 323 | printf ("RDATA:\n"); |
312 | print_bytes (rdata, | 324 | print_bytes (rdata, |
313 | (size_t) rdata_size, | 325 | (size_t) rdata_size, |
314 | 8); | 326 | 8); |
315 | fprintf (stdout, "\n"); | 327 | printf ("\n"); |
316 | GNR_derive_block_xsalsa_key (nonce, | 328 | GNR_derive_block_xsalsa_key (nonce, |
317 | skey, | 329 | skey, |
318 | label, | 330 | label, |
319 | GNUNET_TIME_absolute_hton ( | 331 | GNUNET_TIME_absolute_hton ( |
320 | expire).abs_value_us__, | 332 | expire).abs_value_us__, |
321 | &id_pub.eddsa_key); | 333 | &id_pub.eddsa_key); |
322 | fprintf (stdout, "Encryption NONCE|EXPIRATION:\n"); | 334 | printf ("Encryption NONCE|EXPIRATION:\n"); |
323 | print_bytes (nonce, sizeof (nonce), 8); | 335 | print_bytes (nonce, sizeof (nonce), 8); |
324 | fprintf (stdout, "\n"); | 336 | printf ("\n"); |
325 | fprintf (stdout, "Encryption key (K):\n"); | 337 | printf ("Encryption key (K):\n"); |
326 | print_bytes (skey, sizeof (skey), 8); | 338 | print_bytes (skey, sizeof (skey), 8); |
327 | fprintf (stdout, "\n"); | 339 | printf ("\n"); |
328 | GNUNET_GNSRECORD_query_from_public_key (&id_pub, | 340 | GNUNET_GNSRECORD_query_from_public_key (&id_pub, |
329 | label, | 341 | label, |
330 | &query); | 342 | &query); |
331 | fprintf (stdout, "Storage key (q):\n"); | 343 | printf ("Storage key (q):\n"); |
332 | print_bytes (&query, sizeof (query), 8); | 344 | print_bytes (&query, sizeof (query), 8); |
333 | fprintf (stdout, "\n"); | 345 | printf ("\n"); |
334 | 346 | ||
335 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv, | 347 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv, |
336 | expire, | 348 | expire, |
@@ -342,12 +354,12 @@ run_edkey (struct GNUNET_GNSRECORD_Data *rd, int rd_count, const char*label) | |||
342 | GNUNET_GNSRECORD_Block); | 354 | GNUNET_GNSRECORD_Block); |
343 | 355 | ||
344 | bdata = (char*) &(&rrblock->eddsa_block)[1]; | 356 | bdata = (char*) &(&rrblock->eddsa_block)[1]; |
345 | fprintf (stdout, "BDATA:\n"); | 357 | printf ("BDATA:\n"); |
346 | print_bytes (bdata, bdata_size, 8); | 358 | print_bytes (bdata, bdata_size, 8); |
347 | fprintf (stdout, "\n"); | 359 | printf ("\n"); |
348 | fprintf (stdout, "RRBLOCK:\n"); | 360 | printf ("RRBLOCK:\n"); |
349 | print_bytes (rrblock, ntohl (rrblock->size), 8); | 361 | print_bytes (rrblock, ntohl (rrblock->size), 8); |
350 | fprintf (stdout, "\n"); | 362 | printf ("\n"); |
351 | GNUNET_free (rdata); | 363 | GNUNET_free (rdata); |
352 | } | 364 | } |
353 | 365 | ||
@@ -424,9 +436,9 @@ run (void *cls, | |||
424 | | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | 436 | | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; |
425 | 437 | ||
426 | run_pkey (&rd_pkey, 1, "testdelegation"); | 438 | run_pkey (&rd_pkey, 1, "testdelegation"); |
427 | run_pkey (rd, 3, "namesystem"); | 439 | run_pkey (rd, 3, "\u5929\u4e0b\u7121\u6575"); |
428 | run_edkey (&rd_pkey, 1, "testdelegation"); | 440 | run_edkey (&rd_pkey, 1, "testdelegation"); |
429 | run_edkey (rd, 3, "namesystem"); | 441 | run_edkey (rd, 3, "\u5929\u4e0b\u7121\u6575"); |
430 | } | 442 | } |
431 | 443 | ||
432 | 444 | ||
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 72d783148..582a58861 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h | |||
@@ -287,6 +287,59 @@ struct GNUNET_CRYPTO_EddsaPrivateScalar | |||
287 | unsigned char s[512 / 8]; | 287 | unsigned char s[512 / 8]; |
288 | }; | 288 | }; |
289 | 289 | ||
290 | /** | ||
291 | * Private ECC key material encoded for transmission. To be used only for | ||
292 | * Edx25519 signatures. An inital key corresponds to data from the key | ||
293 | * expansion and clamping in the EdDSA key generation. | ||
294 | */ | ||
295 | struct GNUNET_CRYPTO_Edx25519PrivateKey | ||
296 | { | ||
297 | /** | ||
298 | * a is a value mod n, where n has at most 256 bits. It is the first half of | ||
299 | * the seed-expansion of EdDSA and will be clamped. | ||
300 | */ | ||
301 | unsigned char a[256 / 8]; | ||
302 | |||
303 | /** | ||
304 | * b consists of 32 bytes which where originally the lower 32bytes of the key | ||
305 | * expansion. Subsequent calls to derive_private will change this value, too. | ||
306 | */ | ||
307 | unsigned char b[256 / 8]; | ||
308 | }; | ||
309 | |||
310 | |||
311 | /** | ||
312 | * Public ECC key (always for curve Ed25519) encoded in a format suitable for | ||
313 | * network transmission and Edx25519 (same as EdDSA) signatures. Refer to | ||
314 | * section 5.1.3 of rfc8032, for a thorough explanation of how this value maps | ||
315 | * to the x- and y-coordinates. | ||
316 | */ | ||
317 | struct GNUNET_CRYPTO_Edx25519PublicKey | ||
318 | { | ||
319 | /** | ||
320 | * Point Q consists of a y-value mod p (256 bits); the x-value is | ||
321 | * always positive. The point is stored in Ed25519 standard | ||
322 | * compact format. | ||
323 | */ | ||
324 | unsigned char q_y[256 / 8]; | ||
325 | }; | ||
326 | |||
327 | /** | ||
328 | * @brief an ECC signature using Edx25519 (same as in EdDSA). | ||
329 | */ | ||
330 | struct GNUNET_CRYPTO_Edx25519Signature | ||
331 | { | ||
332 | /** | ||
333 | * R value. | ||
334 | */ | ||
335 | unsigned char r[256 / 8]; | ||
336 | |||
337 | /** | ||
338 | * S value. | ||
339 | */ | ||
340 | unsigned char s[256 / 8]; | ||
341 | }; | ||
342 | |||
290 | 343 | ||
291 | /** | 344 | /** |
292 | * @brief type for session keys | 345 | * @brief type for session keys |
@@ -1279,6 +1332,17 @@ GNUNET_CRYPTO_eddsa_key_get_public ( | |||
1279 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, | 1332 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, |
1280 | struct GNUNET_CRYPTO_EddsaPublicKey *pub); | 1333 | struct GNUNET_CRYPTO_EddsaPublicKey *pub); |
1281 | 1334 | ||
1335 | /** | ||
1336 | * @ingroup crypto | ||
1337 | * Extract the public key for the given private key. | ||
1338 | * | ||
1339 | * @param priv the private key | ||
1340 | * @param pub where to write the public key | ||
1341 | */ | ||
1342 | void | ||
1343 | GNUNET_CRYPTO_edx25519_key_get_public ( | ||
1344 | const struct GNUNET_CRYPTO_Edx25519PrivateKey *priv, | ||
1345 | struct GNUNET_CRYPTO_Edx25519PublicKey *pub); | ||
1282 | 1346 | ||
1283 | /** | 1347 | /** |
1284 | * @ingroup crypto | 1348 | * @ingroup crypto |
@@ -1465,6 +1529,30 @@ GNUNET_CRYPTO_eddsa_key_create (struct GNUNET_CRYPTO_EddsaPrivateKey *pk); | |||
1465 | 1529 | ||
1466 | /** | 1530 | /** |
1467 | * @ingroup crypto | 1531 | * @ingroup crypto |
1532 | * Create a new private key. | ||
1533 | * | ||
1534 | * @param[out] pk private key to initialize | ||
1535 | */ | ||
1536 | void | ||
1537 | GNUNET_CRYPTO_edx25519_key_create (struct GNUNET_CRYPTO_Edx25519PrivateKey *pk); | ||
1538 | |||
1539 | /** | ||
1540 | * @ingroup crypto | ||
1541 | * Create a new private key for Edx25519 from a given seed. After expanding | ||
1542 | * the seed, the first half of the key will be clamped according to EdDSA. | ||
1543 | * | ||
1544 | * @param seed seed input | ||
1545 | * @param seedsize size of the seed in bytes | ||
1546 | * @param[out] pk private key to initialize | ||
1547 | */ | ||
1548 | void | ||
1549 | GNUNET_CRYPTO_edx25519_key_create_from_seed ( | ||
1550 | const void *seed, | ||
1551 | size_t seedsize, | ||
1552 | struct GNUNET_CRYPTO_Edx25519PrivateKey *pk); | ||
1553 | |||
1554 | /** | ||
1555 | * @ingroup crypto | ||
1468 | * Create a new private key. Clear with #GNUNET_CRYPTO_ecdhe_key_clear(). | 1556 | * Create a new private key. Clear with #GNUNET_CRYPTO_ecdhe_key_clear(). |
1469 | * | 1557 | * |
1470 | * @param[out] pk set to fresh private key; | 1558 | * @param[out] pk set to fresh private key; |
@@ -1492,6 +1580,14 @@ GNUNET_CRYPTO_eddsa_key_clear (struct GNUNET_CRYPTO_EddsaPrivateKey *pk); | |||
1492 | void | 1580 | void |
1493 | GNUNET_CRYPTO_ecdsa_key_clear (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk); | 1581 | GNUNET_CRYPTO_ecdsa_key_clear (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk); |
1494 | 1582 | ||
1583 | /** | ||
1584 | * @ingroup crypto | ||
1585 | * Clear memory that was used to store a private key. | ||
1586 | * | ||
1587 | * @param pk location of the key | ||
1588 | */ | ||
1589 | void | ||
1590 | GNUNET_CRYPTO_edx25519_key_clear (struct GNUNET_CRYPTO_Edx25519PrivateKey *pk); | ||
1495 | 1591 | ||
1496 | /** | 1592 | /** |
1497 | * @ingroup crypto | 1593 | * @ingroup crypto |
@@ -1874,6 +1970,53 @@ GNUNET_CRYPTO_ecdsa_sign_ ( | |||
1874 | sig)); \ | 1970 | sig)); \ |
1875 | } while (0) | 1971 | } while (0) |
1876 | 1972 | ||
1973 | /** | ||
1974 | * @ingroup crypto | ||
1975 | * @brief Edx25519 sign a given block. | ||
1976 | * | ||
1977 | * The @a purpose data is the beginning of the data of which the signature is | ||
1978 | * to be created. The `size` field in @a purpose must correctly indicate the | ||
1979 | * number of bytes of the data structure, including its header. If possible, | ||
1980 | * use #GNUNET_CRYPTO_edx25519_sign() instead of this function (only if @a | ||
1981 | * validate is not fixed-size, you must use this function directly). | ||
1982 | * | ||
1983 | * @param priv private key to use for the signing | ||
1984 | * @param purpose what to sign (size, purpose) | ||
1985 | * @param[out] sig where to write the signature | ||
1986 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | ||
1987 | */ | ||
1988 | enum GNUNET_GenericReturnValue | ||
1989 | GNUNET_CRYPTO_edx25519_sign_ ( | ||
1990 | const struct GNUNET_CRYPTO_Edx25519PrivateKey *priv, | ||
1991 | const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, | ||
1992 | struct GNUNET_CRYPTO_Edx25519Signature *sig); | ||
1993 | |||
1994 | |||
1995 | /** | ||
1996 | * @ingroup crypto | ||
1997 | * @brief Edx25519 sign a given block. The resulting signature is compatible | ||
1998 | * with EdDSA. | ||
1999 | * | ||
2000 | * The @a ps data must be a fixed-size struct for which the signature is to be | ||
2001 | * created. The `size` field in @a ps->purpose must correctly indicate the | ||
2002 | * number of bytes of the data structure, including its header. | ||
2003 | * | ||
2004 | * @param priv private key to use for the signing | ||
2005 | * @param ps packed struct with what to sign, MUST begin with a purpose | ||
2006 | * @param[out] sig where to write the signature | ||
2007 | */ | ||
2008 | #define GNUNET_CRYPTO_edx25519_sign(priv,ps,sig) do { \ | ||
2009 | /* check size is set correctly */ \ | ||
2010 | GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ | ||
2011 | /* check 'ps' begins with the purpose */ \ | ||
2012 | GNUNET_static_assert (((void*) (ps)) == \ | ||
2013 | ((void*) &(ps)->purpose)); \ | ||
2014 | GNUNET_assert (GNUNET_OK == \ | ||
2015 | GNUNET_CRYPTO_edx25519_sign_ (priv, \ | ||
2016 | &(ps)->purpose, \ | ||
2017 | sig)); \ | ||
2018 | } while (0) | ||
2019 | |||
1877 | 2020 | ||
1878 | /** | 2021 | /** |
1879 | * @ingroup crypto | 2022 | * @ingroup crypto |
@@ -1917,7 +2060,7 @@ GNUNET_CRYPTO_eddsa_verify_ ( | |||
1917 | */ | 2060 | */ |
1918 | #define GNUNET_CRYPTO_eddsa_verify(purp,ps,sig,pub) ({ \ | 2061 | #define GNUNET_CRYPTO_eddsa_verify(purp,ps,sig,pub) ({ \ |
1919 | /* check size is set correctly */ \ | 2062 | /* check size is set correctly */ \ |
1920 | GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ | 2063 | GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ |
1921 | /* check 'ps' begins with the purpose */ \ | 2064 | /* check 'ps' begins with the purpose */ \ |
1922 | GNUNET_static_assert (((void*) (ps)) == \ | 2065 | GNUNET_static_assert (((void*) (ps)) == \ |
1923 | ((void*) &(ps)->purpose)); \ | 2066 | ((void*) &(ps)->purpose)); \ |
@@ -1927,7 +2070,6 @@ GNUNET_CRYPTO_eddsa_verify_ ( | |||
1927 | pub); \ | 2070 | pub); \ |
1928 | }) | 2071 | }) |
1929 | 2072 | ||
1930 | |||
1931 | /** | 2073 | /** |
1932 | * @ingroup crypto | 2074 | * @ingroup crypto |
1933 | * @brief Verify ECDSA signature. | 2075 | * @brief Verify ECDSA signature. |
@@ -1982,6 +2124,58 @@ GNUNET_CRYPTO_ecdsa_verify_ ( | |||
1982 | 2124 | ||
1983 | /** | 2125 | /** |
1984 | * @ingroup crypto | 2126 | * @ingroup crypto |
2127 | * @brief Verify Edx25519 signature. | ||
2128 | * | ||
2129 | * The @a validate data is the beginning of the data of which the signature | ||
2130 | * is to be verified. The `size` field in @a validate must correctly indicate | ||
2131 | * the number of bytes of the data structure, including its header. If @a | ||
2132 | * purpose does not match the purpose given in @a validate (the latter must be | ||
2133 | * in big endian), signature verification fails. If possible, use | ||
2134 | * #GNUNET_CRYPTO_edx25519_verify() instead of this function (only if @a | ||
2135 | * validate is not fixed-size, you must use this function directly). | ||
2136 | * | ||
2137 | * @param purpose what is the purpose that the signature should have? | ||
2138 | * @param validate block to validate (size, purpose, data) | ||
2139 | * @param sig signature that is being validated | ||
2140 | * @param pub public key of the signer | ||
2141 | * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid | ||
2142 | */ | ||
2143 | enum GNUNET_GenericReturnValue | ||
2144 | GNUNET_CRYPTO_edx25519_verify_ ( | ||
2145 | uint32_t purpose, | ||
2146 | const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, | ||
2147 | const struct GNUNET_CRYPTO_Edx25519Signature *sig, | ||
2148 | const struct GNUNET_CRYPTO_Edx25519PublicKey *pub); | ||
2149 | |||
2150 | |||
2151 | /** | ||
2152 | * @ingroup crypto | ||
2153 | * @brief Verify Edx25519 signature. | ||
2154 | * | ||
2155 | * The @a ps data must be a fixed-size struct for which the signature is to be | ||
2156 | * created. The `size` field in @a ps->purpose must correctly indicate the | ||
2157 | * number of bytes of the data structure, including its header. | ||
2158 | * | ||
2159 | * @param purp purpose of the signature, must match 'ps->purpose.purpose' | ||
2160 | * (except in host byte order) | ||
2161 | * @param priv private key to use for the signing | ||
2162 | * @param ps packed struct with what to sign, MUST begin with a purpose | ||
2163 | * @param sig where to write the signature | ||
2164 | */ | ||
2165 | #define GNUNET_CRYPTO_edx25519_verify(purp,ps,sig,pub) ({ \ | ||
2166 | /* check size is set correctly */ \ | ||
2167 | GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ | ||
2168 | /* check 'ps' begins with the purpose */ \ | ||
2169 | GNUNET_static_assert (((void*) (ps)) == \ | ||
2170 | ((void*) &(ps)->purpose)); \ | ||
2171 | GNUNET_CRYPTO_edx25519_verify_ (purp, \ | ||
2172 | &(ps)->purpose, \ | ||
2173 | sig, \ | ||
2174 | pub); \ | ||
2175 | }) | ||
2176 | |||
2177 | /** | ||
2178 | * @ingroup crypto | ||
1985 | * Derive a private key from a given private key and a label. | 2179 | * Derive a private key from a given private key and a label. |
1986 | * Essentially calculates a private key 'h = H(l,P) * d mod n' | 2180 | * Essentially calculates a private key 'h = H(l,P) * d mod n' |
1987 | * where n is the size of the ECC group and P is the public | 2181 | * where n is the size of the ECC group and P is the public |
@@ -2018,6 +2212,26 @@ GNUNET_CRYPTO_ecdsa_public_key_derive ( | |||
2018 | const char *context, | 2212 | const char *context, |
2019 | struct GNUNET_CRYPTO_EcdsaPublicKey *result); | 2213 | struct GNUNET_CRYPTO_EcdsaPublicKey *result); |
2020 | 2214 | ||
2215 | /** | ||
2216 | * This is a signature function for ECDSA which takes a | ||
2217 | * private key, derives/blinds it and signs the message. | ||
2218 | * | ||
2219 | * @param pkey original private key | ||
2220 | * @param label label to use for key deriviation | ||
2221 | * @param context additional context to use for HKDF of 'h'; | ||
2222 | * typically the name of the subsystem/application | ||
2223 | * @param purp the signature purpose | ||
2224 | * @param sig the resulting signature | ||
2225 | * @return GNUNET_OK on success | ||
2226 | */ | ||
2227 | enum GNUNET_GenericReturnValue | ||
2228 | GNUNET_CRYPTO_ecdsa_sign_derived ( | ||
2229 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, | ||
2230 | const char *label, | ||
2231 | const char *context, | ||
2232 | const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, | ||
2233 | struct GNUNET_CRYPTO_EcdsaSignature *sig); | ||
2234 | |||
2021 | 2235 | ||
2022 | /** | 2236 | /** |
2023 | * @ingroup crypto | 2237 | * @ingroup crypto |
@@ -2063,23 +2277,23 @@ GNUNET_CRYPTO_eddsa_public_key_derive ( | |||
2063 | 2277 | ||
2064 | 2278 | ||
2065 | /** | 2279 | /** |
2066 | * This is a signature function for EdDSA which takes the | 2280 | * This is a signature function for EdDSA which takes a |
2067 | * secret scalar sk instead of the private seed which is | 2281 | * private key and derives it using the label and context |
2068 | * usually the case for crypto APIs. We require this functionality | 2282 | * before signing. |
2069 | * in order to use derived private keys for signatures we | ||
2070 | * cannot calculate the inverse of a sk to find the seed | ||
2071 | * efficiently. | ||
2072 | * | 2283 | * |
2073 | * The resulting signature is a standard EdDSA signature | 2284 | * @param pkey original private key |
2074 | * which can be verified using the usual APIs. | 2285 | * @param label label to use for key deriviation |
2075 | * | 2286 | * @param context additional context to use for HKDF of 'h'; |
2076 | * @param sk the secret scalar | 2287 | * typically the name of the subsystem/application |
2077 | * @param purp the signature purpose | 2288 | * @param purp the signature purpose |
2078 | * @param sig the resulting signature | 2289 | * @param sig the resulting signature |
2290 | * @return GNUNET_OK on success | ||
2079 | */ | 2291 | */ |
2080 | void | 2292 | enum GNUNET_GenericReturnValue |
2081 | GNUNET_CRYPTO_eddsa_sign_with_scalar ( | 2293 | GNUNET_CRYPTO_eddsa_sign_derived ( |
2082 | const struct GNUNET_CRYPTO_EddsaPrivateScalar *priv, | 2294 | const struct GNUNET_CRYPTO_EddsaPrivateKey *pkey, |
2295 | const char *label, | ||
2296 | const char *context, | ||
2083 | const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, | 2297 | const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, |
2084 | struct GNUNET_CRYPTO_EddsaSignature *sig); | 2298 | struct GNUNET_CRYPTO_EddsaSignature *sig); |
2085 | 2299 | ||
@@ -2095,6 +2309,43 @@ GNUNET_CRYPTO_eddsa_key_get_public_from_scalar ( | |||
2095 | const struct GNUNET_CRYPTO_EddsaPrivateScalar *s, | 2309 | const struct GNUNET_CRYPTO_EddsaPrivateScalar *s, |
2096 | struct GNUNET_CRYPTO_EddsaPublicKey *pkey); | 2310 | struct GNUNET_CRYPTO_EddsaPublicKey *pkey); |
2097 | 2311 | ||
2312 | /** | ||
2313 | * @ingroup crypto | ||
2314 | * Derive a private scalar from a given private key and a label. | ||
2315 | * Essentially calculates a private key 'h = H(l,P) * d mod n' | ||
2316 | * where n is the size of the ECC group and P is the public | ||
2317 | * key associated with the private key 'd'. | ||
2318 | * | ||
2319 | * @param priv original private key | ||
2320 | * @param seed input seed | ||
2321 | * @param seedsize size of the seed | ||
2322 | * @param result derived private key | ||
2323 | */ | ||
2324 | void | ||
2325 | GNUNET_CRYPTO_edx25519_private_key_derive ( | ||
2326 | const struct GNUNET_CRYPTO_Edx25519PrivateKey *priv, | ||
2327 | const void *seed, | ||
2328 | size_t seedsize, | ||
2329 | struct GNUNET_CRYPTO_Edx25519PrivateKey *result); | ||
2330 | |||
2331 | |||
2332 | /** | ||
2333 | * @ingroup crypto | ||
2334 | * Derive a public key from a given public key and a label. | ||
2335 | * Essentially calculates a public key 'V = H(l,P) * P'. | ||
2336 | * | ||
2337 | * @param pub original public key | ||
2338 | * @param seed input seed | ||
2339 | * @param seedsize size of the seed | ||
2340 | * @param result where to write the derived public key | ||
2341 | */ | ||
2342 | void | ||
2343 | GNUNET_CRYPTO_edx25519_public_key_derive ( | ||
2344 | const struct GNUNET_CRYPTO_Edx25519PublicKey *pub, | ||
2345 | const void *seed, | ||
2346 | size_t seedsize, | ||
2347 | struct GNUNET_CRYPTO_Edx25519PublicKey *result); | ||
2348 | |||
2098 | 2349 | ||
2099 | /** | 2350 | /** |
2100 | * Output the given MPI value to the given buffer in network | 2351 | * Output the given MPI value to the given buffer in network |
diff --git a/src/include/gnunet_messenger_service.h b/src/include/gnunet_messenger_service.h index 96d48b411..f8bbc7398 100644 --- a/src/include/gnunet_messenger_service.h +++ b/src/include/gnunet_messenger_service.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2020--2021 GNUnet e.V. | 3 | Copyright (C) 2020--2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -96,6 +96,27 @@ struct GNUNET_MESSENGER_RoomEntryRecord | |||
96 | 96 | ||
97 | GNUNET_NETWORK_STRUCT_END | 97 | GNUNET_NETWORK_STRUCT_END |
98 | 98 | ||
99 | GNUNET_NETWORK_STRUCT_BEGIN | ||
100 | |||
101 | /** | ||
102 | * A room details record specifies a custom name for a given room and | ||
103 | * some additional space for flags. | ||
104 | */ | ||
105 | struct GNUNET_MESSENGER_RoomDetailsRecord | ||
106 | { | ||
107 | /** | ||
108 | * The custom name for the room. | ||
109 | */ | ||
110 | char name [256]; | ||
111 | |||
112 | /** | ||
113 | * The flags of the room. | ||
114 | */ | ||
115 | uint32_t flags; | ||
116 | }; | ||
117 | |||
118 | GNUNET_NETWORK_STRUCT_END | ||
119 | |||
99 | /** | 120 | /** |
100 | * Enum for the different supported kinds of messages | 121 | * Enum for the different supported kinds of messages |
101 | */ | 122 | */ |
diff --git a/src/include/gnunet_namestore_plugin.h b/src/include/gnunet_namestore_plugin.h index 9cc8abc6e..3dca5a853 100644 --- a/src/include/gnunet_namestore_plugin.h +++ b/src/include/gnunet_namestore_plugin.h | |||
@@ -150,6 +150,71 @@ struct GNUNET_NAMESTORE_PluginFunctions | |||
150 | const struct GNUNET_IDENTITY_PublicKey *value_zone, | 150 | const struct GNUNET_IDENTITY_PublicKey *value_zone, |
151 | GNUNET_NAMESTORE_RecordIterator iter, | 151 | GNUNET_NAMESTORE_RecordIterator iter, |
152 | void *iter_cls); | 152 | void *iter_cls); |
153 | |||
154 | /** Transaction-based API draft **/ | ||
155 | |||
156 | /** | ||
157 | * Start a transaction in the database | ||
158 | * | ||
159 | * @param cls closure (internal context for the plugin) | ||
160 | * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error | ||
161 | */ | ||
162 | enum GNUNET_GenericReturnValue | ||
163 | (*transaction_begin) (void *cls); | ||
164 | |||
165 | /** | ||
166 | * Abort a transaction in the database | ||
167 | * | ||
168 | * @param cls closure (internal context for the plugin) | ||
169 | * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error | ||
170 | */ | ||
171 | enum GNUNET_GenericReturnValue | ||
172 | (*transaction_abort) (void *cls); | ||
173 | |||
174 | /** | ||
175 | * Commit a transaction in the database | ||
176 | * | ||
177 | * @param cls closure (internal context for the plugin) | ||
178 | * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error | ||
179 | */ | ||
180 | enum GNUNET_GenericReturnValue | ||
181 | (*transaction_commit) (void *cls); | ||
182 | |||
183 | /** | ||
184 | * Replace a record in the datastore for which we are the authority. | ||
185 | * Removes any existing record in the same zone with the same name. | ||
186 | * | ||
187 | * @param cls closure (internal context for the plugin) | ||
188 | * @param zone private key of the zone | ||
189 | * @param label name of the record in the zone | ||
190 | * @param rd_count number of entries in @a rd array, 0 to delete all records | ||
191 | * @param rd array of records with data to store | ||
192 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
193 | */ | ||
194 | int | ||
195 | (*replace_records) (void *cls, | ||
196 | const struct GNUNET_IDENTITY_PrivateKey *zone, | ||
197 | const char *label, | ||
198 | unsigned int rd_count, | ||
199 | const struct GNUNET_GNSRECORD_Data *rd); | ||
200 | |||
201 | /** | ||
202 | * Lookup records in the datastore for which we are the authority. | ||
203 | * | ||
204 | * @param cls closure (internal context for the plugin) | ||
205 | * @param zone private key of the zone | ||
206 | * @param label name of the record in the zone | ||
207 | * @param iter function to call with the result | ||
208 | * @param iter_cls closure for @a iter | ||
209 | * @return #GNUNET_OK on success, #GNUNET_NO for no results, else #GNUNET_SYSERR | ||
210 | */ | ||
211 | int | ||
212 | (*select_records) (void *cls, | ||
213 | const struct GNUNET_IDENTITY_PrivateKey *zone, | ||
214 | const char *label, | ||
215 | GNUNET_NAMESTORE_RecordIterator iter, | ||
216 | void *iter_cls); | ||
217 | |||
153 | }; | 218 | }; |
154 | 219 | ||
155 | 220 | ||
diff --git a/src/include/gnunet_namestore_service.h b/src/include/gnunet_namestore_service.h index 619b81aed..86572803f 100644 --- a/src/include/gnunet_namestore_service.h +++ b/src/include/gnunet_namestore_service.h | |||
@@ -212,61 +212,6 @@ GNUNET_NAMESTORE_records_lookup (struct GNUNET_NAMESTORE_Handle *h, | |||
212 | 212 | ||
213 | 213 | ||
214 | /** | 214 | /** |
215 | * Open a record set for editing. | ||
216 | * Retrieves an exclusive lock on this set. | ||
217 | * Must be commited using @a GNUNET_NAMESTORE_records_commit | ||
218 | * | ||
219 | * @param h handle to the namestore | ||
220 | * @param pkey private key of the zone | ||
221 | * @param label name that is being mapped | ||
222 | * @param error_cb function to call on error (i.e. disconnect or unable to get lock) | ||
223 | * the handle is afterwards invalid | ||
224 | * @param error_cb_cls closure for @a error_cb | ||
225 | * @param rm function to call with the result (with 0 records if we don't have that label) | ||
226 | * @param rm_cls closure for @a rm | ||
227 | * @return handle to abort the request | ||
228 | */ | ||
229 | struct GNUNET_NAMESTORE_QueueEntry * | ||
230 | GNUNET_NAMESTORE_records_open (struct GNUNET_NAMESTORE_Handle *h, | ||
231 | const struct | ||
232 | GNUNET_IDENTITY_PrivateKey *pkey, | ||
233 | const char *label, | ||
234 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
235 | void *error_cb_cls, | ||
236 | GNUNET_NAMESTORE_RecordMonitor rm, | ||
237 | void *rm_cls); | ||
238 | |||
239 | /** | ||
240 | * Commit the record set to the namestore. | ||
241 | * Releases the lock on the record set. | ||
242 | * Use an empty array to | ||
243 | * remove all records under the given name. | ||
244 | * | ||
245 | * The continuation is called after the value has been stored in the | ||
246 | * database. Monitors may be notified asynchronously (basically with | ||
247 | * a buffer). However, if any monitor is consistently too slow to | ||
248 | * keep up with the changes, calling @a cont will be delayed until the | ||
249 | * monitors do keep up. | ||
250 | * | ||
251 | * @param h handle to the namestore | ||
252 | * @param pkey private key of the zone | ||
253 | * @param label name that is being mapped | ||
254 | * @param rd_count number of records in the 'rd' array | ||
255 | * @param rd array of records with data to store | ||
256 | * @param cont continuation to call when done | ||
257 | * @param cont_cls closure for @a cont | ||
258 | * @return handle to abort the request | ||
259 | */ | ||
260 | struct GNUNET_NAMESTORE_QueueEntry * | ||
261 | GNUNET_NAMESTORE_records_commit (struct GNUNET_NAMESTORE_Handle *h, | ||
262 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
263 | const char *label, | ||
264 | unsigned int rd_count, | ||
265 | const struct GNUNET_GNSRECORD_Data *rd, | ||
266 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | ||
267 | void *cont_cls); | ||
268 | |||
269 | /** | ||
270 | * Look for an existing PKEY delegation record for a given public key. | 215 | * Look for an existing PKEY delegation record for a given public key. |
271 | * Returns at most one result to the processor. | 216 | * Returns at most one result to the processor. |
272 | * | 217 | * |
@@ -448,6 +393,107 @@ void | |||
448 | GNUNET_NAMESTORE_zone_monitor_stop (struct GNUNET_NAMESTORE_ZoneMonitor *zm); | 393 | GNUNET_NAMESTORE_zone_monitor_stop (struct GNUNET_NAMESTORE_ZoneMonitor *zm); |
449 | 394 | ||
450 | 395 | ||
396 | /** | ||
397 | * New API draft. Experimental | ||
398 | */ | ||
399 | |||
400 | /** | ||
401 | * Begin a namestore transaction. | ||
402 | * | ||
403 | * @param h handle to the namestore | ||
404 | * @param error_cb function to call on error (i.e. disconnect or unable to get lock) | ||
405 | * the handle is afterwards invalid | ||
406 | * @param error_cb_cls closure for @a error_cb | ||
407 | * @return handle to abort the request | ||
408 | */ | ||
409 | struct GNUNET_NAMESTORE_QueueEntry * | ||
410 | GNUNET_NAMESTORE_transaction_begin (struct GNUNET_NAMESTORE_Handle *h, | ||
411 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
412 | void *error_cb_cls); | ||
413 | |||
414 | /** | ||
415 | * Begin rollback all actions in a transaction. | ||
416 | * Reverts all actions performed since #GNUNET_NAMESTORE_transaction_begin | ||
417 | * | ||
418 | * @param h handle to the namestore | ||
419 | * @param error_cb function to call on error (i.e. disconnect or unable to get lock) | ||
420 | * the handle is afterwards invalid | ||
421 | * @param error_cb_cls closure for @a error_cb | ||
422 | * @return handle to abort the request | ||
423 | */ | ||
424 | struct GNUNET_NAMESTORE_QueueEntry * | ||
425 | GNUNET_NAMESTORE_transaction_abort (struct GNUNET_NAMESTORE_Handle *h, | ||
426 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
427 | void *error_cb_cls); | ||
428 | /** | ||
429 | * Commit a namestore transaction. | ||
430 | * Saves all actions performed since #GNUNET_NAMESTORE_transaction_begin | ||
431 | * | ||
432 | * @param h handle to the namestore | ||
433 | * @param error_cb function to call on error (i.e. disconnect or unable to get lock) | ||
434 | * the handle is afterwards invalid | ||
435 | * @param error_cb_cls closure for @a error_cb | ||
436 | * @return handle to abort the request | ||
437 | */ | ||
438 | struct GNUNET_NAMESTORE_QueueEntry * | ||
439 | GNUNET_NAMESTORE_transaction_commit (struct GNUNET_NAMESTORE_Handle *h, | ||
440 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
441 | void *error_cb_cls); | ||
442 | |||
443 | /** | ||
444 | * Lookup an item in the namestore. | ||
445 | * | ||
446 | * @param h handle to the namestore | ||
447 | * @param pkey private key of the zone | ||
448 | * @param label name that is being mapped | ||
449 | * @param error_cb function to call on error (i.e. disconnect) | ||
450 | * the handle is afterwards invalid | ||
451 | * @param error_cb_cls closure for @a error_cb | ||
452 | * @param rm function to call with the result (with 0 records if we don't have that label); | ||
453 | * the handle is afterwards invalid | ||
454 | * @param rm_cls closure for @a rm | ||
455 | * @return handle to abort the request | ||
456 | */ | ||
457 | struct GNUNET_NAMESTORE_QueueEntry * | ||
458 | GNUNET_NAMESTORE_records_select (struct GNUNET_NAMESTORE_Handle *h, | ||
459 | const struct | ||
460 | GNUNET_IDENTITY_PrivateKey *pkey, | ||
461 | const char *label, | ||
462 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
463 | void *error_cb_cls, | ||
464 | GNUNET_NAMESTORE_RecordMonitor rm, | ||
465 | void *rm_cls); | ||
466 | |||
467 | |||
468 | /** | ||
469 | * Creates, deletes or updates an item in the namestore. | ||
470 | * If the item is already present, it is replaced with the new record set. | ||
471 | * Use an empty array to remove all records under the given name. | ||
472 | * | ||
473 | * The continuation is called after the value has been stored in the | ||
474 | * database. Monitors may be notified asynchronously (basically with | ||
475 | * a buffer). However, if any monitor is consistently too slow to | ||
476 | * keep up with the changes, calling @a cont will be delayed until the | ||
477 | * monitors do keep up. | ||
478 | * | ||
479 | * @param h handle to the namestore | ||
480 | * @param pkey private key of the zone | ||
481 | * @param label name that is being mapped | ||
482 | * @param rd_count number of records in the 'rd' array | ||
483 | * @param rd array of records with data to store | ||
484 | * @param cont continuation to call when done | ||
485 | * @param cont_cls closure for @a cont | ||
486 | * @return handle to abort the request | ||
487 | */ | ||
488 | struct GNUNET_NAMESTORE_QueueEntry * | ||
489 | GNUNET_NAMESTORE_records_replace (struct GNUNET_NAMESTORE_Handle *h, | ||
490 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
491 | const char *label, | ||
492 | unsigned int rd_count, | ||
493 | const struct GNUNET_GNSRECORD_Data *rd, | ||
494 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | ||
495 | void *cont_cls); | ||
496 | |||
451 | #if 0 /* keep Emacsens' auto-indent happy */ | 497 | #if 0 /* keep Emacsens' auto-indent happy */ |
452 | { | 498 | { |
453 | #endif | 499 | #endif |
diff --git a/src/include/gnunet_time_lib.h b/src/include/gnunet_time_lib.h index 96413c3cc..d59eb984d 100644 --- a/src/include/gnunet_time_lib.h +++ b/src/include/gnunet_time_lib.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2001-2013 GNUnet e.V. | 3 | Copyright (C) 2001-2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -482,6 +482,18 @@ GNUNET_TIME_absolute_max (struct GNUNET_TIME_Absolute t1, | |||
482 | 482 | ||
483 | 483 | ||
484 | /** | 484 | /** |
485 | * Round down absolute time @a at to multiple of @a rt. | ||
486 | * | ||
487 | * @param at absolute time to round | ||
488 | * @param rt multiple to round to (non-zero) | ||
489 | * @return rounded time | ||
490 | */ | ||
491 | struct GNUNET_TIME_Absolute | ||
492 | GNUNET_TIME_absolute_round_down (struct GNUNET_TIME_Absolute at, | ||
493 | struct GNUNET_TIME_Relative rt); | ||
494 | |||
495 | |||
496 | /** | ||
485 | * Return the maximum of two timestamps. | 497 | * Return the maximum of two timestamps. |
486 | * | 498 | * |
487 | * @param t1 first timestamp | 499 | * @param t1 first timestamp |
@@ -517,6 +529,21 @@ GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future); | |||
517 | 529 | ||
518 | 530 | ||
519 | /** | 531 | /** |
532 | * Test if @a a1 and @a a2 are equal within a margin of | ||
533 | * error of @a t. | ||
534 | * | ||
535 | * @param a1 time to compare | ||
536 | * @param a2 time to compare | ||
537 | * @param t tolerance to apply | ||
538 | * @return true if "|a1-a2|<=t" holds. | ||
539 | */ | ||
540 | bool | ||
541 | GNUNET_TIME_absolute_approx_eq (struct GNUNET_TIME_Absolute a1, | ||
542 | struct GNUNET_TIME_Absolute a2, | ||
543 | struct GNUNET_TIME_Relative t); | ||
544 | |||
545 | |||
546 | /** | ||
520 | * Calculate the estimate time of arrival/completion | 547 | * Calculate the estimate time of arrival/completion |
521 | * for an operation. | 548 | * for an operation. |
522 | * | 549 | * |
diff --git a/src/messenger/plugin_gnsrecord_messenger.c b/src/messenger/plugin_gnsrecord_messenger.c index 2219f0bde..e09a0330d 100644 --- a/src/messenger/plugin_gnsrecord_messenger.c +++ b/src/messenger/plugin_gnsrecord_messenger.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2021 GNUnet e.V. | 3 | Copyright (C) 2021--2022 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -63,12 +63,30 @@ messenger_value_to_string (void *cls, | |||
63 | char *key = GNUNET_STRINGS_data_to_string_alloc (&(record->key), sizeof(struct GNUNET_HashCode)); | 63 | char *key = GNUNET_STRINGS_data_to_string_alloc (&(record->key), sizeof(struct GNUNET_HashCode)); |
64 | 64 | ||
65 | char *ret; | 65 | char *ret; |
66 | GNUNET_asprintf (&ret, "%s-%s", door, key); | 66 | GNUNET_asprintf (&ret, "%s-%s", key, door); |
67 | GNUNET_free (key); | 67 | GNUNET_free (key); |
68 | GNUNET_free (door); | 68 | GNUNET_free (door); |
69 | return ret; | 69 | return ret; |
70 | } | 70 | } |
71 | case GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_DETAILS: | ||
72 | { | ||
73 | if (data_size != sizeof(struct GNUNET_MESSENGER_RoomDetailsRecord)) | ||
74 | { | ||
75 | GNUNET_break_op (0); | ||
76 | return NULL; | ||
77 | } | ||
78 | |||
79 | const struct GNUNET_MESSENGER_RoomDetailsRecord *record = data; | ||
71 | 80 | ||
81 | char *name = GNUNET_strndup(record->name, 256); | ||
82 | char *flags = GNUNET_STRINGS_data_to_string_alloc (&(record->flags), sizeof(uint32_t)); | ||
83 | |||
84 | char *ret; | ||
85 | GNUNET_asprintf (&ret, "%s-%s", flags, name); | ||
86 | GNUNET_free (flags); | ||
87 | GNUNET_free (name); | ||
88 | return ret; | ||
89 | } | ||
72 | default: | 90 | default: |
73 | return NULL; | 91 | return NULL; |
74 | } | 92 | } |
@@ -141,7 +159,43 @@ messenger_string_to_value (void *cls, | |||
141 | *data_size = sizeof(struct GNUNET_MESSENGER_RoomEntryRecord); | 159 | *data_size = sizeof(struct GNUNET_MESSENGER_RoomEntryRecord); |
142 | return GNUNET_OK; | 160 | return GNUNET_OK; |
143 | } | 161 | } |
162 | case GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_DETAILS: | ||
163 | { | ||
164 | char flags [7]; | ||
165 | const char *dash; | ||
166 | |||
167 | if ((NULL == (dash = strchr (s, '-'))) || | ||
168 | (1 != sscanf (s, "%7s-", flags)) || | ||
169 | (strlen (dash + 1) > 256)) | ||
170 | { | ||
171 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
172 | _ ("Unable to parse MESSENGER_ROOM_DETAILS record `%s'\n"), | ||
173 | s); | ||
174 | return GNUNET_SYSERR; | ||
175 | } | ||
176 | |||
177 | struct GNUNET_MESSENGER_RoomDetailsRecord *record = GNUNET_new ( | ||
178 | struct GNUNET_MESSENGER_RoomDetailsRecord | ||
179 | ); | ||
180 | |||
181 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (flags, | ||
182 | strlen (flags), | ||
183 | &(record->flags), | ||
184 | sizeof(uint32_t))) | ||
185 | { | ||
186 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
187 | _ ("Unable to parse MESSENGER_ROOM_DETAILS record `%s'\n"), | ||
188 | s); | ||
189 | GNUNET_free (record); | ||
190 | return GNUNET_SYSERR; | ||
191 | } | ||
144 | 192 | ||
193 | GNUNET_memcpy(record->name, dash + 1, strlen(dash + 1)); | ||
194 | |||
195 | *data = record; | ||
196 | *data_size = sizeof(struct GNUNET_MESSENGER_RoomDetailsRecord); | ||
197 | return GNUNET_OK; | ||
198 | } | ||
145 | default: | 199 | default: |
146 | return GNUNET_SYSERR; | 200 | return GNUNET_SYSERR; |
147 | } | 201 | } |
@@ -158,6 +212,7 @@ static struct | |||
158 | uint32_t number; | 212 | uint32_t number; |
159 | } name_map[] = { | 213 | } name_map[] = { |
160 | { "MESSENGER_ROOM_ENTRY", GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY }, | 214 | { "MESSENGER_ROOM_ENTRY", GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY }, |
215 | { "MESSENGER_ROOM_DETAILS", GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_DETAILS }, | ||
161 | { NULL, UINT32_MAX } | 216 | { NULL, UINT32_MAX } |
162 | }; | 217 | }; |
163 | 218 | ||
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am index 2441b864a..51708dd67 100644 --- a/src/namestore/Makefile.am +++ b/src/namestore/Makefile.am | |||
@@ -39,7 +39,6 @@ if HAVE_SQLITE | |||
39 | SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la | 39 | SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la |
40 | SQLITE_TESTS = test_plugin_namestore_sqlite \ | 40 | SQLITE_TESTS = test_plugin_namestore_sqlite \ |
41 | test_namestore_api_store_sqlite \ | 41 | test_namestore_api_store_sqlite \ |
42 | test_namestore_api_store_locking_sqlite \ | ||
43 | test_namestore_api_store_update_sqlite \ | 42 | test_namestore_api_store_update_sqlite \ |
44 | test_namestore_api_zone_iteration_sqlite \ | 43 | test_namestore_api_zone_iteration_sqlite \ |
45 | test_namestore_api_remove_sqlite \ | 44 | test_namestore_api_remove_sqlite \ |
@@ -250,16 +249,6 @@ test_namestore_api_store_sqlite_LDADD = \ | |||
250 | $(top_builddir)/src/identity/libgnunetidentity.la \ | 249 | $(top_builddir)/src/identity/libgnunetidentity.la \ |
251 | libgnunetnamestore.la | 250 | libgnunetnamestore.la |
252 | 251 | ||
253 | test_namestore_api_store_locking_sqlite_SOURCES = \ | ||
254 | test_namestore_api_store_locking.c | ||
255 | test_namestore_api_store_locking_sqlite_LDADD = \ | ||
256 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
257 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
258 | $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ | ||
259 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
260 | libgnunetnamestore.la | ||
261 | |||
262 | |||
263 | test_namestore_api_store_postgres_SOURCES = \ | 252 | test_namestore_api_store_postgres_SOURCES = \ |
264 | test_namestore_api_store.c | 253 | test_namestore_api_store.c |
265 | test_namestore_api_store_postgres_LDADD = \ | 254 | test_namestore_api_store_postgres_LDADD = \ |
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c index d735822fb..95260ff9c 100644 --- a/src/namestore/gnunet-service-namestore.c +++ b/src/namestore/gnunet-service-namestore.c | |||
@@ -122,24 +122,6 @@ struct ZoneIteration | |||
122 | }; | 122 | }; |
123 | 123 | ||
124 | /** | 124 | /** |
125 | * Lock on a record set | ||
126 | */ | ||
127 | struct RecordsLock | ||
128 | { | ||
129 | /* DLL */ | ||
130 | struct RecordsLock *prev; | ||
131 | |||
132 | /* DLL */ | ||
133 | struct RecordsLock *next; | ||
134 | |||
135 | /* Hash of the locked label */ | ||
136 | struct GNUNET_HashCode label_hash; | ||
137 | |||
138 | /* Client locking the zone */ | ||
139 | struct NamestoreClient *client; | ||
140 | }; | ||
141 | |||
142 | /** | ||
143 | * A namestore client | 125 | * A namestore client |
144 | */ | 126 | */ |
145 | struct NamestoreClient | 127 | struct NamestoreClient |
@@ -411,16 +393,6 @@ static struct StoreActivity *sa_head; | |||
411 | static struct StoreActivity *sa_tail; | 393 | static struct StoreActivity *sa_tail; |
412 | 394 | ||
413 | /** | 395 | /** |
414 | * Head of the DLL of record set locks | ||
415 | */ | ||
416 | static struct RecordsLock *locks_head; | ||
417 | |||
418 | /** | ||
419 | * Tail of the DLL of record set locks | ||
420 | */ | ||
421 | static struct RecordsLock *locks_tail; | ||
422 | |||
423 | /** | ||
424 | * Notification context shared by all monitors. | 396 | * Notification context shared by all monitors. |
425 | */ | 397 | */ |
426 | static struct GNUNET_NotificationContext *monitor_nc; | 398 | static struct GNUNET_NotificationContext *monitor_nc; |
@@ -447,7 +419,6 @@ static void | |||
447 | cleanup_task (void *cls) | 419 | cleanup_task (void *cls) |
448 | { | 420 | { |
449 | struct CacheOperation *cop; | 421 | struct CacheOperation *cop; |
450 | struct RecordsLock *lock; | ||
451 | 422 | ||
452 | (void) cls; | 423 | (void) cls; |
453 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n"); | 424 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n"); |
@@ -459,13 +430,6 @@ cleanup_task (void *cls) | |||
459 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); | 430 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); |
460 | GNUNET_free (cop); | 431 | GNUNET_free (cop); |
461 | } | 432 | } |
462 | while (NULL != (lock = locks_head)) | ||
463 | { | ||
464 | GNUNET_CONTAINER_DLL_remove (locks_head, | ||
465 | locks_tail, | ||
466 | lock); | ||
467 | GNUNET_free (lock); | ||
468 | } | ||
469 | 433 | ||
470 | if (NULL != namecache) | 434 | if (NULL != namecache) |
471 | { | 435 | { |
@@ -1154,7 +1118,6 @@ client_disconnect_cb (void *cls, | |||
1154 | struct NamestoreClient *nc = app_ctx; | 1118 | struct NamestoreClient *nc = app_ctx; |
1155 | struct ZoneIteration *no; | 1119 | struct ZoneIteration *no; |
1156 | struct CacheOperation *cop; | 1120 | struct CacheOperation *cop; |
1157 | struct RecordsLock *lock; | ||
1158 | 1121 | ||
1159 | (void) cls; | 1122 | (void) cls; |
1160 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client); | 1123 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client); |
@@ -1205,15 +1168,6 @@ client_disconnect_cb (void *cls, | |||
1205 | for (cop = cop_head; NULL != cop; cop = cop->next) | 1168 | for (cop = cop_head; NULL != cop; cop = cop->next) |
1206 | if (nc == cop->nc) | 1169 | if (nc == cop->nc) |
1207 | cop->nc = NULL; | 1170 | cop->nc = NULL; |
1208 | for (lock = locks_head; NULL != lock; lock = lock->next) | ||
1209 | { | ||
1210 | if (nc != lock->client) | ||
1211 | continue; | ||
1212 | GNUNET_CONTAINER_DLL_remove (locks_head, | ||
1213 | locks_tail, | ||
1214 | lock); | ||
1215 | GNUNET_free (lock); | ||
1216 | } | ||
1217 | GNUNET_free (nc); | 1171 | GNUNET_free (nc); |
1218 | } | 1172 | } |
1219 | 1173 | ||
@@ -1407,105 +1361,6 @@ check_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1407 | return GNUNET_OK; | 1361 | return GNUNET_OK; |
1408 | } | 1362 | } |
1409 | 1363 | ||
1410 | static void | ||
1411 | calculate_lock_hash (const char *label, | ||
1412 | const struct GNUNET_IDENTITY_PrivateKey *zone, | ||
1413 | struct GNUNET_HashCode *result) | ||
1414 | { | ||
1415 | struct GNUNET_HashContext *hctx; | ||
1416 | |||
1417 | hctx = GNUNET_CRYPTO_hash_context_start (); | ||
1418 | GNUNET_CRYPTO_hash_context_read (hctx, label, strlen (label)); | ||
1419 | GNUNET_CRYPTO_hash_context_read (hctx, zone, | ||
1420 | sizeof (*zone)); | ||
1421 | GNUNET_CRYPTO_hash_context_finish (hctx, result); | ||
1422 | } | ||
1423 | |||
1424 | /** | ||
1425 | * Release a lock on a record set. | ||
1426 | * Does nothing if lock not held. | ||
1427 | * | ||
1428 | * @param label the label of the record set | ||
1429 | * @param zone the zone | ||
1430 | * @param nc the client releasing the lock | ||
1431 | */ | ||
1432 | static void | ||
1433 | NST_label_lock_release (const char *label, | ||
1434 | const struct GNUNET_IDENTITY_PrivateKey *zone, | ||
1435 | const struct NamestoreClient *nc) | ||
1436 | { | ||
1437 | struct GNUNET_HashCode label_hash; | ||
1438 | struct RecordsLock *lock; | ||
1439 | |||
1440 | calculate_lock_hash (label, zone, &label_hash); | ||
1441 | for (lock = locks_head; NULL != lock; lock = lock->next) | ||
1442 | if (0 == memcmp (&label_hash, &lock->label_hash, sizeof (label_hash))) | ||
1443 | break; | ||
1444 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1445 | "Record locked: %s\n", (NULL == lock) ? "No" : "Yes"); | ||
1446 | if (NULL == lock) | ||
1447 | return; | ||
1448 | if (lock->client != nc) | ||
1449 | { | ||
1450 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1451 | "Lock is held by other client on `%s'\n", label); | ||
1452 | return; | ||
1453 | } | ||
1454 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1455 | "Unocking %s\n", GNUNET_h2s (&label_hash)); | ||
1456 | GNUNET_CONTAINER_DLL_remove (locks_head, | ||
1457 | locks_tail, | ||
1458 | lock); | ||
1459 | GNUNET_free (lock); | ||
1460 | } | ||
1461 | |||
1462 | /** | ||
1463 | * Get/set a lock on a record set. | ||
1464 | * May be called multiple times but will | ||
1465 | * not aquire additional locks. | ||
1466 | * | ||
1467 | * @param the label of the record set | ||
1468 | * @param the zone | ||
1469 | * @param the client doing the locking | ||
1470 | * @return GNUNET_YES if lock retrieved or set already. | ||
1471 | */ | ||
1472 | static enum GNUNET_GenericReturnValue | ||
1473 | NST_label_lock (const char *label, | ||
1474 | const struct GNUNET_IDENTITY_PrivateKey *zone, | ||
1475 | struct NamestoreClient *nc) | ||
1476 | { | ||
1477 | struct GNUNET_HashCode label_hash; | ||
1478 | struct RecordsLock *lock; | ||
1479 | |||
1480 | calculate_lock_hash (label, zone, &label_hash); | ||
1481 | for (lock = locks_head; NULL != lock; lock = lock->next) | ||
1482 | if (0 == memcmp (&label_hash, &lock->label_hash, sizeof (label_hash))) | ||
1483 | break; | ||
1484 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1485 | "Record locked: %s\n", (NULL == lock) ? "No" : "Yes"); | ||
1486 | if (NULL != lock) | ||
1487 | { | ||
1488 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1489 | "Client holds lock: %s\n", (lock->client != nc) ? "No" : "Yes"); | ||
1490 | if (lock->client != nc) | ||
1491 | { | ||
1492 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1493 | "Lock is held by other client on `%s'\n", label); | ||
1494 | return GNUNET_NO; | ||
1495 | } | ||
1496 | return GNUNET_YES; | ||
1497 | } | ||
1498 | lock = GNUNET_new (struct RecordsLock); | ||
1499 | lock->client = nc; | ||
1500 | memcpy (&lock->label_hash, &label_hash, sizeof (label_hash)); | ||
1501 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1502 | "Locking %s\n", GNUNET_h2s (&label_hash)); | ||
1503 | GNUNET_CONTAINER_DLL_insert (locks_head, | ||
1504 | locks_tail, | ||
1505 | lock); | ||
1506 | return GNUNET_YES; | ||
1507 | } | ||
1508 | |||
1509 | 1364 | ||
1510 | /** | 1365 | /** |
1511 | * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message | 1366 | * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message |
@@ -1520,7 +1375,6 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1520 | struct GNUNET_MQ_Envelope *env; | 1375 | struct GNUNET_MQ_Envelope *env; |
1521 | struct LabelLookupResponseMessage *llr_msg; | 1376 | struct LabelLookupResponseMessage *llr_msg; |
1522 | struct RecordLookupContext rlc; | 1377 | struct RecordLookupContext rlc; |
1523 | struct RecordsLock *lock; | ||
1524 | struct GNUNET_HashCode label_hash; | 1378 | struct GNUNET_HashCode label_hash; |
1525 | const char *name_tmp; | 1379 | const char *name_tmp; |
1526 | char *res_name; | 1380 | char *res_name; |
@@ -1544,28 +1398,6 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1544 | return; | 1398 | return; |
1545 | } | 1399 | } |
1546 | name_len = strlen (conv_name) + 1; | 1400 | name_len = strlen (conv_name) + 1; |
1547 | if (GNUNET_YES == ntohl (ll_msg->locking)) | ||
1548 | { | ||
1549 | if (GNUNET_NO == NST_label_lock (conv_name, &ll_msg->zone, nc)) | ||
1550 | { | ||
1551 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1552 | "Lock is held by other client on `%s'\n", conv_name); | ||
1553 | env = | ||
1554 | GNUNET_MQ_msg_extra (llr_msg, | ||
1555 | name_len, | ||
1556 | GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE); | ||
1557 | llr_msg->gns_header.r_id = ll_msg->gns_header.r_id; | ||
1558 | llr_msg->private_key = ll_msg->zone; | ||
1559 | llr_msg->name_len = htons (name_len); | ||
1560 | llr_msg->rd_count = htons (0); | ||
1561 | llr_msg->rd_len = htons (0); | ||
1562 | llr_msg->found = htons (GNUNET_SYSERR); | ||
1563 | GNUNET_memcpy (&llr_msg[1], conv_name, name_len); | ||
1564 | GNUNET_MQ_send (nc->mq, env); | ||
1565 | GNUNET_free (conv_name); | ||
1566 | return; | ||
1567 | } | ||
1568 | } | ||
1569 | rlc.label = conv_name; | 1401 | rlc.label = conv_name; |
1570 | rlc.found = GNUNET_NO; | 1402 | rlc.found = GNUNET_NO; |
1571 | rlc.res_rd_count = 0; | 1403 | rlc.res_rd_count = 0; |
@@ -1699,7 +1531,6 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1699 | unsigned int rd_count; | 1531 | unsigned int rd_count; |
1700 | int res; | 1532 | int res; |
1701 | struct StoreActivity *sa; | 1533 | struct StoreActivity *sa; |
1702 | struct RecordsLock *lock; | ||
1703 | struct GNUNET_HashCode label_hash; | 1534 | struct GNUNET_HashCode label_hash; |
1704 | struct GNUNET_TIME_Absolute existing_block_exp; | 1535 | struct GNUNET_TIME_Absolute existing_block_exp; |
1705 | struct GNUNET_TIME_Absolute new_block_exp; | 1536 | struct GNUNET_TIME_Absolute new_block_exp; |
@@ -1753,20 +1584,6 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1753 | GNUNET_SERVICE_client_continue (nc->client); | 1584 | GNUNET_SERVICE_client_continue (nc->client); |
1754 | return; | 1585 | return; |
1755 | } | 1586 | } |
1756 | if (GNUNET_YES == ntohl (rp_msg->locking)) | ||
1757 | { | ||
1758 | if (GNUNET_NO == NST_label_lock (conv_name, &rp_msg->private_key, nc)) | ||
1759 | { | ||
1760 | send_store_response (nc, GNUNET_SYSERR, _ ("Record set locked."), rid); | ||
1761 | GNUNET_SERVICE_client_continue (nc->client); | ||
1762 | GNUNET_free (conv_name); | ||
1763 | return; | ||
1764 | } | ||
1765 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1766 | "Client has lock on `%s', continuing.\n", conv_name); | ||
1767 | if (GNUNET_YES == ntohl (rp_msg->locking)) | ||
1768 | NST_label_lock_release (conv_name, &rp_msg->private_key, nc); | ||
1769 | } | ||
1770 | 1587 | ||
1771 | GNUNET_STATISTICS_update (statistics, | 1588 | GNUNET_STATISTICS_update (statistics, |
1772 | "Well-formed store requests received", | 1589 | "Well-formed store requests received", |
diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h index 0f3ffa837..583ec1e68 100644 --- a/src/namestore/namestore.h +++ b/src/namestore/namestore.h | |||
@@ -68,11 +68,6 @@ struct RecordStoreMessage | |||
68 | struct GNUNET_TIME_AbsoluteNBO expire; | 68 | struct GNUNET_TIME_AbsoluteNBO expire; |
69 | 69 | ||
70 | /** | 70 | /** |
71 | * Unock the label with this request. | ||
72 | */ | ||
73 | uint32_t locking GNUNET_PACKED; | ||
74 | |||
75 | /** | ||
76 | * Name length | 71 | * Name length |
77 | */ | 72 | */ |
78 | uint16_t name_len GNUNET_PACKED; | 73 | uint16_t name_len GNUNET_PACKED; |
@@ -151,11 +146,6 @@ struct LabelLookupMessage | |||
151 | uint32_t label_len GNUNET_PACKED; | 146 | uint32_t label_len GNUNET_PACKED; |
152 | 147 | ||
153 | /** | 148 | /** |
154 | * Lock the label with this lookup | ||
155 | */ | ||
156 | uint32_t locking GNUNET_PACKED; | ||
157 | |||
158 | /** | ||
159 | * The private key of the zone to look up in | 149 | * The private key of the zone to look up in |
160 | */ | 150 | */ |
161 | struct GNUNET_IDENTITY_PrivateKey zone; | 151 | struct GNUNET_IDENTITY_PrivateKey zone; |
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c index a7380bbde..73f985803 100644 --- a/src/namestore/namestore_api.c +++ b/src/namestore/namestore_api.c | |||
@@ -411,7 +411,7 @@ handle_record_store_response (void *cls, | |||
411 | return; | 411 | return; |
412 | if (NULL != qe->cont) | 412 | if (NULL != qe->cont) |
413 | qe->cont (qe->cont_cls, res, | 413 | qe->cont (qe->cont_cls, res, |
414 | (GNUNET_OK == res) ? NULL : emsg); | 414 | (GNUNET_OK == res) ? NULL : emsg); |
415 | free_qe (qe); | 415 | free_qe (qe); |
416 | } | 416 | } |
417 | 417 | ||
@@ -482,7 +482,7 @@ handle_lookup_result (void *cls, const struct LabelLookupResponseMessage *msg) | |||
482 | int16_t found = (int16_t) ntohs (msg->found); | 482 | int16_t found = (int16_t) ntohs (msg->found); |
483 | 483 | ||
484 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_LOOKUP_RESULT (found=%i)\n", | 484 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_LOOKUP_RESULT (found=%i)\n", |
485 | found); | 485 | found); |
486 | qe = find_qe (h, ntohl (msg->gns_header.r_id)); | 486 | qe = find_qe (h, ntohl (msg->gns_header.r_id)); |
487 | if (NULL == qe) | 487 | if (NULL == qe) |
488 | return; | 488 | return; |
@@ -820,9 +820,9 @@ reconnect (struct GNUNET_NAMESTORE_Handle *h) | |||
820 | { | 820 | { |
821 | struct GNUNET_MQ_MessageHandler handlers[] = | 821 | struct GNUNET_MQ_MessageHandler handlers[] = |
822 | { GNUNET_MQ_hd_var_size (record_store_response, | 822 | { GNUNET_MQ_hd_var_size (record_store_response, |
823 | GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE, | 823 | GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE, |
824 | struct RecordStoreResponseMessage, | 824 | struct RecordStoreResponseMessage, |
825 | h), | 825 | h), |
826 | GNUNET_MQ_hd_var_size (zone_to_name_response, | 826 | GNUNET_MQ_hd_var_size (zone_to_name_response, |
827 | GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE, | 827 | GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE, |
828 | struct ZoneToNameResponseMessage, | 828 | struct ZoneToNameResponseMessage, |
@@ -1013,16 +1013,16 @@ warn_delay (void *cls) | |||
1013 | GNUNET_NAMESTORE_cancel (qe); | 1013 | GNUNET_NAMESTORE_cancel (qe); |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | |||
1016 | struct GNUNET_NAMESTORE_QueueEntry * | 1017 | struct GNUNET_NAMESTORE_QueueEntry * |
1017 | records_store_ ( | 1018 | GNUNET_NAMESTORE_records_store ( |
1018 | struct GNUNET_NAMESTORE_Handle *h, | 1019 | struct GNUNET_NAMESTORE_Handle *h, |
1019 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | 1020 | const struct GNUNET_IDENTITY_PrivateKey *pkey, |
1020 | const char *label, | 1021 | const char *label, |
1021 | unsigned int rd_count, | 1022 | unsigned int rd_count, |
1022 | const struct GNUNET_GNSRECORD_Data *rd, | 1023 | const struct GNUNET_GNSRECORD_Data *rd, |
1023 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | 1024 | GNUNET_NAMESTORE_ContinuationWithStatus cont, |
1024 | void *cont_cls, | 1025 | void *cont_cls) |
1025 | int locking) | ||
1026 | { | 1026 | { |
1027 | struct GNUNET_NAMESTORE_QueueEntry *qe; | 1027 | struct GNUNET_NAMESTORE_QueueEntry *qe; |
1028 | struct GNUNET_MQ_Envelope *env; | 1028 | struct GNUNET_MQ_Envelope *env; |
@@ -1067,9 +1067,8 @@ records_store_ ( | |||
1067 | msg->name_len = htons (name_len); | 1067 | msg->name_len = htons (name_len); |
1068 | msg->rd_count = htons (rd_count); | 1068 | msg->rd_count = htons (rd_count); |
1069 | msg->rd_len = htons (rd_ser_len); | 1069 | msg->rd_len = htons (rd_ser_len); |
1070 | msg->reserved = ntohs(0); | 1070 | msg->reserved = ntohs (0); |
1071 | msg->private_key = *pkey; | 1071 | msg->private_key = *pkey; |
1072 | msg->locking = htonl (locking); | ||
1073 | 1072 | ||
1074 | name_tmp = (char *) &msg[1]; | 1073 | name_tmp = (char *) &msg[1]; |
1075 | GNUNET_memcpy (name_tmp, label, name_len); | 1074 | GNUNET_memcpy (name_tmp, label, name_len); |
@@ -1101,22 +1100,11 @@ records_store_ ( | |||
1101 | return qe; | 1100 | return qe; |
1102 | } | 1101 | } |
1103 | 1102 | ||
1103 | /** | ||
1104 | * TODO: Experimental API will replace API above. | ||
1105 | */ | ||
1104 | struct GNUNET_NAMESTORE_QueueEntry * | 1106 | struct GNUNET_NAMESTORE_QueueEntry * |
1105 | GNUNET_NAMESTORE_records_store ( | 1107 | GNUNET_NAMESTORE_records_replace ( |
1106 | struct GNUNET_NAMESTORE_Handle *h, | ||
1107 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
1108 | const char *label, | ||
1109 | unsigned int rd_count, | ||
1110 | const struct GNUNET_GNSRECORD_Data *rd, | ||
1111 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | ||
1112 | void *cont_cls) | ||
1113 | { | ||
1114 | return records_store_ (h, pkey, label, | ||
1115 | rd_count, rd, cont, cont_cls, GNUNET_NO); | ||
1116 | } | ||
1117 | |||
1118 | struct GNUNET_NAMESTORE_QueueEntry * | ||
1119 | GNUNET_NAMESTORE_records_commit ( | ||
1120 | struct GNUNET_NAMESTORE_Handle *h, | 1108 | struct GNUNET_NAMESTORE_Handle *h, |
1121 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | 1109 | const struct GNUNET_IDENTITY_PrivateKey *pkey, |
1122 | const char *label, | 1110 | const char *label, |
@@ -1125,21 +1113,19 @@ GNUNET_NAMESTORE_records_commit ( | |||
1125 | GNUNET_NAMESTORE_ContinuationWithStatus cont, | 1113 | GNUNET_NAMESTORE_ContinuationWithStatus cont, |
1126 | void *cont_cls) | 1114 | void *cont_cls) |
1127 | { | 1115 | { |
1128 | return records_store_ (h, pkey, label, | 1116 | return GNUNET_NAMESTORE_records_store (h, pkey, label, rd_count, rd, |
1129 | rd_count, rd, cont, cont_cls, GNUNET_YES); | 1117 | cont, cont_cls); |
1130 | } | 1118 | } |
1131 | 1119 | ||
1132 | |||
1133 | struct GNUNET_NAMESTORE_QueueEntry * | 1120 | struct GNUNET_NAMESTORE_QueueEntry * |
1134 | records_lookup_ ( | 1121 | GNUNET_NAMESTORE_records_lookup ( |
1135 | struct GNUNET_NAMESTORE_Handle *h, | 1122 | struct GNUNET_NAMESTORE_Handle *h, |
1136 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | 1123 | const struct GNUNET_IDENTITY_PrivateKey *pkey, |
1137 | const char *label, | 1124 | const char *label, |
1138 | GNUNET_SCHEDULER_TaskCallback error_cb, | 1125 | GNUNET_SCHEDULER_TaskCallback error_cb, |
1139 | void *error_cb_cls, | 1126 | void *error_cb_cls, |
1140 | GNUNET_NAMESTORE_RecordMonitor rm, | 1127 | GNUNET_NAMESTORE_RecordMonitor rm, |
1141 | void *rm_cls, | 1128 | void *rm_cls) |
1142 | int locking) | ||
1143 | { | 1129 | { |
1144 | struct GNUNET_NAMESTORE_QueueEntry *qe; | 1130 | struct GNUNET_NAMESTORE_QueueEntry *qe; |
1145 | struct GNUNET_MQ_Envelope *env; | 1131 | struct GNUNET_MQ_Envelope *env; |
@@ -1167,7 +1153,6 @@ records_lookup_ ( | |||
1167 | msg->gns_header.r_id = htonl (qe->op_id); | 1153 | msg->gns_header.r_id = htonl (qe->op_id); |
1168 | msg->zone = *pkey; | 1154 | msg->zone = *pkey; |
1169 | msg->label_len = htonl (label_len); | 1155 | msg->label_len = htonl (label_len); |
1170 | msg->locking = htonl (locking); | ||
1171 | GNUNET_memcpy (&msg[1], label, label_len); | 1156 | GNUNET_memcpy (&msg[1], label, label_len); |
1172 | if (NULL == h->mq) | 1157 | if (NULL == h->mq) |
1173 | qe->env = env; | 1158 | qe->env = env; |
@@ -1176,22 +1161,12 @@ records_lookup_ ( | |||
1176 | return qe; | 1161 | return qe; |
1177 | } | 1162 | } |
1178 | 1163 | ||
1179 | struct GNUNET_NAMESTORE_QueueEntry * | ||
1180 | GNUNET_NAMESTORE_records_lookup ( | ||
1181 | struct GNUNET_NAMESTORE_Handle *h, | ||
1182 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | ||
1183 | const char *label, | ||
1184 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
1185 | void *error_cb_cls, | ||
1186 | GNUNET_NAMESTORE_RecordMonitor rm, | ||
1187 | void *rm_cls) | ||
1188 | { | ||
1189 | return records_lookup_ (h, pkey, label, | ||
1190 | error_cb, error_cb_cls, rm, rm_cls, GNUNET_NO); | ||
1191 | } | ||
1192 | 1164 | ||
1165 | /** | ||
1166 | * TODO experimental API. Will replace old API above. | ||
1167 | */ | ||
1193 | struct GNUNET_NAMESTORE_QueueEntry * | 1168 | struct GNUNET_NAMESTORE_QueueEntry * |
1194 | GNUNET_NAMESTORE_records_open ( | 1169 | GNUNET_NAMESTORE_records_select ( |
1195 | struct GNUNET_NAMESTORE_Handle *h, | 1170 | struct GNUNET_NAMESTORE_Handle *h, |
1196 | const struct GNUNET_IDENTITY_PrivateKey *pkey, | 1171 | const struct GNUNET_IDENTITY_PrivateKey *pkey, |
1197 | const char *label, | 1172 | const char *label, |
@@ -1200,8 +1175,9 @@ GNUNET_NAMESTORE_records_open ( | |||
1200 | GNUNET_NAMESTORE_RecordMonitor rm, | 1175 | GNUNET_NAMESTORE_RecordMonitor rm, |
1201 | void *rm_cls) | 1176 | void *rm_cls) |
1202 | { | 1177 | { |
1203 | return records_lookup_ (h, pkey, label, | 1178 | return GNUNET_NAMESTORE_records_lookup (h, pkey, label, |
1204 | error_cb, error_cb_cls, rm, rm_cls, GNUNET_YES); | 1179 | error_cb, error_cb_cls, |
1180 | rm, rm_cls); | ||
1205 | } | 1181 | } |
1206 | 1182 | ||
1207 | struct GNUNET_NAMESTORE_QueueEntry * | 1183 | struct GNUNET_NAMESTORE_QueueEntry * |
@@ -1364,5 +1340,48 @@ GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe) | |||
1364 | free_qe (qe); | 1340 | free_qe (qe); |
1365 | } | 1341 | } |
1366 | 1342 | ||
1343 | /** | ||
1344 | * New API draft. Experimental | ||
1345 | */ | ||
1346 | |||
1347 | struct GNUNET_NAMESTORE_QueueEntry * | ||
1348 | GNUNET_NAMESTORE_transaction_begin (struct GNUNET_NAMESTORE_Handle *h, | ||
1349 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
1350 | void *error_cb_cls) | ||
1351 | { | ||
1352 | GNUNET_break (0); | ||
1353 | return NULL; | ||
1354 | } | ||
1355 | |||
1356 | |||
1357 | struct GNUNET_NAMESTORE_QueueEntry * | ||
1358 | GNUNET_NAMESTORE_transaction_abort (struct GNUNET_NAMESTORE_Handle *h, | ||
1359 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
1360 | void *error_cb_cls) | ||
1361 | { | ||
1362 | GNUNET_break (0); | ||
1363 | return NULL; | ||
1364 | } | ||
1365 | |||
1366 | |||
1367 | /** | ||
1368 | * Commit a namestore transaction. | ||
1369 | * Saves all actions performed since #GNUNET_NAMESTORE_transaction_begin | ||
1370 | * | ||
1371 | * @param h handle to the namestore | ||
1372 | * @param error_cb function to call on error (i.e. disconnect or unable to get lock) | ||
1373 | * the handle is afterwards invalid | ||
1374 | * @param error_cb_cls closure for @a error_cb | ||
1375 | * @return handle to abort the request | ||
1376 | */ | ||
1377 | struct GNUNET_NAMESTORE_QueueEntry * | ||
1378 | GNUNET_NAMESTORE_transaction_commit (struct GNUNET_NAMESTORE_Handle *h, | ||
1379 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
1380 | void *error_cb_cls) | ||
1381 | { | ||
1382 | GNUNET_break (0); | ||
1383 | return NULL; | ||
1384 | } | ||
1385 | |||
1367 | 1386 | ||
1368 | /* end of namestore_api.c */ | 1387 | /* end of namestore_api.c */ |
diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 2c11f5202..f3d246c36 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c | |||
@@ -1086,6 +1086,12 @@ extract_uint64 (void *cls, | |||
1086 | fnum)) | 1086 | fnum)) |
1087 | { | 1087 | { |
1088 | GNUNET_break (0); | 1088 | GNUNET_break (0); |
1089 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1090 | "Got length %u for field `%s'\n", | ||
1091 | PQgetlength (result, | ||
1092 | row, | ||
1093 | fnum), | ||
1094 | fname); | ||
1089 | return GNUNET_SYSERR; | 1095 | return GNUNET_SYSERR; |
1090 | } | 1096 | } |
1091 | res = (uint64_t *) PQgetvalue (result, | 1097 | res = (uint64_t *) PQgetvalue (result, |
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index 69b05fb13..2b09ccf63 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am | |||
@@ -1528,6 +1528,7 @@ test_transport_simple_send_string.sh \ | |||
1528 | test_transport_simple_send.sh \ | 1528 | test_transport_simple_send.sh \ |
1529 | test_transport_simple_send_broadcast.sh \ | 1529 | test_transport_simple_send_broadcast.sh \ |
1530 | test_transport_udp_backchannel.sh \ | 1530 | test_transport_udp_backchannel.sh \ |
1531 | test_transport_simple_send_dv_circle.sh \ | ||
1531 | gnunet-transport-certificate-creation.in \ | 1532 | gnunet-transport-certificate-creation.in \ |
1532 | communicator-unix.conf \ | 1533 | communicator-unix.conf \ |
1533 | test_plugin_hostkey \ | 1534 | test_plugin_hostkey \ |
diff --git a/src/util/.gitignore b/src/util/.gitignore index 51eab71db..0e3449fed 100644 --- a/src/util/.gitignore +++ b/src/util/.gitignore | |||
@@ -36,6 +36,7 @@ test_crypto_ecdh_eddsa | |||
36 | test_crypto_ecdhe | 36 | test_crypto_ecdhe |
37 | test_crypto_ecdsa | 37 | test_crypto_ecdsa |
38 | test_crypto_eddsa | 38 | test_crypto_eddsa |
39 | test_crypto_edx25519 | ||
39 | test_crypto_hash | 40 | test_crypto_hash |
40 | test_crypto_hash_context | 41 | test_crypto_hash_context |
41 | test_crypto_hkdf | 42 | test_crypto_hkdf |
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 406d42b1e..9cb7da15b 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am | |||
@@ -66,6 +66,7 @@ libgnunetutil_la_SOURCES = \ | |||
66 | crypto_ecc_gnsrecord.c \ | 66 | crypto_ecc_gnsrecord.c \ |
67 | $(DLOG) \ | 67 | $(DLOG) \ |
68 | crypto_ecc_setup.c \ | 68 | crypto_ecc_setup.c \ |
69 | crypto_edx25519.c \ | ||
69 | crypto_hash.c \ | 70 | crypto_hash.c \ |
70 | crypto_hash_file.c \ | 71 | crypto_hash_file.c \ |
71 | crypto_hkdf.c \ | 72 | crypto_hkdf.c \ |
@@ -297,6 +298,7 @@ check_PROGRAMS = \ | |||
297 | test_crypto_ecdhe \ | 298 | test_crypto_ecdhe \ |
298 | test_crypto_ecdh_eddsa \ | 299 | test_crypto_ecdh_eddsa \ |
299 | test_crypto_ecdh_ecdsa \ | 300 | test_crypto_ecdh_ecdsa \ |
301 | test_crypto_edx25519 \ | ||
300 | $(DLOG_TEST) \ | 302 | $(DLOG_TEST) \ |
301 | test_crypto_hash \ | 303 | test_crypto_hash \ |
302 | test_crypto_hash_context \ | 304 | test_crypto_hash_context \ |
@@ -470,6 +472,12 @@ test_crypto_eddsa_LDADD = \ | |||
470 | libgnunetutil.la \ | 472 | libgnunetutil.la \ |
471 | $(LIBGCRYPT_LIBS) | 473 | $(LIBGCRYPT_LIBS) |
472 | 474 | ||
475 | test_crypto_edx25519_SOURCES = \ | ||
476 | test_crypto_edx25519.c | ||
477 | test_crypto_edx25519_LDADD = \ | ||
478 | libgnunetutil.la \ | ||
479 | $(LIBGCRYPT_LIBS) | ||
480 | |||
473 | test_crypto_ecc_dlog_SOURCES = \ | 481 | test_crypto_ecc_dlog_SOURCES = \ |
474 | test_crypto_ecc_dlog.c | 482 | test_crypto_ecc_dlog.c |
475 | test_crypto_ecc_dlog_LDADD = \ | 483 | test_crypto_ecc_dlog_LDADD = \ |
diff --git a/src/util/crypto_ecc_gnsrecord.c b/src/util/crypto_ecc_gnsrecord.c index ce41a4699..0ee0570c0 100644 --- a/src/util/crypto_ecc_gnsrecord.c +++ b/src/util/crypto_ecc_gnsrecord.c | |||
@@ -68,28 +68,15 @@ derive_h (const void *pub, | |||
68 | } | 68 | } |
69 | 69 | ||
70 | 70 | ||
71 | /** | 71 | enum GNUNET_GenericReturnValue |
72 | * This is a signature function for EdDSA which takes the | 72 | GNUNET_CRYPTO_eddsa_sign_derived ( |
73 | * secret scalar sk instead of the private seed which is | 73 | const struct GNUNET_CRYPTO_EddsaPrivateKey *pkey, |
74 | * usually the case for crypto APIs. We require this functionality | 74 | const char *label, |
75 | * in order to use derived private keys for signatures we | 75 | const char *context, |
76 | * cannot calculate the inverse of a sk to find the seed | ||
77 | * efficiently. | ||
78 | * | ||
79 | * The resulting signature is a standard EdDSA signature | ||
80 | * which can be verified using the usual APIs. | ||
81 | * | ||
82 | * @param sk the secret scalar | ||
83 | * @param purp the signature purpose | ||
84 | * @param sig the resulting signature | ||
85 | */ | ||
86 | void | ||
87 | GNUNET_CRYPTO_eddsa_sign_with_scalar ( | ||
88 | const struct GNUNET_CRYPTO_EddsaPrivateScalar *priv, | ||
89 | const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, | 76 | const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, |
90 | struct GNUNET_CRYPTO_EddsaSignature *sig) | 77 | struct GNUNET_CRYPTO_EddsaSignature *sig) |
91 | { | 78 | { |
92 | 79 | struct GNUNET_CRYPTO_EddsaPrivateScalar priv; | |
93 | crypto_hash_sha512_state hs; | 80 | crypto_hash_sha512_state hs; |
94 | unsigned char sk[64]; | 81 | unsigned char sk[64]; |
95 | unsigned char r[64]; | 82 | unsigned char r[64]; |
@@ -98,6 +85,14 @@ GNUNET_CRYPTO_eddsa_sign_with_scalar ( | |||
98 | unsigned char zk[32]; | 85 | unsigned char zk[32]; |
99 | unsigned char tmp[32]; | 86 | unsigned char tmp[32]; |
100 | 87 | ||
88 | /** | ||
89 | * Derive the private key | ||
90 | */ | ||
91 | GNUNET_CRYPTO_eddsa_private_key_derive (pkey, | ||
92 | label, | ||
93 | context, | ||
94 | &priv); | ||
95 | |||
101 | crypto_hash_sha512_init (&hs); | 96 | crypto_hash_sha512_init (&hs); |
102 | 97 | ||
103 | /** | 98 | /** |
@@ -108,7 +103,7 @@ GNUNET_CRYPTO_eddsa_sign_with_scalar ( | |||
108 | * sk[0..31] = h * SHA512 (d)[0..31] | 103 | * sk[0..31] = h * SHA512 (d)[0..31] |
109 | * sk[32..63] = SHA512 (d)[32..63] | 104 | * sk[32..63] = SHA512 (d)[32..63] |
110 | */ | 105 | */ |
111 | memcpy (sk, priv->s, 64); | 106 | memcpy (sk, priv.s, 64); |
112 | 107 | ||
113 | /** | 108 | /** |
114 | * Calculate the derived zone key zk' from the | 109 | * Calculate the derived zone key zk' from the |
@@ -172,8 +167,28 @@ GNUNET_CRYPTO_eddsa_sign_with_scalar ( | |||
172 | sodium_memzero (sk, sizeof (sk)); | 167 | sodium_memzero (sk, sizeof (sk)); |
173 | sodium_memzero (r, sizeof (r)); | 168 | sodium_memzero (r, sizeof (r)); |
174 | sodium_memzero (r_mod, sizeof (r_mod)); | 169 | sodium_memzero (r_mod, sizeof (r_mod)); |
170 | return GNUNET_OK; | ||
175 | } | 171 | } |
176 | 172 | ||
173 | enum GNUNET_GenericReturnValue | ||
174 | GNUNET_CRYPTO_ecdsa_sign_derived ( | ||
175 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, | ||
176 | const char *label, | ||
177 | const char *context, | ||
178 | const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, | ||
179 | struct GNUNET_CRYPTO_EcdsaSignature *sig) | ||
180 | { | ||
181 | struct GNUNET_CRYPTO_EcdsaPrivateKey *key; | ||
182 | enum GNUNET_GenericReturnValue res; | ||
183 | key = GNUNET_CRYPTO_ecdsa_private_key_derive (priv, | ||
184 | label, | ||
185 | context); | ||
186 | res = GNUNET_CRYPTO_ecdsa_sign_ (key, | ||
187 | purpose, | ||
188 | sig); | ||
189 | GNUNET_free (key); | ||
190 | return res; | ||
191 | } | ||
177 | 192 | ||
178 | struct GNUNET_CRYPTO_EcdsaPrivateKey * | 193 | struct GNUNET_CRYPTO_EcdsaPrivateKey * |
179 | GNUNET_CRYPTO_ecdsa_private_key_derive ( | 194 | GNUNET_CRYPTO_ecdsa_private_key_derive ( |
diff --git a/src/util/crypto_edx25519.c b/src/util/crypto_edx25519.c new file mode 100644 index 000000000..26b45407e --- /dev/null +++ b/src/util/crypto_edx25519.c | |||
@@ -0,0 +1,418 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2022 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file util/crypto_edx25519.c | ||
23 | * @brief An variant of EdDSA which allows for iterative derivation of key pairs. | ||
24 | * @author Özgür Kesim | ||
25 | * @author Christian Grothoff | ||
26 | * @author Florian Dold | ||
27 | * @author Martin Schanzenbach | ||
28 | */ | ||
29 | #include "platform.h" | ||
30 | #include <gcrypt.h> | ||
31 | #include <sodium.h> | ||
32 | #include "gnunet_crypto_lib.h" | ||
33 | #include "gnunet_strings_lib.h" | ||
34 | |||
35 | #define CURVE "Ed25519" | ||
36 | |||
37 | void | ||
38 | GNUNET_CRYPTO_edx25519_key_clear (struct GNUNET_CRYPTO_Edx25519PrivateKey *pk) | ||
39 | { | ||
40 | memset (pk, 0, sizeof(struct GNUNET_CRYPTO_Edx25519PrivateKey)); | ||
41 | } | ||
42 | |||
43 | |||
44 | void | ||
45 | GNUNET_CRYPTO_edx25519_key_create_from_seed ( | ||
46 | const void *seed, | ||
47 | size_t seedsize, | ||
48 | struct GNUNET_CRYPTO_Edx25519PrivateKey *pk) | ||
49 | { | ||
50 | |||
51 | GNUNET_static_assert (sizeof(*pk) == sizeof(struct GNUNET_HashCode)); | ||
52 | GNUNET_CRYPTO_hash (seed, | ||
53 | seedsize, | ||
54 | (struct GNUNET_HashCode *) pk); | ||
55 | |||
56 | /* Clamp the first half of the key. The second half is used in the signature | ||
57 | * process. */ | ||
58 | pk->a[0] &= 248; | ||
59 | pk->a[31] &= 127; | ||
60 | pk->a[31] |= 64; | ||
61 | } | ||
62 | |||
63 | |||
64 | void | ||
65 | GNUNET_CRYPTO_edx25519_key_create ( | ||
66 | struct GNUNET_CRYPTO_Edx25519PrivateKey *pk) | ||
67 | { | ||
68 | char seed[256 / 8]; | ||
69 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, | ||
70 | seed, | ||
71 | sizeof (seed)); | ||
72 | GNUNET_CRYPTO_edx25519_key_create_from_seed (seed, | ||
73 | sizeof(seed), | ||
74 | pk); | ||
75 | } | ||
76 | |||
77 | |||
78 | void | ||
79 | GNUNET_CRYPTO_edx25519_key_get_public ( | ||
80 | const struct GNUNET_CRYPTO_Edx25519PrivateKey *priv, | ||
81 | struct GNUNET_CRYPTO_Edx25519PublicKey *pub) | ||
82 | { | ||
83 | crypto_scalarmult_ed25519_base_noclamp (pub->q_y, | ||
84 | priv->a); | ||
85 | } | ||
86 | |||
87 | |||
88 | /** | ||
89 | * This function operates the basically same way as the signature function for | ||
90 | * EdDSA. But instead of expanding a private seed (which is usually the case | ||
91 | * for crypto APIs) and using the resulting scalars, it takes the scalars | ||
92 | * directly from Edx25519PrivateKey. We require this functionality in order to | ||
93 | * use derived private keys for signatures. | ||
94 | * | ||
95 | * The resulting signature is a standard EdDSA signature | ||
96 | * which can be verified using the usual APIs. | ||
97 | * | ||
98 | * @param priv the private key (containing two scalars .a and .b) | ||
99 | * @param purp the signature purpose | ||
100 | * @param sig the resulting signature | ||
101 | */ | ||
102 | enum GNUNET_GenericReturnValue | ||
103 | GNUNET_CRYPTO_edx25519_sign_ ( | ||
104 | const struct GNUNET_CRYPTO_Edx25519PrivateKey *priv, | ||
105 | const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, | ||
106 | struct GNUNET_CRYPTO_Edx25519Signature *sig) | ||
107 | { | ||
108 | |||
109 | crypto_hash_sha512_state hs; | ||
110 | unsigned char r[64]; | ||
111 | unsigned char hram[64]; | ||
112 | unsigned char P[32]; | ||
113 | unsigned char r_mod[64]; | ||
114 | unsigned char R[32]; | ||
115 | unsigned char tmp[32]; | ||
116 | |||
117 | crypto_hash_sha512_init (&hs); | ||
118 | |||
119 | /** | ||
120 | * Calculate the public key P from the private scalar in the key. | ||
121 | */ | ||
122 | crypto_scalarmult_ed25519_base_noclamp (P, | ||
123 | priv->a); | ||
124 | |||
125 | /** | ||
126 | * Calculate r: | ||
127 | * r = SHA512 (b ∥ M) | ||
128 | * where M is our message (purpose). | ||
129 | */ | ||
130 | crypto_hash_sha512_update (&hs, | ||
131 | priv->b, | ||
132 | sizeof(priv->b)); | ||
133 | crypto_hash_sha512_update (&hs, | ||
134 | (uint8_t*) purpose, | ||
135 | ntohl (purpose->size)); | ||
136 | crypto_hash_sha512_final (&hs, | ||
137 | r); | ||
138 | |||
139 | /** | ||
140 | * Temporarily put P into S | ||
141 | */ | ||
142 | memcpy (sig->s, P, 32); | ||
143 | |||
144 | /** | ||
145 | * Reduce the scalar value r | ||
146 | */ | ||
147 | crypto_core_ed25519_scalar_reduce (r_mod, r); | ||
148 | |||
149 | /** | ||
150 | * Calculate R := r * G of the signature | ||
151 | */ | ||
152 | crypto_scalarmult_ed25519_base_noclamp (R, r_mod); | ||
153 | memcpy (sig->r, R, sizeof (R)); | ||
154 | |||
155 | /** | ||
156 | * Calculate | ||
157 | * hram := SHA512 (R ∥ P ∥ M) | ||
158 | */ | ||
159 | crypto_hash_sha512_init (&hs); | ||
160 | crypto_hash_sha512_update (&hs, (uint8_t*) sig, 64); | ||
161 | crypto_hash_sha512_update (&hs, (uint8_t*) purpose, | ||
162 | ntohl (purpose->size)); | ||
163 | crypto_hash_sha512_final (&hs, hram); | ||
164 | |||
165 | /** | ||
166 | * Reduce the resulting scalar value | ||
167 | */ | ||
168 | unsigned char hram_mod[64]; | ||
169 | crypto_core_ed25519_scalar_reduce (hram_mod, hram); | ||
170 | |||
171 | /** | ||
172 | * Calculate | ||
173 | * S := r + hram * s mod L | ||
174 | */ | ||
175 | crypto_core_ed25519_scalar_mul (tmp, hram_mod, priv->a); | ||
176 | crypto_core_ed25519_scalar_add (sig->s, tmp, r_mod); | ||
177 | |||
178 | sodium_memzero (r, sizeof (r)); | ||
179 | sodium_memzero (r_mod, sizeof (r_mod)); | ||
180 | |||
181 | return GNUNET_OK; | ||
182 | } | ||
183 | |||
184 | |||
185 | enum GNUNET_GenericReturnValue | ||
186 | GNUNET_CRYPTO_edx25519_verify_ ( | ||
187 | uint32_t purpose, | ||
188 | const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, | ||
189 | const struct GNUNET_CRYPTO_Edx25519Signature *sig, | ||
190 | const struct GNUNET_CRYPTO_Edx25519PublicKey *pub) | ||
191 | { | ||
192 | const unsigned char *m = (const void *) validate; | ||
193 | size_t mlen = ntohl (validate->size); | ||
194 | const unsigned char *s = (const void *) sig; | ||
195 | |||
196 | int res; | ||
197 | |||
198 | if (purpose != ntohl (validate->purpose)) | ||
199 | return GNUNET_SYSERR; /* purpose mismatch */ | ||
200 | |||
201 | res = crypto_sign_verify_detached (s, m, mlen, pub->q_y); | ||
202 | return (res == 0) ? GNUNET_OK : GNUNET_SYSERR; | ||
203 | } | ||
204 | |||
205 | |||
206 | /** | ||
207 | * Derive the 'h' value for key derivation, where | ||
208 | * 'h = H(P ∥ seed) mod n' and 'n' is the size of the cyclic subroup. | ||
209 | * | ||
210 | * @param pub public key for deriviation | ||
211 | * @param seed seed for key the deriviation | ||
212 | * @param seedsize the size of the seed | ||
213 | * @param n The value for the modulus 'n' | ||
214 | * @param[out] phc if not NULL, the output of H() will be written into | ||
215 | * return h_mod_n (allocated by this function) | ||
216 | */ | ||
217 | static gcry_mpi_t | ||
218 | derive_h_mod_n ( | ||
219 | const struct GNUNET_CRYPTO_Edx25519PublicKey *pub, | ||
220 | const void *seed, | ||
221 | size_t seedsize, | ||
222 | const gcry_mpi_t n, | ||
223 | struct GNUNET_HashCode *phc) | ||
224 | { | ||
225 | static const char *const salt = "edx2559-derivation"; | ||
226 | struct GNUNET_HashCode hc; | ||
227 | gcry_mpi_t h; | ||
228 | gcry_mpi_t h_mod_n; | ||
229 | |||
230 | if (NULL == phc) | ||
231 | phc = &hc; | ||
232 | |||
233 | GNUNET_CRYPTO_kdf (phc, sizeof(*phc), | ||
234 | salt, strlen (salt), | ||
235 | pub, sizeof(*pub), | ||
236 | seed, seedsize, | ||
237 | NULL, 0); | ||
238 | |||
239 | /* calculate h_mod_n = h % n */ | ||
240 | GNUNET_CRYPTO_mpi_scan_unsigned (&h, | ||
241 | (unsigned char *) phc, | ||
242 | sizeof(*phc)); | ||
243 | h_mod_n = gcry_mpi_new (256); | ||
244 | gcry_mpi_mod (h_mod_n, h, n); | ||
245 | |||
246 | #ifdef CHECK_RARE_CASES | ||
247 | /** | ||
248 | * Note that the following cases would be problematic: | ||
249 | * 1.) h == 0 mod n | ||
250 | * 2.) h == 1 mod n | ||
251 | * 3.) [h] * P == E | ||
252 | * We assume that the probalities for these cases to occur are neglegible. | ||
253 | */ | ||
254 | GNUNET_assert (! gcry_mpi_cmp_ui (h_mod_n, 0)); | ||
255 | GNUNET_assert (! gcry_mpi_cmp_ui (h_mod_n, 1)); | ||
256 | #endif | ||
257 | |||
258 | gcry_mpi_release(h); | ||
259 | return h_mod_n; | ||
260 | } | ||
261 | |||
262 | |||
263 | void | ||
264 | GNUNET_CRYPTO_edx25519_private_key_derive ( | ||
265 | const struct GNUNET_CRYPTO_Edx25519PrivateKey *priv, | ||
266 | const void *seed, | ||
267 | size_t seedsize, | ||
268 | struct GNUNET_CRYPTO_Edx25519PrivateKey *result) | ||
269 | { | ||
270 | struct GNUNET_CRYPTO_Edx25519PublicKey pub; | ||
271 | struct GNUNET_HashCode hc; | ||
272 | uint8_t a[32]; | ||
273 | gcry_ctx_t ctx; | ||
274 | gcry_mpi_t h_mod_n; | ||
275 | gcry_mpi_t x; | ||
276 | gcry_mpi_t n; | ||
277 | gcry_mpi_t a1; | ||
278 | gcry_mpi_t a2; | ||
279 | gcry_mpi_t ap; // a' | ||
280 | |||
281 | GNUNET_CRYPTO_edx25519_key_get_public (priv, &pub); | ||
282 | |||
283 | /** | ||
284 | * Libsodium does not offer an API with arbitrary arithmetic. | ||
285 | * Hence we have to use libgcrypt here. | ||
286 | */ | ||
287 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, "Ed25519")); | ||
288 | |||
289 | /** | ||
290 | * Get our modulo | ||
291 | */ | ||
292 | n = gcry_mpi_ec_get_mpi ("n", ctx, 1); | ||
293 | GNUNET_assert (NULL != n); | ||
294 | |||
295 | /** | ||
296 | * Get h mod n | ||
297 | */ | ||
298 | h_mod_n = derive_h_mod_n (&pub, | ||
299 | seed, | ||
300 | seedsize, | ||
301 | n, | ||
302 | &hc); | ||
303 | |||
304 | /* Convert priv->a scalar to big endian for libgcrypt */ | ||
305 | for (size_t i = 0; i < 32; i++) | ||
306 | a[i] = priv->a[31 - i]; | ||
307 | |||
308 | /** | ||
309 | * dc now contains the private scalar "a". | ||
310 | * We carefully remove the clamping and derive a'. | ||
311 | * Calculate: | ||
312 | * a1 := a / 8 | ||
313 | * a2 := h * a1 mod n | ||
314 | * a' := a2 * 8 mod n | ||
315 | */ | ||
316 | GNUNET_CRYPTO_mpi_scan_unsigned (&x, a, sizeof(a)); // a | ||
317 | a1 = gcry_mpi_new (256); | ||
318 | gcry_mpi_t eight = gcry_mpi_set_ui (NULL, 8); | ||
319 | gcry_mpi_div (a1, NULL, x, eight, 0); // a1 := a / 8 | ||
320 | a2 = gcry_mpi_new (256); | ||
321 | gcry_mpi_mulm (a2, h_mod_n, a1, n); // a2 := h * a1 mod n | ||
322 | ap = gcry_mpi_new (256); | ||
323 | gcry_mpi_mul (ap, a2, eight); // a' := a2 * 8 | ||
324 | |||
325 | #ifdef CHECK_RARE_CASES | ||
326 | /* The likelihood for a' == 0 or a' == 1 is neglegible */ | ||
327 | GNUNET_assert (! gcry_mpi_cmp_ui (ap, 0)); | ||
328 | GNUNET_assert (! gcry_mpi_cmp_ui (ap, 1)); | ||
329 | #endif | ||
330 | |||
331 | gcry_mpi_release (h_mod_n); | ||
332 | gcry_mpi_release (eight); | ||
333 | gcry_mpi_release (x); | ||
334 | gcry_mpi_release (n); | ||
335 | gcry_mpi_release (a1); | ||
336 | gcry_mpi_release (a2); | ||
337 | gcry_ctx_release (ctx); | ||
338 | GNUNET_CRYPTO_mpi_print_unsigned (a, sizeof(a), ap); | ||
339 | gcry_mpi_release (ap); | ||
340 | |||
341 | /** | ||
342 | * We hash the derived "h" parameter with the other half of the expanded | ||
343 | * private key (that is: priv->b). This ensures that for signature | ||
344 | * generation, the "R" is derived from the same derivation path as "h" and is | ||
345 | * not reused. | ||
346 | */ | ||
347 | { | ||
348 | crypto_hash_sha256_state hs; | ||
349 | crypto_hash_sha256_init (&hs); | ||
350 | crypto_hash_sha256_update (&hs, priv->b, sizeof(priv->b)); | ||
351 | crypto_hash_sha256_update (&hs, (unsigned char*) &hc, sizeof (hc)); | ||
352 | crypto_hash_sha256_final (&hs, result->b); | ||
353 | } | ||
354 | |||
355 | /* Convert to little endian for libsodium */ | ||
356 | for (size_t i = 0; i < 32; i++) | ||
357 | result->a[i] = a[31 - i]; | ||
358 | |||
359 | sodium_memzero (a, sizeof(a)); | ||
360 | } | ||
361 | |||
362 | |||
363 | void | ||
364 | GNUNET_CRYPTO_edx25519_public_key_derive ( | ||
365 | const struct GNUNET_CRYPTO_Edx25519PublicKey *pub, | ||
366 | const void *seed, | ||
367 | size_t seedsize, | ||
368 | struct GNUNET_CRYPTO_Edx25519PublicKey *result) | ||
369 | { | ||
370 | gcry_ctx_t ctx; | ||
371 | gcry_mpi_t q_y; | ||
372 | gcry_mpi_t n; | ||
373 | gcry_mpi_t h_mod_n; | ||
374 | gcry_mpi_point_t q; | ||
375 | gcry_mpi_point_t v; | ||
376 | |||
377 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, "Ed25519")); | ||
378 | |||
379 | /* obtain point 'q' from original public key. The provided 'q' is | ||
380 | compressed thus we first store it in the context and then get it | ||
381 | back as a (decompresssed) point. */ | ||
382 | q_y = gcry_mpi_set_opaque_copy (NULL, | ||
383 | pub->q_y, | ||
384 | 8 * sizeof(pub->q_y)); | ||
385 | GNUNET_assert (NULL != q_y); | ||
386 | GNUNET_assert (0 == gcry_mpi_ec_set_mpi ("q", q_y, ctx)); | ||
387 | gcry_mpi_release (q_y); | ||
388 | q = gcry_mpi_ec_get_point ("q", ctx, 0); | ||
389 | GNUNET_assert (q); | ||
390 | |||
391 | /** | ||
392 | * Get h mod n | ||
393 | */ | ||
394 | n = gcry_mpi_ec_get_mpi ("n", ctx, 1); | ||
395 | GNUNET_assert (NULL != n); | ||
396 | GNUNET_assert (NULL != pub); | ||
397 | h_mod_n = derive_h_mod_n (pub, | ||
398 | seed, | ||
399 | seedsize, | ||
400 | n, | ||
401 | NULL /* We don't need hc here */); | ||
402 | |||
403 | /* calculate v = h_mod_n * q */ | ||
404 | v = gcry_mpi_point_new (0); | ||
405 | gcry_mpi_ec_mul (v, h_mod_n, q, ctx); | ||
406 | gcry_mpi_release (h_mod_n); | ||
407 | gcry_mpi_release (n); | ||
408 | gcry_mpi_point_release (q); | ||
409 | |||
410 | /* convert point 'v' to public key that we return */ | ||
411 | GNUNET_assert (0 == gcry_mpi_ec_set_point ("q", v, ctx)); | ||
412 | gcry_mpi_point_release (v); | ||
413 | q_y = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0); | ||
414 | GNUNET_assert (q_y); | ||
415 | GNUNET_CRYPTO_mpi_print_unsigned (result->q_y, sizeof(result->q_y), q_y); | ||
416 | gcry_mpi_release (q_y); | ||
417 | gcry_ctx_release (ctx); | ||
418 | } | ||
diff --git a/src/util/crypto_hkdf.c b/src/util/crypto_hkdf.c index 4e4496819..838e37d8d 100644 --- a/src/util/crypto_hkdf.c +++ b/src/util/crypto_hkdf.c | |||
@@ -74,16 +74,21 @@ | |||
74 | * @return HMAC, freed by caller via gcry_md_close/_reset | 74 | * @return HMAC, freed by caller via gcry_md_close/_reset |
75 | */ | 75 | */ |
76 | static const void * | 76 | static const void * |
77 | doHMAC (gcry_md_hd_t mac, const void *key, size_t key_len, const void *buf, | 77 | doHMAC (gcry_md_hd_t mac, |
78 | const void *key, | ||
79 | size_t key_len, | ||
80 | const void *buf, | ||
78 | size_t buf_len) | 81 | size_t buf_len) |
79 | { | 82 | { |
80 | if (GPG_ERR_NO_ERROR != gcry_md_setkey (mac, key, key_len)) | 83 | if (GPG_ERR_NO_ERROR != |
84 | gcry_md_setkey (mac, key, key_len)) | ||
81 | { | 85 | { |
82 | GNUNET_break (0); | 86 | GNUNET_break (0); |
83 | return NULL; | 87 | return NULL; |
84 | } | 88 | } |
85 | gcry_md_write (mac, buf, buf_len); | 89 | gcry_md_write (mac, |
86 | 90 | buf, | |
91 | buf_len); | ||
87 | return (const void *) gcry_md_read (mac, 0); | 92 | return (const void *) gcry_md_read (mac, 0); |
88 | } | 93 | } |
89 | 94 | ||
@@ -98,9 +103,13 @@ doHMAC (gcry_md_hd_t mac, const void *key, size_t key_len, const void *buf, | |||
98 | * @param prk result buffer (allocated by caller; at least gcry_md_dlen() bytes) | 103 | * @param prk result buffer (allocated by caller; at least gcry_md_dlen() bytes) |
99 | * @return #GNUNET_YES on success | 104 | * @return #GNUNET_YES on success |
100 | */ | 105 | */ |
101 | static int | 106 | static enum GNUNET_GenericReturnValue |
102 | getPRK (gcry_md_hd_t mac, const void *xts, size_t xts_len, const void *skm, | 107 | getPRK (gcry_md_hd_t mac, |
103 | size_t skm_len, void *prk) | 108 | const void *xts, |
109 | size_t xts_len, | ||
110 | const void *skm, | ||
111 | size_t skm_len, | ||
112 | void *prk) | ||
104 | { | 113 | { |
105 | const void *ret; | 114 | const void *ret; |
106 | size_t dlen; | 115 | size_t dlen; |
@@ -114,9 +123,10 @@ getPRK (gcry_md_hd_t mac, const void *xts, size_t xts_len, const void *skm, | |||
114 | * salt - optional salt value (a non-secret random value); | 123 | * salt - optional salt value (a non-secret random value); |
115 | * if not provided, it is set to a string of HashLen zeros. */ | 124 | * if not provided, it is set to a string of HashLen zeros. */ |
116 | 125 | ||
117 | if (xts_len == 0) | 126 | if (0 == xts_len) |
118 | { | 127 | { |
119 | char zero_salt[dlen]; | 128 | char zero_salt[dlen]; |
129 | |||
120 | memset (zero_salt, 0, dlen); | 130 | memset (zero_salt, 0, dlen); |
121 | ret = doHMAC (mac, zero_salt, dlen, skm, skm_len); | 131 | ret = doHMAC (mac, zero_salt, dlen, skm, skm_len); |
122 | } | 132 | } |
@@ -124,22 +134,23 @@ getPRK (gcry_md_hd_t mac, const void *xts, size_t xts_len, const void *skm, | |||
124 | { | 134 | { |
125 | ret = doHMAC (mac, xts, xts_len, skm, skm_len); | 135 | ret = doHMAC (mac, xts, xts_len, skm, skm_len); |
126 | } | 136 | } |
127 | if (ret == NULL) | 137 | if (NULL == ret) |
128 | return GNUNET_SYSERR; | 138 | return GNUNET_SYSERR; |
129 | GNUNET_memcpy (prk, ret, dlen); | 139 | GNUNET_memcpy (prk, |
130 | 140 | ret, | |
141 | dlen); | ||
131 | return GNUNET_YES; | 142 | return GNUNET_YES; |
132 | } | 143 | } |
133 | 144 | ||
134 | 145 | ||
135 | #if DEBUG_HKDF | 146 | #if DEBUG_HKDF |
136 | static void | 147 | static void |
137 | dump (const char *src, const void *p, unsigned int l) | 148 | dump (const char *src, |
149 | const void *p, | ||
150 | unsigned int l) | ||
138 | { | 151 | { |
139 | unsigned int i; | ||
140 | |||
141 | printf ("\n%s: ", src); | 152 | printf ("\n%s: ", src); |
142 | for (i = 0; i < l; i++) | 153 | for (unsigned int i = 0; i < l; i++) |
143 | { | 154 | { |
144 | printf ("%2x", (int) ((const unsigned char *) p)[i]); | 155 | printf ("%2x", (int) ((const unsigned char *) p)[i]); |
145 | } | 156 | } |
@@ -150,23 +161,16 @@ dump (const char *src, const void *p, unsigned int l) | |||
150 | #endif | 161 | #endif |
151 | 162 | ||
152 | 163 | ||
153 | /** | 164 | enum GNUNET_GenericReturnValue |
154 | * @brief Derive key | 165 | GNUNET_CRYPTO_hkdf_v (void *result, |
155 | * @param result buffer for the derived key, allocated by caller | 166 | size_t out_len, |
156 | * @param out_len desired length of the derived key | 167 | int xtr_algo, |
157 | * @param xtr_algo hash algorithm for the extraction phase, GCRY_MD_... | 168 | int prf_algo, |
158 | * @param prf_algo hash algorithm for the expansion phase, GCRY_MD_... | 169 | const void *xts, |
159 | * @param xts salt | 170 | size_t xts_len, |
160 | * @param xts_len length of @a xts | 171 | const void *skm, |
161 | * @param skm source key material | 172 | size_t skm_len, |
162 | * @param skm_len length of @a skm | 173 | va_list argp) |
163 | * @param argp va_list of void * & size_t pairs for context chunks | ||
164 | * @return #GNUNET_YES on success | ||
165 | */ | ||
166 | int | ||
167 | GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo, | ||
168 | const void *xts, size_t xts_len, const void *skm, | ||
169 | size_t skm_len, va_list argp) | ||
170 | { | 174 | { |
171 | gcry_md_hd_t xtr; | 175 | gcry_md_hd_t xtr; |
172 | gcry_md_hd_t prf; | 176 | gcry_md_hd_t prf; |
@@ -186,10 +190,14 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo, | |||
186 | if (0 == k) | 190 | if (0 == k) |
187 | return GNUNET_SYSERR; | 191 | return GNUNET_SYSERR; |
188 | if (GPG_ERR_NO_ERROR != | 192 | if (GPG_ERR_NO_ERROR != |
189 | gcry_md_open (&xtr, xtr_algo, GCRY_MD_FLAG_HMAC)) | 193 | gcry_md_open (&xtr, |
194 | xtr_algo, | ||
195 | GCRY_MD_FLAG_HMAC)) | ||
190 | return GNUNET_SYSERR; | 196 | return GNUNET_SYSERR; |
191 | if (GPG_ERR_NO_ERROR != | 197 | if (GPG_ERR_NO_ERROR != |
192 | gcry_md_open (&prf, prf_algo, GCRY_MD_FLAG_HMAC)) | 198 | gcry_md_open (&prf, |
199 | prf_algo, | ||
200 | GCRY_MD_FLAG_HMAC)) | ||
193 | { | 201 | { |
194 | gcry_md_close (xtr); | 202 | gcry_md_close (xtr); |
195 | return GNUNET_SYSERR; | 203 | return GNUNET_SYSERR; |
@@ -221,7 +229,8 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo, | |||
221 | } | 229 | } |
222 | 230 | ||
223 | memset (result, 0, out_len); | 231 | memset (result, 0, out_len); |
224 | if (getPRK (xtr, xts, xts_len, skm, skm_len, prk) != GNUNET_YES) | 232 | if (GNUNET_YES != |
233 | getPRK (xtr, xts, xts_len, skm, skm_len, prk)) | ||
225 | goto hkdf_error; | 234 | goto hkdf_error; |
226 | #if DEBUG_HKDF | 235 | #if DEBUG_HKDF |
227 | dump ("PRK", prk, xtr_len); | 236 | dump ("PRK", prk, xtr_len); |
@@ -276,7 +285,7 @@ GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo, | |||
276 | dump ("K(i+1)", plain, plain_len); | 285 | dump ("K(i+1)", plain, plain_len); |
277 | #endif | 286 | #endif |
278 | hc = doHMAC (prf, prk, xtr_len, plain, plain_len); | 287 | hc = doHMAC (prf, prk, xtr_len, plain, plain_len); |
279 | if (hc == NULL) | 288 | if (NULL == hc) |
280 | { | 289 | { |
281 | GNUNET_free (plain); | 290 | GNUNET_free (plain); |
282 | goto hkdf_error; | 291 | goto hkdf_error; |
@@ -327,32 +336,31 @@ hkdf_ok: | |||
327 | } | 336 | } |
328 | 337 | ||
329 | 338 | ||
330 | /** | 339 | enum GNUNET_GenericReturnValue |
331 | * @brief Derive key | 340 | GNUNET_CRYPTO_hkdf (void *result, |
332 | * @param result buffer for the derived key, allocated by caller | 341 | size_t out_len, |
333 | * @param out_len desired length of the derived key | 342 | int xtr_algo, |
334 | * @param xtr_algo hash algorithm for the extraction phase, GCRY_MD_... | 343 | int prf_algo, |
335 | * @param prf_algo hash algorithm for the expansion phase, GCRY_MD_... | 344 | const void *xts, |
336 | * @param xts salt | 345 | size_t xts_len, |
337 | * @param xts_len length of @a xts | 346 | const void *skm, |
338 | * @param skm source key material | ||
339 | * @param skm_len length of @a skm | ||
340 | * @return #GNUNET_YES on success | ||
341 | */ | ||
342 | int | ||
343 | GNUNET_CRYPTO_hkdf (void *result, size_t out_len, int xtr_algo, int prf_algo, | ||
344 | const void *xts, size_t xts_len, const void *skm, | ||
345 | size_t skm_len, ...) | 347 | size_t skm_len, ...) |
346 | { | 348 | { |
347 | va_list argp; | 349 | va_list argp; |
348 | int ret; | 350 | enum GNUNET_GenericReturnValue ret; |
349 | 351 | ||
350 | va_start (argp, skm_len); | 352 | va_start (argp, skm_len); |
351 | ret = | 353 | ret = |
352 | GNUNET_CRYPTO_hkdf_v (result, out_len, xtr_algo, prf_algo, xts, xts_len, | 354 | GNUNET_CRYPTO_hkdf_v (result, |
353 | skm, skm_len, argp); | 355 | out_len, |
356 | xtr_algo, | ||
357 | prf_algo, | ||
358 | xts, | ||
359 | xts_len, | ||
360 | skm, | ||
361 | skm_len, | ||
362 | argp); | ||
354 | va_end (argp); | 363 | va_end (argp); |
355 | |||
356 | return ret; | 364 | return ret; |
357 | } | 365 | } |
358 | 366 | ||
diff --git a/src/util/crypto_kdf.c b/src/util/crypto_kdf.c index 0dc734549..f577e0f7a 100644 --- a/src/util/crypto_kdf.c +++ b/src/util/crypto_kdf.c | |||
@@ -32,18 +32,8 @@ | |||
32 | 32 | ||
33 | #define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-kdf", __VA_ARGS__) | 33 | #define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-kdf", __VA_ARGS__) |
34 | 34 | ||
35 | /** | 35 | |
36 | * @brief Derive key | 36 | enum GNUNET_GenericReturnValue |
37 | * @param result buffer for the derived key, allocated by caller | ||
38 | * @param out_len desired length of the derived key | ||
39 | * @param xts salt | ||
40 | * @param xts_len length of @a xts | ||
41 | * @param skm source key material | ||
42 | * @param skm_len length of @a skm | ||
43 | * @param argp va_list of void * & size_t pairs for context chunks | ||
44 | * @return #GNUNET_YES on success | ||
45 | */ | ||
46 | int | ||
47 | GNUNET_CRYPTO_kdf_v (void *result, | 37 | GNUNET_CRYPTO_kdf_v (void *result, |
48 | size_t out_len, | 38 | size_t out_len, |
49 | const void *xts, | 39 | const void *xts, |
@@ -62,7 +52,7 @@ GNUNET_CRYPTO_kdf_v (void *result, | |||
62 | * hash function." | 52 | * hash function." |
63 | * | 53 | * |
64 | * http://eprint.iacr.org/2010/264 | 54 | * http://eprint.iacr.org/2010/264 |
65 | */// | 55 | */ |
66 | return GNUNET_CRYPTO_hkdf_v (result, | 56 | return GNUNET_CRYPTO_hkdf_v (result, |
67 | out_len, | 57 | out_len, |
68 | GCRY_MD_SHA512, | 58 | GCRY_MD_SHA512, |
@@ -75,18 +65,7 @@ GNUNET_CRYPTO_kdf_v (void *result, | |||
75 | } | 65 | } |
76 | 66 | ||
77 | 67 | ||
78 | /** | 68 | enum GNUNET_GenericReturnValue |
79 | * @brief Derive key | ||
80 | * @param result buffer for the derived key, allocated by caller | ||
81 | * @param out_len desired length of the derived key | ||
82 | * @param xts salt | ||
83 | * @param xts_len length of @a xts | ||
84 | * @param skm source key material | ||
85 | * @param skm_len length of @a skm | ||
86 | * @param ... void * & size_t pairs for context chunks | ||
87 | * @return #GNUNET_YES on success | ||
88 | */ | ||
89 | int | ||
90 | GNUNET_CRYPTO_kdf (void *result, | 69 | GNUNET_CRYPTO_kdf (void *result, |
91 | size_t out_len, | 70 | size_t out_len, |
92 | const void *xts, | 71 | const void *xts, |
@@ -111,18 +90,6 @@ GNUNET_CRYPTO_kdf (void *result, | |||
111 | } | 90 | } |
112 | 91 | ||
113 | 92 | ||
114 | /** | ||
115 | * Deterministically generate a pseudo-random number uniformly from the | ||
116 | * integers modulo a libgcrypt mpi. | ||
117 | * | ||
118 | * @param[out] r MPI value set to the FDH | ||
119 | * @param n MPI to work modulo | ||
120 | * @param xts salt | ||
121 | * @param xts_len length of @a xts | ||
122 | * @param skm source key material | ||
123 | * @param skm_len length of @a skm | ||
124 | * @param ctx context string | ||
125 | */ | ||
126 | void | 93 | void |
127 | GNUNET_CRYPTO_kdf_mod_mpi (gcry_mpi_t *r, | 94 | GNUNET_CRYPTO_kdf_mod_mpi (gcry_mpi_t *r, |
128 | gcry_mpi_t n, | 95 | gcry_mpi_t n, |
@@ -137,32 +104,34 @@ GNUNET_CRYPTO_kdf_mod_mpi (gcry_mpi_t *r, | |||
137 | 104 | ||
138 | nbits = gcry_mpi_get_nbits (n); | 105 | nbits = gcry_mpi_get_nbits (n); |
139 | /* GNUNET_assert (nbits > 512); */ | 106 | /* GNUNET_assert (nbits > 512); */ |
140 | |||
141 | ctr = 0; | 107 | ctr = 0; |
142 | while (1) | 108 | while (1) |
143 | { | 109 | { |
144 | /* Ain't clear if n is always divisible by 8 */ | 110 | /* Ain't clear if n is always divisible by 8 */ |
145 | uint8_t buf[ (nbits - 1) / 8 + 1 ]; | 111 | size_t bsize = (nbits - 1) / 8 + 1; |
112 | uint8_t buf[bsize]; | ||
146 | uint16_t ctr_nbo = htons (ctr); | 113 | uint16_t ctr_nbo = htons (ctr); |
147 | 114 | ||
148 | rc = GNUNET_CRYPTO_kdf (buf, | 115 | rc = GNUNET_CRYPTO_kdf (buf, |
149 | sizeof(buf), | 116 | bsize, |
150 | xts, xts_len, | 117 | xts, xts_len, |
151 | skm, skm_len, | 118 | skm, skm_len, |
152 | ctx, strlen (ctx), | 119 | ctx, strlen (ctx), |
153 | &ctr_nbo, sizeof(ctr_nbo), | 120 | &ctr_nbo, sizeof(ctr_nbo), |
154 | NULL, 0); | 121 | NULL, 0); |
155 | GNUNET_assert (GNUNET_YES == rc); | 122 | GNUNET_assert (GNUNET_YES == rc); |
156 | |||
157 | rc = gcry_mpi_scan (r, | 123 | rc = gcry_mpi_scan (r, |
158 | GCRYMPI_FMT_USG, | 124 | GCRYMPI_FMT_USG, |
159 | (const unsigned char *) buf, | 125 | (const unsigned char *) buf, |
160 | sizeof(buf), | 126 | bsize, |
161 | &rsize); | 127 | &rsize); |
162 | GNUNET_assert (0 == rc); /* Allocation error? */ | 128 | GNUNET_assert (GPG_ERR_NO_ERROR == rc); /* Allocation error? */ |
163 | 129 | GNUNET_assert (rsize == bsize); | |
164 | gcry_mpi_clear_highbit (*r, nbits); | 130 | gcry_mpi_clear_highbit (*r, |
165 | GNUNET_assert (0 == gcry_mpi_test_bit (*r, nbits)); | 131 | nbits); |
132 | GNUNET_assert (0 == | ||
133 | gcry_mpi_test_bit (*r, | ||
134 | nbits)); | ||
166 | ++ctr; | 135 | ++ctr; |
167 | /* We reject this FDH if either *r > n and retry with another ctr */ | 136 | /* We reject this FDH if either *r > n and retry with another ctr */ |
168 | if (0 > gcry_mpi_cmp (*r, n)) | 137 | if (0 > gcry_mpi_cmp (*r, n)) |
diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c index 43e6eedac..4b8e5a5ce 100644 --- a/src/util/crypto_rsa.c +++ b/src/util/crypto_rsa.c | |||
@@ -497,7 +497,8 @@ GNUNET_CRYPTO_rsa_public_key_decode (const char *buf, | |||
497 | * @return True if gcd(r,n) = 1, False means RSA key is malicious | 497 | * @return True if gcd(r,n) = 1, False means RSA key is malicious |
498 | */ | 498 | */ |
499 | static int | 499 | static int |
500 | rsa_gcd_validate (gcry_mpi_t r, gcry_mpi_t n) | 500 | rsa_gcd_validate (gcry_mpi_t r, |
501 | gcry_mpi_t n) | ||
501 | { | 502 | { |
502 | gcry_mpi_t g; | 503 | gcry_mpi_t g; |
503 | int t; | 504 | int t; |
@@ -520,29 +521,34 @@ static struct RsaBlindingKey * | |||
520 | rsa_blinding_key_derive (const struct GNUNET_CRYPTO_RsaPublicKey *pkey, | 521 | rsa_blinding_key_derive (const struct GNUNET_CRYPTO_RsaPublicKey *pkey, |
521 | const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks) | 522 | const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks) |
522 | { | 523 | { |
523 | char *xts = "Blinding KDF extractor HMAC key"; /* Trusts bks' randomness more */ | 524 | const char *xts = "Blinding KDF extractor HMAC key"; /* Trusts bks' randomness more */ |
524 | struct RsaBlindingKey *blind; | 525 | struct RsaBlindingKey *blind; |
525 | gcry_mpi_t n; | 526 | gcry_mpi_t n; |
526 | 527 | ||
527 | blind = GNUNET_new (struct RsaBlindingKey); | 528 | blind = GNUNET_new (struct RsaBlindingKey); |
528 | GNUNET_assert (NULL != blind); | ||
529 | 529 | ||
530 | /* Extract the composite n from the RSA public key */ | 530 | /* Extract the composite n from the RSA public key */ |
531 | GNUNET_assert (0 == key_from_sexp (&n, pkey->sexp, "rsa", "n")); | 531 | GNUNET_assert (0 == |
532 | key_from_sexp (&n, | ||
533 | pkey->sexp, | ||
534 | "rsa", | ||
535 | "n")); | ||
532 | /* Assert that it at least looks like an RSA key */ | 536 | /* Assert that it at least looks like an RSA key */ |
533 | GNUNET_assert (0 == gcry_mpi_get_flag (n, GCRYMPI_FLAG_OPAQUE)); | 537 | GNUNET_assert (0 == |
534 | 538 | gcry_mpi_get_flag (n, | |
539 | GCRYMPI_FLAG_OPAQUE)); | ||
535 | GNUNET_CRYPTO_kdf_mod_mpi (&blind->r, | 540 | GNUNET_CRYPTO_kdf_mod_mpi (&blind->r, |
536 | n, | 541 | n, |
537 | xts, strlen (xts), | 542 | xts, strlen (xts), |
538 | bks, sizeof(*bks), | 543 | bks, sizeof(*bks), |
539 | "Blinding KDF"); | 544 | "Blinding KDF"); |
540 | if (0 == rsa_gcd_validate (blind->r, n)) | 545 | if (0 == rsa_gcd_validate (blind->r, |
546 | n)) | ||
541 | { | 547 | { |
548 | gcry_mpi_release (blind->r); | ||
542 | GNUNET_free (blind); | 549 | GNUNET_free (blind); |
543 | blind = NULL; | 550 | blind = NULL; |
544 | } | 551 | } |
545 | |||
546 | gcry_mpi_release (n); | 552 | gcry_mpi_release (n); |
547 | return blind; | 553 | return blind; |
548 | } | 554 | } |
@@ -760,8 +766,9 @@ rsa_full_domain_hash (const struct GNUNET_CRYPTO_RsaPublicKey *pkey, | |||
760 | /* We key with the public denomination key as a homage to RSA-PSS by * | 766 | /* We key with the public denomination key as a homage to RSA-PSS by * |
761 | * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree * | 767 | * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree * |
762 | * of the hypothetical polyomial-time attack on RSA-KTI created by a * | 768 | * of the hypothetical polyomial-time attack on RSA-KTI created by a * |
763 | * polynomial-time one-more forgary attack. Yey seeding! */ | 769 | * polynomial-time one-more forgary attack. Yey seeding! */ |
764 | xts_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &xts); | 770 | xts_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, |
771 | &xts); | ||
765 | 772 | ||
766 | GNUNET_CRYPTO_kdf_mod_mpi (&r, | 773 | GNUNET_CRYPTO_kdf_mod_mpi (&r, |
767 | n, | 774 | n, |
@@ -769,7 +776,6 @@ rsa_full_domain_hash (const struct GNUNET_CRYPTO_RsaPublicKey *pkey, | |||
769 | hash, sizeof(*hash), | 776 | hash, sizeof(*hash), |
770 | "RSA-FDA FTpsW!"); | 777 | "RSA-FDA FTpsW!"); |
771 | GNUNET_free (xts); | 778 | GNUNET_free (xts); |
772 | |||
773 | ok = rsa_gcd_validate (r, n); | 779 | ok = rsa_gcd_validate (r, n); |
774 | gcry_mpi_release (n); | 780 | gcry_mpi_release (n); |
775 | if (ok) | 781 | if (ok) |
diff --git a/src/util/test_crypto_eddsa.c b/src/util/test_crypto_eddsa.c index 459619ff2..e9573a307 100644 --- a/src/util/test_crypto_eddsa.c +++ b/src/util/test_crypto_eddsa.c | |||
@@ -130,9 +130,11 @@ testDeriveSignVerify (void) | |||
130 | return GNUNET_SYSERR; | 130 | return GNUNET_SYSERR; |
131 | } | 131 | } |
132 | 132 | ||
133 | GNUNET_CRYPTO_eddsa_sign_with_scalar (&dpriv, | 133 | GNUNET_CRYPTO_eddsa_sign_derived (&key, |
134 | &purp, | 134 | "test-derive", |
135 | &sig); | 135 | "test-CTX", |
136 | &purp, | ||
137 | &sig); | ||
136 | if (GNUNET_SYSERR == | 138 | if (GNUNET_SYSERR == |
137 | GNUNET_CRYPTO_eddsa_verify_ (GNUNET_SIGNATURE_PURPOSE_TEST, | 139 | GNUNET_CRYPTO_eddsa_verify_ (GNUNET_SIGNATURE_PURPOSE_TEST, |
138 | &purp, | 140 | &purp, |
diff --git a/src/util/test_crypto_edx25519.c b/src/util/test_crypto_edx25519.c new file mode 100644 index 000000000..ead6f0bb9 --- /dev/null +++ b/src/util/test_crypto_edx25519.c | |||
@@ -0,0 +1,326 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2022 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | |||
20 | */ | ||
21 | /** | ||
22 | * @file util/test_crypto_edx25519.c | ||
23 | * @brief testcase for ECC public key crypto for edx25519 | ||
24 | * @author Özgür Kesim | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_signatures.h" | ||
29 | #include <gcrypt.h> | ||
30 | |||
31 | #define ITER 25 | ||
32 | |||
33 | #define KEYFILE "/tmp/test-gnunet-crypto-edx25519.key" | ||
34 | |||
35 | #define PERF GNUNET_YES | ||
36 | |||
37 | |||
38 | static struct GNUNET_CRYPTO_Edx25519PrivateKey key; | ||
39 | |||
40 | |||
41 | static int | ||
42 | testSignVerify (void) | ||
43 | { | ||
44 | struct GNUNET_CRYPTO_Edx25519Signature sig; | ||
45 | struct GNUNET_CRYPTO_EccSignaturePurpose purp; | ||
46 | struct GNUNET_CRYPTO_Edx25519PublicKey pkey; | ||
47 | struct GNUNET_TIME_Absolute start; | ||
48 | int ok = GNUNET_OK; | ||
49 | |||
50 | fprintf (stderr, "%s", "W"); | ||
51 | GNUNET_CRYPTO_edx25519_key_get_public (&key, | ||
52 | &pkey); | ||
53 | start = GNUNET_TIME_absolute_get (); | ||
54 | purp.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)); | ||
55 | purp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST); | ||
56 | |||
57 | for (unsigned int i = 0; i < ITER; i++) | ||
58 | { | ||
59 | fprintf (stderr, "%s", "."); fflush (stderr); | ||
60 | if (GNUNET_SYSERR == GNUNET_CRYPTO_edx25519_sign_ (&key, | ||
61 | &purp, | ||
62 | &sig)) | ||
63 | { | ||
64 | fprintf (stderr, | ||
65 | "GNUNET_CRYPTO_edx25519_sign returned SYSERR\n"); | ||
66 | ok = GNUNET_SYSERR; | ||
67 | continue; | ||
68 | } | ||
69 | if (GNUNET_SYSERR == | ||
70 | GNUNET_CRYPTO_edx25519_verify_ (GNUNET_SIGNATURE_PURPOSE_TEST, | ||
71 | &purp, | ||
72 | &sig, | ||
73 | &pkey)) | ||
74 | { | ||
75 | fprintf (stderr, | ||
76 | "GNUNET_CRYPTO_edx25519_verify failed!\n"); | ||
77 | ok = GNUNET_SYSERR; | ||
78 | continue; | ||
79 | } | ||
80 | if (GNUNET_SYSERR != | ||
81 | GNUNET_CRYPTO_edx25519_verify_ ( | ||
82 | GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN, | ||
83 | &purp, | ||
84 | &sig, | ||
85 | &pkey)) | ||
86 | { | ||
87 | fprintf (stderr, | ||
88 | "GNUNET_CRYPTO_edx25519_verify failed to fail!\n"); | ||
89 | ok = GNUNET_SYSERR; | ||
90 | continue; | ||
91 | } | ||
92 | } | ||
93 | fprintf (stderr, "\n"); | ||
94 | printf ("%d EdDSA sign/verify operations %s\n", | ||
95 | ITER, | ||
96 | GNUNET_STRINGS_relative_time_to_string ( | ||
97 | GNUNET_TIME_absolute_get_duration (start), | ||
98 | GNUNET_YES)); | ||
99 | return ok; | ||
100 | } | ||
101 | |||
102 | |||
103 | static int | ||
104 | testDeriveSignVerify (void) | ||
105 | { | ||
106 | struct GNUNET_CRYPTO_EccSignaturePurpose purp; | ||
107 | struct GNUNET_CRYPTO_Edx25519Signature sig; | ||
108 | struct GNUNET_CRYPTO_Edx25519PrivateKey dkey; | ||
109 | struct GNUNET_CRYPTO_Edx25519PublicKey pub; | ||
110 | struct GNUNET_CRYPTO_Edx25519PublicKey dpub; | ||
111 | struct GNUNET_CRYPTO_Edx25519PublicKey dpub2; | ||
112 | |||
113 | GNUNET_CRYPTO_edx25519_key_get_public (&key, &pub); | ||
114 | GNUNET_CRYPTO_edx25519_private_key_derive (&key, | ||
115 | "test-derive", | ||
116 | sizeof("test-derive"), | ||
117 | &dkey); | ||
118 | GNUNET_CRYPTO_edx25519_public_key_derive (&pub, | ||
119 | "test-derive", | ||
120 | sizeof("test-derive"), | ||
121 | &dpub); | ||
122 | GNUNET_CRYPTO_edx25519_key_get_public (&dkey, &dpub2); | ||
123 | |||
124 | if (0 != GNUNET_memcmp (&dpub.q_y, &dpub2.q_y)) | ||
125 | { | ||
126 | fprintf (stderr, "key deriviation failed\n"); | ||
127 | return GNUNET_SYSERR; | ||
128 | } | ||
129 | |||
130 | purp.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)); | ||
131 | purp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST); | ||
132 | |||
133 | GNUNET_CRYPTO_edx25519_sign_ (&dkey, | ||
134 | &purp, | ||
135 | &sig); | ||
136 | |||
137 | if (GNUNET_SYSERR == | ||
138 | GNUNET_CRYPTO_edx25519_verify_ (GNUNET_SIGNATURE_PURPOSE_TEST, | ||
139 | &purp, | ||
140 | &sig, | ||
141 | &dpub)) | ||
142 | { | ||
143 | fprintf (stderr, | ||
144 | "GNUNET_CRYPTO_edx25519_verify failed after derivation!\n"); | ||
145 | return GNUNET_SYSERR; | ||
146 | } | ||
147 | |||
148 | if (GNUNET_SYSERR != | ||
149 | GNUNET_CRYPTO_edx25519_verify_ (GNUNET_SIGNATURE_PURPOSE_TEST, | ||
150 | &purp, | ||
151 | &sig, | ||
152 | &pub)) | ||
153 | { | ||
154 | fprintf (stderr, | ||
155 | "GNUNET_CRYPTO_edx25519_verify failed to fail after derivation!\n"); | ||
156 | return GNUNET_SYSERR; | ||
157 | } | ||
158 | |||
159 | if (GNUNET_SYSERR != | ||
160 | GNUNET_CRYPTO_edx25519_verify_ ( | ||
161 | GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN, | ||
162 | &purp, | ||
163 | &sig, | ||
164 | &dpub)) | ||
165 | { | ||
166 | fprintf (stderr, | ||
167 | "GNUNET_CRYPTO_edx25519_verify failed to fail after derivation!\n"); | ||
168 | return GNUNET_SYSERR; | ||
169 | } | ||
170 | return GNUNET_OK; | ||
171 | } | ||
172 | |||
173 | |||
174 | #if PERF | ||
175 | static int | ||
176 | testSignPerformance () | ||
177 | { | ||
178 | struct GNUNET_CRYPTO_EccSignaturePurpose purp; | ||
179 | struct GNUNET_CRYPTO_Edx25519Signature sig; | ||
180 | struct GNUNET_CRYPTO_Edx25519PublicKey pkey; | ||
181 | struct GNUNET_TIME_Absolute start; | ||
182 | int ok = GNUNET_OK; | ||
183 | |||
184 | purp.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)); | ||
185 | purp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST); | ||
186 | fprintf (stderr, "%s", "W"); | ||
187 | GNUNET_CRYPTO_edx25519_key_get_public (&key, | ||
188 | &pkey); | ||
189 | start = GNUNET_TIME_absolute_get (); | ||
190 | for (unsigned int i = 0; i < ITER; i++) | ||
191 | { | ||
192 | fprintf (stderr, "%s", "."); | ||
193 | fflush (stderr); | ||
194 | if (GNUNET_SYSERR == | ||
195 | GNUNET_CRYPTO_edx25519_sign_ (&key, | ||
196 | &purp, | ||
197 | &sig)) | ||
198 | { | ||
199 | fprintf (stderr, "%s", "GNUNET_CRYPTO_edx25519_sign returned SYSERR\n"); | ||
200 | ok = GNUNET_SYSERR; | ||
201 | continue; | ||
202 | } | ||
203 | } | ||
204 | fprintf (stderr, "\n"); | ||
205 | printf ("%d EdDSA sign operations %s\n", | ||
206 | ITER, | ||
207 | GNUNET_STRINGS_relative_time_to_string ( | ||
208 | GNUNET_TIME_absolute_get_duration (start), | ||
209 | GNUNET_YES)); | ||
210 | return ok; | ||
211 | } | ||
212 | |||
213 | |||
214 | #endif | ||
215 | |||
216 | |||
217 | #if 0 /* not implemented */ | ||
218 | static int | ||
219 | testCreateFromFile (void) | ||
220 | { | ||
221 | struct GNUNET_CRYPTO_Edx25519PublicKey p1; | ||
222 | struct GNUNET_CRYPTO_Edx25519PublicKey p2; | ||
223 | |||
224 | /* do_create == GNUNET_YES and non-existing file MUST return GNUNET_YES */ | ||
225 | GNUNET_assert (0 == unlink (KEYFILE) || ENOENT == errno); | ||
226 | GNUNET_assert (GNUNET_YES == | ||
227 | GNUNET_CRYPTO_edx25519_key_from_file (KEYFILE, | ||
228 | GNUNET_YES, | ||
229 | &key)); | ||
230 | GNUNET_CRYPTO_edx25519_key_get_public (&key, | ||
231 | &p1); | ||
232 | |||
233 | /* do_create == GNUNET_YES and _existing_ file MUST return GNUNET_NO */ | ||
234 | GNUNET_assert (GNUNET_NO == | ||
235 | GNUNET_CRYPTO_edx25519_key_from_file (KEYFILE, | ||
236 | GNUNET_YES, | ||
237 | &key)); | ||
238 | GNUNET_CRYPTO_edx25519_key_get_public (&key, | ||
239 | &p2); | ||
240 | GNUNET_assert (0 == | ||
241 | GNUNET_memcmp (&p1, | ||
242 | &p2)); | ||
243 | |||
244 | /* do_create == GNUNET_NO and non-existing file MUST return GNUNET_SYSERR */ | ||
245 | GNUNET_assert (0 == unlink (KEYFILE)); | ||
246 | GNUNET_assert (GNUNET_SYSERR == | ||
247 | GNUNET_CRYPTO_edx25519_key_from_file (KEYFILE, | ||
248 | GNUNET_NO, | ||
249 | &key)); | ||
250 | return GNUNET_OK; | ||
251 | } | ||
252 | |||
253 | |||
254 | #endif | ||
255 | |||
256 | |||
257 | static void | ||
258 | perf_keygen (void) | ||
259 | { | ||
260 | struct GNUNET_TIME_Absolute start; | ||
261 | struct GNUNET_CRYPTO_Edx25519PrivateKey pk; | ||
262 | |||
263 | fprintf (stderr, "%s", "W"); | ||
264 | start = GNUNET_TIME_absolute_get (); | ||
265 | for (unsigned int i = 0; i < 10; i++) | ||
266 | { | ||
267 | fprintf (stderr, "."); | ||
268 | fflush (stderr); | ||
269 | GNUNET_CRYPTO_edx25519_key_create (&pk); | ||
270 | } | ||
271 | fprintf (stderr, "\n"); | ||
272 | printf ("10 EdDSA keys created in %s\n", | ||
273 | GNUNET_STRINGS_relative_time_to_string ( | ||
274 | GNUNET_TIME_absolute_get_duration (start), GNUNET_YES)); | ||
275 | } | ||
276 | |||
277 | |||
278 | int | ||
279 | main (int argc, char *argv[]) | ||
280 | { | ||
281 | int failure_count = 0; | ||
282 | |||
283 | if (! gcry_check_version ("1.6.0")) | ||
284 | { | ||
285 | fprintf (stderr, | ||
286 | "libgcrypt has not the expected version (version %s is required).\n", | ||
287 | "1.6.0"); | ||
288 | return 0; | ||
289 | } | ||
290 | if (getenv ("GNUNET_GCRYPT_DEBUG")) | ||
291 | gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); | ||
292 | GNUNET_log_setup ("test-crypto-edx25519", | ||
293 | "WARNING", | ||
294 | NULL); | ||
295 | GNUNET_CRYPTO_edx25519_key_create (&key); | ||
296 | if (GNUNET_OK != testDeriveSignVerify ()) | ||
297 | { | ||
298 | failure_count++; | ||
299 | fprintf (stderr, | ||
300 | "\n\n%d TESTS FAILED!\n\n", failure_count); | ||
301 | return -1; | ||
302 | } | ||
303 | #if PERF | ||
304 | if (GNUNET_OK != testSignPerformance ()) | ||
305 | failure_count++; | ||
306 | #endif | ||
307 | if (GNUNET_OK != testSignVerify ()) | ||
308 | failure_count++; | ||
309 | #if 0 /* not implemented */ | ||
310 | if (GNUNET_OK != testCreateFromFile ()) | ||
311 | failure_count++; | ||
312 | #endif | ||
313 | perf_keygen (); | ||
314 | |||
315 | if (0 != failure_count) | ||
316 | { | ||
317 | fprintf (stderr, | ||
318 | "\n\n%d TESTS FAILED!\n\n", | ||
319 | failure_count); | ||
320 | return -1; | ||
321 | } | ||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | |||
326 | /* end of test_crypto_edx25519.c */ | ||
diff --git a/src/util/time.c b/src/util/time.c index 68a6937a0..cf072aebf 100644 --- a/src/util/time.c +++ b/src/util/time.c | |||
@@ -58,6 +58,22 @@ GNUNET_TIME_get_offset () | |||
58 | } | 58 | } |
59 | 59 | ||
60 | 60 | ||
61 | bool | ||
62 | GNUNET_TIME_absolute_approx_eq (struct GNUNET_TIME_Absolute a1, | ||
63 | struct GNUNET_TIME_Absolute a2, | ||
64 | struct GNUNET_TIME_Relative t) | ||
65 | { | ||
66 | struct GNUNET_TIME_Relative delta; | ||
67 | |||
68 | delta = GNUNET_TIME_relative_min ( | ||
69 | GNUNET_TIME_absolute_get_difference (a1, a2), | ||
70 | GNUNET_TIME_absolute_get_difference (a2, a1)); | ||
71 | return GNUNET_TIME_relative_cmp (delta, | ||
72 | <=, | ||
73 | t); | ||
74 | } | ||
75 | |||
76 | |||
61 | struct GNUNET_TIME_Timestamp | 77 | struct GNUNET_TIME_Timestamp |
62 | GNUNET_TIME_absolute_to_timestamp (struct GNUNET_TIME_Absolute at) | 78 | GNUNET_TIME_absolute_to_timestamp (struct GNUNET_TIME_Absolute at) |
63 | { | 79 | { |
@@ -370,6 +386,20 @@ GNUNET_TIME_timestamp_min (struct GNUNET_TIME_Timestamp t1, | |||
370 | } | 386 | } |
371 | 387 | ||
372 | 388 | ||
389 | struct GNUNET_TIME_Absolute | ||
390 | GNUNET_TIME_absolute_round_down (struct GNUNET_TIME_Absolute at, | ||
391 | struct GNUNET_TIME_Relative rt) | ||
392 | { | ||
393 | struct GNUNET_TIME_Absolute ret; | ||
394 | |||
395 | GNUNET_assert (! GNUNET_TIME_relative_is_zero (rt)); | ||
396 | ret.abs_value_us | ||
397 | = at.abs_value_us | ||
398 | - at.abs_value_us % rt.rel_value_us; | ||
399 | return ret; | ||
400 | } | ||
401 | |||
402 | |||
373 | struct GNUNET_TIME_Relative | 403 | struct GNUNET_TIME_Relative |
374 | GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future) | 404 | GNUNET_TIME_absolute_get_remaining (struct GNUNET_TIME_Absolute future) |
375 | { | 405 | { |