[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnunet] 04/20: -conclude hello-uri implementation and test
From: |
gnunet |
Subject: |
[gnunet] 04/20: -conclude hello-uri implementation and test |
Date: |
Sat, 19 Feb 2022 16:20:44 +0100 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository gnunet.
commit af252f5c3d4e62f4db39bbc65f3eea4f853d04bc
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Wed Jan 12 20:30:37 2022 +0100
-conclude hello-uri implementation and test
---
src/hello/.gitignore | 2 +
src/hello/Makefile.am | 7 +
src/hello/hello-uri.c | 459 ++++++++++++++++++++++++++++++++-----
src/hello/test_hello-ng.c | 23 +-
src/hello/test_hello-uri.c | 176 ++++++++++++++
src/include/gnunet_hello_uri_lib.h | 13 +-
src/include/gnunet_strings_lib.h | 2 +-
src/include/gnunet_time_lib.h | 13 +-
src/util/strings.c | 9 +-
src/util/time.c | 7 +
10 files changed, 649 insertions(+), 62 deletions(-)
diff --git a/src/hello/.gitignore b/src/hello/.gitignore
index bb49ceb20..d175d148e 100644
--- a/src/hello/.gitignore
+++ b/src/hello/.gitignore
@@ -1,3 +1,5 @@
gnunet-hello
test_friend_hello
test_hello
+test_hello-uri
+test_hello-ng
diff --git a/src/hello/Makefile.am b/src/hello/Makefile.am
index f97ede97c..08d976260 100644
--- a/src/hello/Makefile.am
+++ b/src/hello/Makefile.am
@@ -25,6 +25,7 @@ noinst_PROGRAMS = \
check_PROGRAMS = \
test_hello \
+ test_hello-uri \
test_friend_hello \
test_hello-ng
@@ -45,6 +46,12 @@ test_hello_ng_LDADD = \
libgnunethello.la \
$(top_builddir)/src/util/libgnunetutil.la
+test_hello_uri_SOURCES = \
+ test_hello-uri.c
+test_hello_uri_LDADD = \
+ libgnunethello.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
test_friend_hello_SOURCES = \
test_friend_hello.c
diff --git a/src/hello/hello-uri.c b/src/hello/hello-uri.c
index 347c4bf0c..49e4f6ed3 100644
--- a/src/hello/hello-uri.c
+++ b/src/hello/hello-uri.c
@@ -22,6 +22,17 @@
* @file hello/hello-uri.c
* @brief helper library for handling URI-based HELLOs
* @author Christian Grothoff
+ *
+ * Note:
+ * - Current API does not support deserializing HELLO of
+ * another peer and then serializing it into another
+ * format (we always require the private key).
+ * Not sure if we need this, but if we do, we need
+ * to extend the builder and the API.
+ * - Current API does not allow overriding the default
+ * HELLO expiration time. We may want to add a function
+ * that does this to create bootstrap HELLOs shipped with
+ * the TGZ.
*/
#include "platform.h"
#include "gnunet_signatures.h"
@@ -29,15 +40,44 @@
#include "gnunet_protocols.h"
#include "gnunet_util_lib.h"
+/**
+ * For how long are HELLO signatures valid?
+ */
+#define HELLO_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply ( \
+ GNUNET_TIME_UNIT_DAYS, 2)
+
+
GNUNET_NETWORK_STRUCT_BEGIN
+/**
+ * Message signed as part of a HELLO block/URL.
+ */
+struct HelloSignaturePurpose
+{
+ /**
+ * Purpose must be #GNUNET_SIGNATURE_PURPOSE_HELLO
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * When does the signature expire?
+ */
+ struct GNUNET_TIME_AbsoluteNBO expiration_time;
+
+ /**
+ * Hash over all addresses.
+ */
+ struct GNUNET_HashCode h_addrs;
+
+};
+
/**
* Binary block we sign when we sign an address.
*/
struct HelloUriMessage
{
/**
- * Purpose must be #GNUNET_MESSAGE_TYPE_HELLO_URI
+ * Type must be #GNUNET_MESSAGE_TYPE_HELLO_URI
*/
struct GNUNET_MessageHeader header;
@@ -51,11 +91,32 @@ struct HelloUriMessage
*/
uint16_t url_counter GNUNET_PACKED;
+ /* followed by a 'block' */
+};
+
+
+/**
+ * Start of a 'block'.
+ */
+struct BlockHeader
+{
/**
* Public key of the peer.
*/
struct GNUNET_PeerIdentity pid;
+
+ /**
+ * Signature over the block, of purpose #GNUNET_SIGNATURE_PURPOSE_HELLO.
+ */
+ struct GNUNET_CRYPTO_EddsaSignature sig;
+
+ /**
+ * When does the HELLO expire?
+ */
+ struct GNUNET_TIME_AbsoluteNBO expiration_time;
+
};
+
GNUNET_NETWORK_STRUCT_END
@@ -114,6 +175,98 @@ struct GNUNET_HELLO_Builder
};
+/**
+ * Compute @a hash over addresses in @a builder.
+ *
+ * @param builder the builder to hash addresses of
+ * @param[out] hash where to write the hash
+ */
+static void
+hash_addresses (const struct GNUNET_HELLO_Builder *builder,
+ struct GNUNET_HashCode *hash)
+{
+ struct GNUNET_HashContext *hc;
+
+ hc = GNUNET_CRYPTO_hash_context_start ();
+ for (struct Address *a = builder->a_head;
+ NULL != a;
+ a = a->next)
+ {
+ GNUNET_CRYPTO_hash_context_read (hc,
+ a->uri,
+ a->uri_len);
+ }
+ GNUNET_CRYPTO_hash_context_finish (hc,
+ hash);
+
+}
+
+
+/**
+ * Create HELLO signature.
+ *
+ * @param builder the builder to use
+ * @param et expiration time to sign
+ * @param priv key to sign with
+ * @param[out] sig where to write the signature
+ */
+static void
+sign_hello (const struct GNUNET_HELLO_Builder *builder,
+ struct GNUNET_TIME_Timestamp et,
+ const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
+ struct GNUNET_CRYPTO_EddsaSignature *sig)
+{
+ struct HelloSignaturePurpose hsp = {
+ .purpose.size = htonl (sizeof (hsp)),
+ .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_HELLO),
+ .expiration_time = GNUNET_TIME_absolute_hton (et.abs_time)
+ };
+
+ hash_addresses (builder,
+ &hsp.h_addrs);
+ GNUNET_CRYPTO_eddsa_sign (priv,
+ &hsp,
+ sig);
+}
+
+
+/**
+ * Verify HELLO signature.
+ *
+ * @param builder the builder to use
+ * @param et expiration time to verify
+ * @param sig signature to verify
+ * @return #GNUNET_OK if everything is ok, #GNUNET_NO if the
+ * HELLO expired, #GNUNET_SYSERR if the signature is wrong
+ */
+static enum GNUNET_GenericReturnValue
+verify_hello (const struct GNUNET_HELLO_Builder *builder,
+ struct GNUNET_TIME_Absolute et,
+ const struct GNUNET_CRYPTO_EddsaSignature *sig)
+{
+ struct HelloSignaturePurpose hsp = {
+ .purpose.size = htonl (sizeof (hsp)),
+ .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_HELLO),
+ .expiration_time = GNUNET_TIME_absolute_hton (et)
+ };
+
+ hash_addresses (builder,
+ &hsp.h_addrs);
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_HELLO,
+ &hsp,
+ sig,
+ &builder->pid.public_key))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_TIME_absolute_is_past (et))
+ return GNUNET_NO;
+ return GNUNET_OK;
+}
+
+
struct GNUNET_HELLO_Builder *
GNUNET_HELLO_builder_new (const struct GNUNET_PeerIdentity *pid)
{
@@ -147,29 +300,45 @@ struct GNUNET_HELLO_Builder *
GNUNET_HELLO_builder_from_msg (const struct GNUNET_MessageHeader *msg)
{
const struct HelloUriMessage *h;
- struct GNUNET_HELLO_Builder *b;
uint16_t size = ntohs (msg->size);
- const char *pos;
if (GNUNET_MESSAGE_TYPE_HELLO_URI != ntohs (msg->type))
{
GNUNET_break (0);
return NULL;
}
- if (sizeof (struct HelloUriMessage) < size)
+ if (sizeof (struct HelloUriMessage) > size)
{
GNUNET_break_op (0);
return NULL;
}
h = (const struct HelloUriMessage *) msg;
- pos = (const char *) &h[1];
size -= sizeof (*h);
- b = GNUNET_HELLO_builder_new (&h->pid);
- for (unsigned int i = 0; i<ntohs (h->url_counter); i++)
+ return GNUNET_HELLO_builder_from_block (&h[1],
+ size);
+}
+
+
+struct GNUNET_HELLO_Builder *
+GNUNET_HELLO_builder_from_block (const void *block,
+ size_t block_size)
+{
+ const struct BlockHeader *bh = block;
+ struct GNUNET_HELLO_Builder *b;
+
+ if (block_size < sizeof (*bh))
{
- const char *end = memchr (pos,
+ GNUNET_break_op (0);
+ return NULL;
+ }
+ b = GNUNET_HELLO_builder_new (&bh->pid);
+ block += sizeof (*bh);
+ block_size -= sizeof (*bh);
+ while (block_size > 0)
+ {
+ const void *end = memchr (block,
'\0',
- size);
+ block_size);
if (NULL == end)
{
@@ -179,79 +348,174 @@ GNUNET_HELLO_builder_from_msg (const struct
GNUNET_MessageHeader *msg)
}
if (GNUNET_OK !=
GNUNET_HELLO_builder_add_address (b,
- pos))
+ block))
{
GNUNET_break_op (0);
GNUNET_HELLO_builder_free (b);
return NULL;
}
- end++; /* skip '\0' */
- size -= (end - pos);
- pos = end;
+ end++;
+ block_size -= (end - block);
+ block = end;
}
- if (0 != size)
{
- GNUNET_break_op (0);
- GNUNET_HELLO_builder_free (b);
- return NULL;
+ enum GNUNET_GenericReturnValue ret;
+
+ ret = verify_hello (b,
+ GNUNET_TIME_absolute_ntoh (bh->expiration_time),
+ &bh->sig);
+ GNUNET_break (GNUNET_SYSERR != ret);
+ if (GNUNET_OK != ret)
+ {
+ GNUNET_HELLO_builder_free (b);
+ return NULL;
+ }
}
return b;
}
struct GNUNET_HELLO_Builder *
-GNUNET_HELLO_builder_from_block (const void *block,
- size_t block_size)
+GNUNET_HELLO_builder_from_url (const char *url)
{
- const struct GNUNET_PeerIdentity *pid = block;
+ const char *q;
+ const char *s1;
+ const char *s2;
+ struct GNUNET_PeerIdentity pid;
+ struct GNUNET_CRYPTO_EddsaSignature sig;
+ struct GNUNET_TIME_Absolute et;
+ size_t len;
struct GNUNET_HELLO_Builder *b;
- if (block_size < sizeof (*pid))
+ if (0 != strncasecmp (url,
+ "gnunet://hello/",
+ strlen ("gnunet://hello/")))
+ return NULL;
+ url += strlen ("gnunet://hello/");
+ s1 = strchr (url, '/');
+ if (NULL == s1)
{
GNUNET_break_op (0);
return NULL;
}
- b = GNUNET_HELLO_builder_new (pid);
- block += sizeof (*pid);
- block_size -= sizeof (*pid);
- while (block_size > 0)
+ s2 = strchr (s1 + 1, '/');
+ if (NULL == s1)
{
- const void *end = memchr (block,
- '\0',
- block_size);
+ GNUNET_break_op (0);
+ return NULL;
+ }
+ q = strchr (url, '?');
+ if (NULL == q)
+ q = url + strlen (url);
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (url,
+ s1 - url,
+ &pid,
+ sizeof(pid)))
+ {
+ GNUNET_break_op (0);
+ return NULL;
+ }
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (s1 + 1,
+ s2 - (s1 + 1),
+ &sig,
+ sizeof(sig)))
+ {
+ GNUNET_break_op (0);
+ return NULL;
+ }
+ {
+ unsigned long long sec;
+ char dummy = '?';
+
+ if ( (0 == sscanf (s2 + 1,
+ "%llu%c",
+ &sec,
+ &dummy)) ||
+ ('?' != dummy) )
+ {
+ GNUNET_break_op (0);
+ return NULL;
+ }
+ et = GNUNET_TIME_absolute_from_s (sec);
+ }
- if (NULL == end)
+ b = GNUNET_HELLO_builder_new (&pid);
+ len = strlen (q);
+ while (len > 0)
+ {
+ const char *eq;
+ const char *amp;
+ char *addr = NULL;
+ char *uri;
+
+ /* skip ?/& separator */
+ len--;
+ q++;
+ eq = strchr (q, '=');
+ if ( (eq == q) ||
+ (NULL == eq) )
{
GNUNET_break_op (0);
GNUNET_HELLO_builder_free (b);
return NULL;
}
+ amp = strchr (eq, '&');
+ if (NULL == amp)
+ amp = &q[len];
+ GNUNET_STRINGS_urldecode (eq + 1,
+ amp - (eq + 1),
+ &addr);
+ if ( (NULL == addr) ||
+ (0 == strlen (addr)) )
+ {
+ GNUNET_free (addr);
+ GNUNET_break_op (0);
+ GNUNET_HELLO_builder_free (b);
+ return NULL;
+ }
+ GNUNET_asprintf (&uri,
+ "%.*s://%s",
+ (int) (eq - q),
+ q,
+ addr);
+ GNUNET_free (addr);
if (GNUNET_OK !=
GNUNET_HELLO_builder_add_address (b,
- block))
+ uri))
{
GNUNET_break_op (0);
+ GNUNET_free (uri);
GNUNET_HELLO_builder_free (b);
return NULL;
}
- end++;
- block_size -= (end - block);
- block = end;
+ GNUNET_free (uri);
+ /* move to next URL */
+ len -= (amp - q);
+ q = amp;
}
- return b;
-}
+ {
+ enum GNUNET_GenericReturnValue ret;
-struct GNUNET_HELLO_Builder *
-GNUNET_HELLO_builder_from_url (const char *url)
-{
- // FIXME!
- return NULL;
+ ret = verify_hello (b,
+ et,
+ &sig);
+ GNUNET_break (GNUNET_SYSERR != ret);
+ if (GNUNET_OK != ret)
+ {
+ GNUNET_HELLO_builder_free (b);
+ return NULL;
+ }
+ }
+ return b;
}
struct GNUNET_MQ_Envelope *
-GNUNET_HELLO_builder_to_env (struct GNUNET_HELLO_Builder *builder)
+GNUNET_HELLO_builder_to_env (const struct GNUNET_HELLO_Builder *builder,
+ const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
{
struct GNUNET_MQ_Envelope *env;
struct HelloUriMessage *msg;
@@ -260,14 +524,15 @@ GNUNET_HELLO_builder_to_env (struct GNUNET_HELLO_Builder
*builder)
blen = 0;
GNUNET_assert (GNUNET_NO ==
GNUNET_HELLO_builder_to_block (builder,
+ priv,
NULL,
&blen));
env = GNUNET_MQ_msg_extra (msg,
blen,
GNUNET_MESSAGE_TYPE_HELLO_URI);
- msg->pid = builder->pid;
GNUNET_assert (GNUNET_OK ==
GNUNET_HELLO_builder_to_block (builder,
+ priv,
&msg[1],
&blen));
return env;
@@ -275,20 +540,80 @@ GNUNET_HELLO_builder_to_env (struct GNUNET_HELLO_Builder
*builder)
char *
-GNUNET_HELLO_builder_to_url (struct GNUNET_HELLO_Builder *builder)
+GNUNET_HELLO_builder_to_url (const struct GNUNET_HELLO_Builder *builder,
+ const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
{
- // FIXME!
- return NULL;
+ struct GNUNET_CRYPTO_EddsaSignature sig;
+ struct GNUNET_TIME_Timestamp et;
+ char *result;
+ char *pids;
+ char *sigs;
+ const char *sep = "?";
+
+ et = GNUNET_TIME_relative_to_timestamp (HELLO_ADDRESS_EXPIRATION);
+ sign_hello (builder,
+ et,
+ priv,
+ &sig);
+ pids = GNUNET_STRINGS_data_to_string_alloc (&builder->pid,
+ sizeof (builder->pid));
+ sigs = GNUNET_STRINGS_data_to_string_alloc (&sig,
+ sizeof (sig));
+ GNUNET_asprintf (&result,
+ "gnunet://hello/%s/%s/%llu",
+ pids,
+ sigs,
+ (unsigned long long) GNUNET_TIME_timestamp_to_s (et));
+ GNUNET_free (sigs);
+ GNUNET_free (pids);
+ for (struct Address *a = builder->a_head;
+ NULL != a;
+ a = a->next)
+ {
+ char *ue;
+ char *tmp;
+ int pfx_len;
+ const char *eou;
+
+ eou = strstr (a->uri,
+ "://");
+ if (NULL == eou)
+ {
+ GNUNET_break (0);
+ GNUNET_free (result);
+ return NULL;
+ }
+ pfx_len = eou - a->uri;
+ eou += 3;
+ GNUNET_STRINGS_urlencode (eou,
+ a->uri_len - 4 - pfx_len,
+ &ue);
+ GNUNET_asprintf (&tmp,
+ "%s%s%.*s=%s",
+ result,
+ sep,
+ pfx_len,
+ a->uri,
+ ue);
+ GNUNET_free (ue);
+ GNUNET_free (result);
+ result = tmp;
+ sep = "&";
+ }
+ return result;
}
enum GNUNET_GenericReturnValue
-GNUNET_HELLO_builder_to_block (struct GNUNET_HELLO_Builder *builder,
+GNUNET_HELLO_builder_to_block (const struct GNUNET_HELLO_Builder *builder,
+ const struct GNUNET_CRYPTO_EddsaPrivateKey
*priv,
void *block,
size_t *block_size)
{
- size_t needed = sizeof (struct GNUNET_PeerIdentity);
+ struct BlockHeader bh;
+ size_t needed = sizeof (bh);
char *pos;
+ struct GNUNET_TIME_Timestamp et;
for (struct Address *a = builder->a_head;
NULL != a;
@@ -303,10 +628,17 @@ GNUNET_HELLO_builder_to_block (struct
GNUNET_HELLO_Builder *builder,
*block_size = needed;
return GNUNET_NO;
}
+ bh.pid = builder->pid;
+ et = GNUNET_TIME_relative_to_timestamp (HELLO_ADDRESS_EXPIRATION);
+ bh.expiration_time = GNUNET_TIME_absolute_hton (et.abs_time);
+ sign_hello (builder,
+ et,
+ priv,
+ &bh.sig);
memcpy (block,
- &builder->pid,
- sizeof (builder->pid));
- pos = block + sizeof (builder->pid);
+ &bh,
+ sizeof (bh));
+ pos = block + sizeof (bh);
for (struct Address *a = builder->a_head;
NULL != a;
a = a->next)
@@ -327,7 +659,26 @@ GNUNET_HELLO_builder_add_address (struct
GNUNET_HELLO_Builder *builder,
{
size_t alen = strlen (address) + 1;
struct Address *a;
+ const char *e;
+ if (NULL == (e = strstr (address,
+ "://")))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ if (e == address)
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ for (const char *p = address; p != e; p++)
+ if ( (! isalpha ((unsigned char) *p)) &&
+ ('+' != *p) )
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
/* check for duplicates */
for (a = builder->a_head;
NULL != a;
@@ -341,9 +692,10 @@ GNUNET_HELLO_builder_add_address (struct
GNUNET_HELLO_Builder *builder,
address,
alen);
a->uri = (const char *) &a[1];
- GNUNET_CONTAINER_DLL_insert (builder->a_head,
- builder->a_tail,
- a);
+ GNUNET_CONTAINER_DLL_insert_tail (builder->a_head,
+ builder->a_tail,
+ a);
+ builder->a_length++;
return GNUNET_OK;
}
@@ -366,6 +718,7 @@ GNUNET_HELLO_builder_del_address (struct
GNUNET_HELLO_Builder *builder,
GNUNET_CONTAINER_DLL_remove (builder->a_head,
builder->a_tail,
a);
+ builder->a_length--;
GNUNET_free (a);
return GNUNET_OK;
}
diff --git a/src/hello/test_hello-ng.c b/src/hello/test_hello-ng.c
index e6b1d42a0..4ace9439f 100644
--- a/src/hello/test_hello-ng.c
+++ b/src/hello/test_hello-ng.c
@@ -1,3 +1,22 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2022 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_nt_lib.h"
@@ -23,12 +42,12 @@ main (int argc,
GNUNET_NT_LAN,
t,
&privKey,
- (void**)&res,
+ (void**) &res,
&res_len);
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
"%s\n", res);
GNUNET_assert (NULL !=
- GNUNET_HELLO_extract_address ((void**)res,
+ GNUNET_HELLO_extract_address ((void**) res,
res_len,
&pid,
&nt,
diff --git a/src/hello/test_hello-uri.c b/src/hello/test_hello-uri.c
new file mode 100644
index 000000000..295c08ea3
--- /dev/null
+++ b/src/hello/test_hello-uri.c
@@ -0,0 +1,176 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2022 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/**
+ * @file hello/test_hello-uri.c
+ * @brief test for helper library for handling URI-based HELLOs
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_signatures.h"
+#include "gnunet_hello_uri_lib.h"
+#include "gnunet_util_lib.h"
+
+
+/**
+ * Check for expected URIs.
+ *
+ * @param cls a `unsigned int*`, bitmask set to found URIs
+ * @param uri URI to check for
+ */
+static void
+check_uris (void *cls,
+ const char *uri)
+{
+ unsigned int *found = cls;
+
+ if (0 == strcmp (uri,
+ "test://address"))
+ *found |= 1;
+ else if (0 == strcmp (uri,
+ "test://more"))
+ *found |= 2;
+ else
+ *found = (unsigned int) -1;
+}
+
+
+int
+main (int argc,
+ char *argv[])
+{
+ struct GNUNET_PeerIdentity pid;
+ struct GNUNET_HELLO_Builder *b;
+ struct GNUNET_CRYPTO_EddsaPrivateKey priv;
+
+ GNUNET_log_setup ("test-hell-uri",
+ "WARNING",
+ NULL);
+ GNUNET_CRYPTO_eddsa_key_create (&priv);
+ GNUNET_CRYPTO_eddsa_key_get_public (&priv,
+ &pid.public_key);
+ b = GNUNET_HELLO_builder_new (&pid);
+ GNUNET_assert (GNUNET_SYSERR ==
+ GNUNET_HELLO_builder_add_address (b,
+ "invalid"));
+ GNUNET_assert (GNUNET_SYSERR ==
+ GNUNET_HELLO_builder_add_address (b,
+ "i%v://bla"));
+ GNUNET_assert (GNUNET_SYSERR ==
+ GNUNET_HELLO_builder_add_address (b,
+ "://empty"));
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_HELLO_builder_add_address (b,
+ "test://address"));
+ GNUNET_assert (GNUNET_NO ==
+ GNUNET_HELLO_builder_add_address (b,
+ "test://address"));
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_HELLO_builder_add_address (b,
+ "test://more"));
+ {
+ void *block;
+ size_t block_size = 0;
+ struct GNUNET_HELLO_Builder *b2;
+ struct GNUNET_PeerIdentity p2;
+ unsigned int found;
+
+ GNUNET_assert (GNUNET_NO ==
+ GNUNET_HELLO_builder_to_block (b,
+ &priv,
+ NULL,
+ &block_size));
+ GNUNET_assert (GNUNET_NO ==
+ GNUNET_HELLO_builder_to_block (b,
+ &priv,
+ NULL,
+ &block_size));
+ GNUNET_assert (0 != block_size);
+ block = GNUNET_malloc (block_size);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_HELLO_builder_to_block (b,
+ &priv,
+ block,
+ &block_size));
+ b2 = GNUNET_HELLO_builder_from_block (block,
+ block_size);
+ GNUNET_free (block);
+ GNUNET_assert (NULL != b2);
+ found = 0;
+ GNUNET_HELLO_builder_iterate (b2,
+ &p2,
+ &check_uris,
+ &found);
+ GNUNET_assert (3 == found);
+ GNUNET_assert (0 ==
+ GNUNET_memcmp (&p2,
+ &pid));
+ GNUNET_HELLO_builder_free (b2);
+ }
+
+ {
+ char *url;
+ struct GNUNET_HELLO_Builder *b2;
+ struct GNUNET_PeerIdentity p2;
+ unsigned int found;
+
+ url = GNUNET_HELLO_builder_to_url (b,
+ &priv);
+ b2 = GNUNET_HELLO_builder_from_url (url);
+ GNUNET_free (url);
+ GNUNET_assert (NULL != b2);
+ found = 0;
+ GNUNET_HELLO_builder_iterate (b2,
+ &p2,
+ &check_uris,
+ &found);
+ GNUNET_assert (3 == found);
+ GNUNET_assert (0 ==
+ GNUNET_memcmp (&p2,
+ &pid));
+ GNUNET_HELLO_builder_free (b2);
+ }
+
+ {
+ struct GNUNET_MQ_Envelope *env;
+ struct GNUNET_HELLO_Builder *b2;
+ struct GNUNET_PeerIdentity p2;
+ unsigned int found;
+
+ env = GNUNET_HELLO_builder_to_env (b,
+ &priv);
+ b2 = GNUNET_HELLO_builder_from_msg (GNUNET_MQ_env_get_msg (env));
+ GNUNET_free (env);
+ GNUNET_assert (NULL != b2);
+ found = 0;
+ GNUNET_HELLO_builder_iterate (b2,
+ &p2,
+ &check_uris,
+ &found);
+ GNUNET_assert (3 == found);
+ GNUNET_assert (0 ==
+ GNUNET_memcmp (&p2,
+ &pid));
+ GNUNET_HELLO_builder_free (b2);
+ }
+
+
+ GNUNET_HELLO_builder_free (b);
+ return 0;
+}
diff --git a/src/include/gnunet_hello_uri_lib.h
b/src/include/gnunet_hello_uri_lib.h
index dbf4dc35e..ec9cdfa5e 100644
--- a/src/include/gnunet_hello_uri_lib.h
+++ b/src/include/gnunet_hello_uri_lib.h
@@ -103,26 +103,30 @@ GNUNET_HELLO_builder_from_url (const char *url);
* Generate HELLO message from a @a builder
*
* @param builder builder to serialize
+ * @param priv private key to use to sign the result
* @return HELLO message matching @a builder
*/
struct GNUNET_MQ_Envelope *
-GNUNET_HELLO_builder_to_env (struct GNUNET_HELLO_Builder *builder);
+GNUNET_HELLO_builder_to_env (const struct GNUNET_HELLO_Builder *builder,
+ const struct GNUNET_CRYPTO_EddsaPrivateKey *priv);
/**
* Generate GNUnet HELLO URI from a @a builder
*
* @param builder builder to serialize
+ * @param priv private key to use to sign the result
* @return hello URI
*/
char *
-GNUNET_HELLO_builder_to_url (struct GNUNET_HELLO_Builder *builder);
-
+GNUNET_HELLO_builder_to_url (const struct GNUNET_HELLO_Builder *builder,
+ const struct GNUNET_CRYPTO_EddsaPrivateKey *priv);
/**
* Generate DHT block from a @a builder
*
* @param builder the builder to serialize
+ * @param priv private key to use to sign the result
* @param[out] block where to write the block, NULL to only calculate @a
block_size
* @param[in,out] block_size input is number of bytes available in @a block,
* output is number of bytes needed in @a block
@@ -130,7 +134,8 @@ GNUNET_HELLO_builder_to_url (struct GNUNET_HELLO_Builder
*builder);
* or if @a block was NULL
*/
enum GNUNET_GenericReturnValue
-GNUNET_HELLO_builder_to_block (struct GNUNET_HELLO_Builder *builder,
+GNUNET_HELLO_builder_to_block (const struct GNUNET_HELLO_Builder *builder,
+ const struct GNUNET_CRYPTO_EddsaPrivateKey
*priv,
void *block,
size_t *block_size);
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h
index 09c547b09..bb8577b7a 100644
--- a/src/include/gnunet_strings_lib.h
+++ b/src/include/gnunet_strings_lib.h
@@ -458,7 +458,7 @@ GNUNET_STRINGS_base64url_decode (const char *data,
*
* @param data the data to encode
* @param len the length of the input
- * @param output where to write the output (*output should be NULL,
+ * @param[out] out where to write the output (*output should be NULL,
* is allocated)
* @return the size of the output
*/
diff --git a/src/include/gnunet_time_lib.h b/src/include/gnunet_time_lib.h
index b14439462..96413c3cc 100644
--- a/src/include/gnunet_time_lib.h
+++ b/src/include/gnunet_time_lib.h
@@ -762,10 +762,21 @@ GNUNET_TIME_absolute_from_s (uint64_t s_after_epoch);
*
* @param s_after_epoch seconds after epoch to convert
* @return converted time value
- */struct GNUNET_TIME_Timestamp
+ */
+struct GNUNET_TIME_Timestamp
GNUNET_TIME_timestamp_from_s (uint64_t s_after_epoch);
+/**
+ * Convert timestamp to number of seconds after the UNIX epoch.
+ *
+ * @param ts timestamp to convert
+ * @return converted time value
+ */
+uint64_t
+GNUNET_TIME_timestamp_to_s (struct GNUNET_TIME_Timestamp ts);
+
+
/**
* Convert absolute time from network byte order.
*
diff --git a/src/util/strings.c b/src/util/strings.c
index a77f09022..7e218cc59 100644
--- a/src/util/strings.c
+++ b/src/util/strings.c
@@ -1813,12 +1813,19 @@ GNUNET_STRINGS_urldecode (const char *data,
char *wpos = *out;
size_t resl = 0;
- while ('\0' != *rpos)
+ while ( ('\0' != *rpos) &&
+ (data + len != rpos) )
{
unsigned int num;
switch (*rpos)
{
case '%':
+ if (rpos + 3 > data + len)
+ {
+ GNUNET_break_op (0);
+ GNUNET_free (*out);
+ return 0;
+ }
if (1 != sscanf (rpos + 1, "%2x", &num))
break;
*wpos = (char) ((unsigned char) num);
diff --git a/src/util/time.c b/src/util/time.c
index 83b39b4e8..68a6937a0 100644
--- a/src/util/time.c
+++ b/src/util/time.c
@@ -695,6 +695,13 @@ GNUNET_TIME_timestamp_from_s (uint64_t s_after_epoch)
}
+uint64_t
+GNUNET_TIME_timestamp_to_s (struct GNUNET_TIME_Timestamp ts)
+{
+ return ts.abs_time.abs_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us;
+}
+
+
struct GNUNET_TIME_Absolute
GNUNET_TIME_absolute_ntoh (struct GNUNET_TIME_AbsoluteNBO a)
{
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [gnunet] branch master updated (25ef40ef7 -> d68731944), gnunet, 2022/02/19
- [gnunet] 02/20: -also add serialization from/to block, gnunet, 2022/02/19
- [gnunet] 03/20: incomplete first hack of new hello-uri lib, gnunet, 2022/02/19
- [gnunet] 01/20: first steps towards usable dhtu, gnunet, 2022/02/19
- [gnunet] 04/20: -conclude hello-uri implementation and test,
gnunet <=
- [gnunet] 09/20: -DHT now takes care of queue size limit, gnunet, 2022/02/19
- [gnunet] 07/20: -more work on DHTU integration, gnunet, 2022/02/19
- [gnunet] 08/20: rebase, gnunet, 2022/02/19
- [gnunet] 13/20: -fix port initialization in addr, gnunet, 2022/02/19
- [gnunet] 11/20: -DHT: add gnunet-dht-hello for bootstrapping, gnunet, 2022/02/19
- [gnunet] 16/20: -got basics to work with dhtu and udp+ip underlay, gnunet, 2022/02/19
- [gnunet] 18/20: -fix merge issues, gnunet, 2022/02/19
- [gnunet] 20/20: -fix assertion, fix key initialization, gnunet, 2022/02/19
- [gnunet] 17/20: -try to make static analysis happy, gnunet, 2022/02/19
- [gnunet] 15/20: -adding logging, minor dthu bugfixes, gnunet, 2022/02/19