GNUnet 0.22.2
fs_uri.c File Reference

Parses and produces uri strings. More...

#include "platform.h"
#include "gnunet_fs_service.h"
#include "gnunet_signatures.h"
#include "fs_api.h"
#include <unitypes.h>
#include <unicase.h>
#include <uniconv.h>
#include <unistr.h>
#include <unistdio.h>
Include dependency graph for fs_uri.c:

Go to the source code of this file.

Data Structures

struct  LocUriAssembly
 Structure that defines how the contents of a location URI must be assembled in memory to create or verify the signature of a location URI. More...
 

Macros

#define GNUNET_FS_URI_KSK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_KSK_INFIX
 
#define GNUNET_FS_URI_SKS_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_SKS_INFIX
 
#define GNUNET_FS_URI_CHK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_CHK_INFIX
 
#define GNUNET_FS_URI_LOC_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX
 
#define SIGNATURE_ASCII_LENGTH   103
 
#define TOKENS   "_. /-!?#&+@\"\'\\;:,()[]{}$<>|"
 Where to break up keywords. More...
 

Functions

int GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri, struct GNUNET_HashCode *key)
 Get a unique key from a URI. More...
 
char * GNUNET_FS_uri_ksk_to_string_fancy (const struct GNUNET_FS_Uri *uri)
 Convert keyword URI to a human readable format (i.e. More...
 
static char * percent_decode_keyword (const char *in, char **emsg)
 Given a keyword with %-encoding (and possibly quotes to protect spaces), return a copy of the keyword without %-encoding and without double-quotes (%22). More...
 
static struct GNUNET_FS_Uriuri_ksk_parse (const char *s, char **emsg)
 Parse a KSK URI. More...
 
static struct GNUNET_FS_Uriuri_sks_parse (const char *s, char **emsg)
 Parse an SKS URI. More...
 
static struct GNUNET_FS_Uriuri_chk_parse (const char *s, char **emsg)
 Parse a CHK URI. More...
 
static struct GNUNET_FS_Uriuri_loc_parse (const char *s, char **emsg)
 Parse a LOC URI. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_parse (const char *uri, char **emsg)
 Convert a UTF-8 String to a URI. More...
 
void GNUNET_FS_uri_destroy (struct GNUNET_FS_Uri *uri)
 Free URI. More...
 
unsigned int GNUNET_FS_uri_ksk_get_keyword_count (const struct GNUNET_FS_Uri *uri)
 How many keywords are ANDed in this keyword URI? More...
 
int GNUNET_FS_uri_ksk_get_keywords (const struct GNUNET_FS_Uri *uri, GNUNET_FS_KeywordIterator iterator, void *iterator_cls)
 Iterate over all keywords in this keyword URI. More...
 
void GNUNET_FS_uri_ksk_add_keyword (struct GNUNET_FS_Uri *uri, const char *keyword, int is_mandatory)
 Add the given keyword to the set of keywords represented by the URI. More...
 
void GNUNET_FS_uri_ksk_remove_keyword (struct GNUNET_FS_Uri *uri, const char *keyword)
 Remove the given keyword from the set of keywords represented by the URI. More...
 
int GNUNET_FS_uri_loc_get_peer_identity (const struct GNUNET_FS_Uri *uri, struct GNUNET_PeerIdentity *peer)
 Obtain the identity of the peer offering the data. More...
 
struct GNUNET_TIME_Absolute GNUNET_FS_uri_loc_get_expiration (const struct GNUNET_FS_Uri *uri)
 Obtain the expiration of the LOC URI. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_loc_get_uri (const struct GNUNET_FS_Uri *uri)
 Obtain the URI of the content itself. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *base_uri, const struct GNUNET_CRYPTO_EddsaPrivateKey *sign_key, struct GNUNET_TIME_Absolute expiration_time)
 Construct a location URI (this peer will be used for the location). More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_sks_create (const struct GNUNET_CRYPTO_EcdsaPublicKey *ns, const char *id)
 Create an SKS URI from a namespace ID and an identifier. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_ksk_merge (const struct GNUNET_FS_Uri *u1, const struct GNUNET_FS_Uri *u2)
 Merge the sets of keywords from two KSK URIs. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_dup (const struct GNUNET_FS_Uri *uri)
 Duplicate URI. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_ksk_create (const char *keywords, char **emsg)
 Create an FS URI from a single user-supplied string of keywords. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_ksk_create_from_args (unsigned int argc, const char **argv)
 Create an FS URI from a user-supplied command line of keywords. More...
 
int GNUNET_FS_uri_test_equal (const struct GNUNET_FS_Uri *u1, const struct GNUNET_FS_Uri *u2)
 Test if two URIs are equal. More...
 
int GNUNET_FS_uri_test_sks (const struct GNUNET_FS_Uri *uri)
 Is this a namespace URI? More...
 
int GNUNET_FS_uri_sks_get_namespace (const struct GNUNET_FS_Uri *uri, struct GNUNET_CRYPTO_EcdsaPublicKey *pseudonym)
 Get the ID of a namespace from the given namespace URI. More...
 
char * GNUNET_FS_uri_sks_get_content_id (const struct GNUNET_FS_Uri *uri)
 Get the content identifier of an SKS URI. More...
 
int GNUNET_FS_uri_test_ksk (const struct GNUNET_FS_Uri *uri)
 Is this a keyword URI? More...
 
int GNUNET_FS_uri_test_chk (const struct GNUNET_FS_Uri *uri)
 Is this a file (or directory) URI? More...
 
uint64_t GNUNET_FS_uri_chk_get_file_size (const struct GNUNET_FS_Uri *uri)
 What is the size of the file that this URI refers to? More...
 
const struct GNUNET_HashCodeGNUNET_FS_uri_chk_get_file_hash (const struct GNUNET_FS_Uri *uri)
 What is the hash of the original file's content that this URI refers to? More...
 
int GNUNET_FS_uri_test_loc (const struct GNUNET_FS_Uri *uri)
 Is this a location URI? More...
 
static void insert_non_mandatory_keyword (const char *s, char **array, int index)
 Add a keyword as non-mandatory (with ' '-prefix) to the given keyword list at offset 'index'. More...
 
static int find_duplicate (const char *s, const char **array, int array_length)
 Test if the given keyword s is already present in the given array, ignoring the '+'-mandatory prefix in the array. More...
 
static char * normalize_metadata (enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len)
 FIXME: comment. More...
 
static size_t u8_strcount (const uint8_t *s)
 Counts the number of UTF-8 characters (not bytes) in the string, returns that count. More...
 
static int get_keywords_from_parens (const char *s, char **array, int index)
 Break the filename up by matching [], () and {} pairs to make keywords. More...
 
static int get_keywords_from_tokens (const char *s, char **array, int index)
 Break the filename up by TOKENS to make keywords. More...
 
static int gather_uri_data (void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, const char *data_mime_type, const char *data, size_t data_len)
 Function called on each value in the meta data. More...
 
struct GNUNET_FS_UriGNUNET_FS_uri_ksk_create_from_meta_data (const struct GNUNET_FS_MetaData *md)
 Construct a keyword-URI from meta-data (take all entries in the meta-data and construct one large keyword URI that lists all keywords that can be found in the meta-data). More...
 
static int needs_percent (char c)
 In URI-encoding, does the given character need to be encoded using %-encoding? More...
 
static char * uri_ksk_to_string (const struct GNUNET_FS_Uri *uri)
 Convert a KSK URI to a string. More...
 
static char * uri_sks_to_string (const struct GNUNET_FS_Uri *uri)
 Convert SKS URI to a string. More...
 
static char * uri_chk_to_string (const struct GNUNET_FS_Uri *uri)
 Convert a CHK URI to a string. More...
 
static char * uri_loc_to_string (const struct GNUNET_FS_Uri *uri)
 Convert a LOC URI to a string. More...
 
char * GNUNET_FS_uri_to_string (const struct GNUNET_FS_Uri *uri)
 Convert a URI to a UTF-8 String. More...
 

Detailed Description

Parses and produces uri strings.

Author
Igor Wronsky, Christian Grothoff

GNUnet URIs are of the general form "gnunet://MODULE/IDENTIFIER". The specific structure of "IDENTIFIER" depends on the module and maybe differentiated into additional subcategories if applicable. This module only deals with fs identifiers (MODULE = "fs").

This module only parses URIs for the AFS module. The FS URIs fall into four categories, "chk", "sks", "ksk" and "loc". The first three categories were named in analogy (!) to Freenet, but they do NOT work in exactly the same way. They are very similar from the user's point of view (unique file identifier, subspace, keyword), but the implementation is rather different in pretty much every detail. The concrete URI formats are:

  • First, there are URIs that identify a file. They have the format "gnunet://fs/chk/HEX1.HEX2.SIZE". These URIs can be used to download the file. The description, filename, mime-type and other meta-data is NOT part of the file-URI since a URI uniquely identifies a resource (and the contents of the file would be the same even if it had a different description).

  • The second category identifies entries in a namespace. The format is "gnunet://fs/sks/NAMESPACE/IDENTIFIER" where the namespace should be given in HEX. Applications may allow using a nickname for the namespace if the nickname is not ambiguous. The identifier can be either an ASCII sequence or a HEX-encoding. If the identifier is in ASCII but the format is ambiguous and could denote a HEX-string a "/" is appended to indicate ASCII encoding.

  • The third category identifies ordinary searches. The format is "gnunet://fs/ksk/KEYWORD[+KEYWORD]*". Using the "+" syntax it is possible to encode searches with the boolean "AND" operator. "+" is used since it indicates a commutative 'and' operation and is unlikely to be used in a keyword by itself.

  • The last category identifies a datum on a specific machine. The format is "gnunet://fs/loc/HEX1.HEX2.SIZE.PEER.SIG.EXPTIME". PEER is the BinName of the public key of the peer storing the datum. The signature (SIG) certifies that this peer has this content. HEX1, HEX2 and SIZE correspond to a 'chk' URI.

The encoding for hexadecimal values is defined in the hashing.c module in the gnunetutil library and discussed there.

Definition in file fs_uri.c.

Macro Definition Documentation

◆ GNUNET_FS_URI_KSK_PREFIX

#define GNUNET_FS_URI_KSK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_KSK_INFIX

Definition at line 262 of file fs_uri.c.

◆ GNUNET_FS_URI_SKS_PREFIX

#define GNUNET_FS_URI_SKS_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_SKS_INFIX

Definition at line 356 of file fs_uri.c.

◆ GNUNET_FS_URI_CHK_PREFIX

#define GNUNET_FS_URI_CHK_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_CHK_INFIX

Definition at line 395 of file fs_uri.c.

◆ GNUNET_FS_URI_LOC_PREFIX

#define GNUNET_FS_URI_LOC_PREFIX   GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX

Definition at line 483 of file fs_uri.c.

◆ SIGNATURE_ASCII_LENGTH

#define SIGNATURE_ASCII_LENGTH   103

Definition at line 485 of file fs_uri.c.

◆ TOKENS

#define TOKENS   "_. /-!?#&+@\"\'\\;:,()[]{}$<>|"

Where to break up keywords.

Definition at line 1631 of file fs_uri.c.

Function Documentation

◆ percent_decode_keyword()

static char * percent_decode_keyword ( const char *  in,
char **  emsg 
)
static

Given a keyword with %-encoding (and possibly quotes to protect spaces), return a copy of the keyword without %-encoding and without double-quotes (%22).

Also, add a space at the beginning if there is not a '+'.

Parameters
instring with %-encoding
emsgwhere to store the parser error message (if any)
Returns
decoded string with leading space (or preserved plus)

Definition at line 212 of file fs_uri.c.

213{
214 char *out;
215 char *ret;
216 unsigned int rpos;
217 unsigned int wpos;
218 unsigned int hx;
219
220 out = GNUNET_strdup (in);
221 rpos = 0;
222 wpos = 0;
223 while (out[rpos] != '\0')
224 {
225 if (out[rpos] == '%')
226 {
227 if (1 != sscanf (&out[rpos + 1], "%2X", &hx))
228 {
229 GNUNET_free (out);
230 *emsg = GNUNET_strdup (
231 _ ( /* xgettext:no-c-format */
232 "Malformed KSK URI (`%' must be followed by HEX number)"));
233 return NULL;
234 }
235 rpos += 3;
236 if (hx == '"')
237 continue; /* skip double quote */
238 out[wpos++] = (char) hx;
239 }
240 else
241 {
242 out[wpos++] = out[rpos++];
243 }
244 }
245 out[wpos] = '\0';
246 if (out[0] == '+')
247 {
248 ret = GNUNET_strdup (out);
249 }
250 else
251 {
252 /* need to prefix with space */
253 ret = GNUNET_malloc (strlen (out) + 2);
254 strcpy (ret, " ");
255 strcat (ret, out);
256 }
257 GNUNET_free (out);
258 return ret;
259}
static int ret
Final status code.
Definition: gnunet-arm.c:93
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178

References _, GNUNET_free, GNUNET_malloc, GNUNET_strdup, and ret.

Referenced by uri_ksk_parse().

Here is the caller graph for this function:

◆ uri_ksk_parse()

static struct GNUNET_FS_Uri * uri_ksk_parse ( const char *  s,
char **  emsg 
)
static

Parse a KSK URI.

Parameters
san uri string
emsgwhere to store the parser error message (if any)
Returns
NULL on error, otherwise the KSK URI

Definition at line 272 of file fs_uri.c.

273{
274 struct GNUNET_FS_Uri *ret;
275 char **keywords;
276 unsigned int pos;
277 int max;
278 int iret;
279 int i;
280 size_t slen;
281 char *dup;
282 int saw_quote;
283
284 slen = strlen (s);
285 pos = strlen (GNUNET_FS_URI_KSK_PREFIX);
286 if ((slen <= pos) || (0 != strncmp (s, GNUNET_FS_URI_KSK_PREFIX, pos)))
287 return NULL; /* not KSK URI */
288 if ((s[slen - 1] == '+') || (s[pos] == '+'))
289 {
290 *emsg =
291 GNUNET_strdup (_ ("Malformed KSK URI (must not begin or end with `+')"));
292 return NULL;
293 }
294 max = 1;
295 saw_quote = 0;
296 for (i = pos; i < slen; i++)
297 {
298 if ((s[i] == '%') && (&s[i] == strstr (&s[i], "%22")))
299 {
300 saw_quote = (saw_quote + 1) % 2;
301 i += 3;
302 continue;
303 }
304 if ((s[i] == '+') && (saw_quote == 0))
305 {
306 max++;
307 if (s[i - 1] == '+')
308 {
309 *emsg = GNUNET_strdup (_ ("Malformed KSK URI (`++' not allowed)"));
310 return NULL;
311 }
312 }
313 }
314 if (saw_quote == 1)
315 {
316 *emsg = GNUNET_strdup (_ ("Malformed KSK URI (quotes not balanced)"));
317 return NULL;
318 }
319 iret = max;
320 dup = GNUNET_strdup (s);
321 keywords = GNUNET_new_array (max, char *);
322 for (i = slen - 1; i >= (int) pos; i--)
323 {
324 if ((s[i] == '%') && (&s[i] == strstr (&s[i], "%22")))
325 {
326 saw_quote = (saw_quote + 1) % 2;
327 continue;
328 }
329 if ((dup[i] == '+') && (saw_quote == 0))
330 {
331 keywords[--max] = percent_decode_keyword (&dup[i + 1], emsg);
332 if (NULL == keywords[max])
333 goto CLEANUP;
334 dup[i] = '\0';
335 }
336 }
337 keywords[--max] = percent_decode_keyword (&dup[pos], emsg);
338 if (NULL == keywords[max])
339 goto CLEANUP;
340 GNUNET_assert (0 == max);
341 GNUNET_free (dup);
342 ret = GNUNET_new (struct GNUNET_FS_Uri);
343 ret->type = GNUNET_FS_URI_KSK;
344 ret->data.ksk.keywordCount = iret;
345 ret->data.ksk.keywords = keywords;
346 return ret;
347 CLEANUP:
348 for (i = 0; i < max; i++)
351 GNUNET_free (dup);
352 return NULL;
353}
@ GNUNET_FS_URI_KSK
Keyword search key (query with keywords).
Definition: fs_api.h:154
static char * percent_decode_keyword(const char *in, char **emsg)
Given a keyword with %-encoding (and possibly quotes to protect spaces), return a copy of the keyword...
Definition: fs_uri.c:212
#define GNUNET_FS_URI_KSK_PREFIX
Definition: fs_uri.c:262
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
#define max(x, y)
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:167
char ** keywords
Keywords start with a '+' if they are mandatory (in which case the '+' is NOT part of the keyword) an...
Definition: fs_api.h:186

References _, GNUNET_assert, GNUNET_free, GNUNET_FS_URI_KSK, GNUNET_FS_URI_KSK_PREFIX, GNUNET_new, GNUNET_new_array, GNUNET_strdup, consensus-simulation::int, GNUNET_FS_Uri::keywords, max, percent_decode_keyword(), and ret.

Referenced by GNUNET_FS_uri_parse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_sks_parse()

static struct GNUNET_FS_Uri * uri_sks_parse ( const char *  s,
char **  emsg 
)
static

Parse an SKS URI.

Parameters
san uri string
emsgwhere to store the parser error message (if any)
Returns
NULL on error, SKS URI otherwise

Definition at line 366 of file fs_uri.c.

367{
368 struct GNUNET_FS_Uri *ret;
370 size_t pos;
371 char *end;
372
373 pos = strlen (GNUNET_FS_URI_SKS_PREFIX);
374 if ((strlen (s) <= pos) || (0 != strncmp (s, GNUNET_FS_URI_SKS_PREFIX, pos)))
375 return NULL; /* not an SKS URI */
376 end = strchr (&s[pos], '/');
377 if ((NULL == end) ||
379 end - &s[pos],
380 &ns,
381 sizeof(ns))))
382 {
383 *emsg = GNUNET_strdup (_ ("Malformed SKS URI (wrong syntax)"));
384 return NULL; /* malformed */
385 }
386 end++; /* skip over '/' */
387 ret = GNUNET_new (struct GNUNET_FS_Uri);
388 ret->type = GNUNET_FS_URI_SKS;
389 ret->data.sks.ns = ns;
390 ret->data.sks.identifier = GNUNET_strdup (end);
391 return ret;
392}
@ GNUNET_FS_URI_SKS
Signed key space (file in namespace).
Definition: fs_api.h:149
#define GNUNET_FS_URI_SKS_PREFIX
Definition: fs_uri.c:356
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:33
static struct GNUNET_NAMECACHE_Handle * ns
Handle to the namecache.
@ GNUNET_OK
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:812
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...

References _, end, GNUNET_FS_URI_SKS, GNUNET_FS_URI_SKS_PREFIX, GNUNET_new, GNUNET_OK, GNUNET_strdup, GNUNET_STRINGS_string_to_data(), ns, and ret.

Referenced by GNUNET_FS_uri_parse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_chk_parse()

static struct GNUNET_FS_Uri * uri_chk_parse ( const char *  s,
char **  emsg 
)
static

Parse a CHK URI.

Parameters
san uri string
emsgwhere to store the parser error message (if any)
Returns
NULL on error, CHK URI otherwise

Definition at line 406 of file fs_uri.c.

407{
408 struct GNUNET_FS_Uri *ret;
409 struct FileIdentifier fi;
410 unsigned int pos;
411 unsigned long long flen;
412 size_t slen;
413 char h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
414 char h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
415
416 slen = strlen (s);
417 pos = strlen (GNUNET_FS_URI_CHK_PREFIX);
418 if ((slen < pos + 2 * sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) ||
419 (0 != strncmp (s, GNUNET_FS_URI_CHK_PREFIX, pos)))
420 return NULL; /* not a CHK URI */
421 if ((s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '.') ||
422 (s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2 - 1] != '.'))
423 {
424 *emsg = GNUNET_strdup (_ ("Malformed CHK URI (wrong syntax)"));
425 return NULL;
426 }
427 GNUNET_memcpy (h1, &s[pos], sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
428 h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
429 GNUNET_memcpy (h2,
430 &s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)],
431 sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
432 h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
433
434 if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h1, &fi.chk.key)) ||
435 (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h2, &fi.chk.query)) ||
436 (1 !=
437 sscanf (&s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2],
438 "%llu",
439 &flen)))
440 {
441 *emsg = GNUNET_strdup (_ ("Malformed CHK URI (failed to decode CHK)"));
442 return NULL;
443 }
444 fi.file_length = GNUNET_htonll (flen);
445 ret = GNUNET_new (struct GNUNET_FS_Uri);
446 ret->type = GNUNET_FS_URI_CHK;
447 ret->data.chk = fi;
448 return ret;
449}
@ GNUNET_FS_URI_CHK
Content-hash-key (simple file).
Definition: fs_api.h:144
#define GNUNET_FS_URI_CHK_PREFIX
Definition: fs_uri.c:395
#define GNUNET_CRYPTO_hash_from_string(enc, result)
Convert ASCII encoding back to struct GNUNET_HashCode
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:37
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
complete information needed to download a file.
Definition: fs_api.h:95
0-terminated ASCII encoding of a struct GNUNET_HashCode.

References _, FileIdentifier::chk, FileIdentifier::file_length, GNUNET_CRYPTO_hash_from_string, GNUNET_FS_URI_CHK, GNUNET_FS_URI_CHK_PREFIX, GNUNET_htonll(), GNUNET_memcpy, GNUNET_new, GNUNET_OK, GNUNET_strdup, ContentHashKey::key, ContentHashKey::query, and ret.

Referenced by GNUNET_FS_uri_parse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_loc_parse()

static struct GNUNET_FS_Uri * uri_loc_parse ( const char *  s,
char **  emsg 
)
static

Parse a LOC URI.

Also verifies validity of the location URI.

Parameters
san uri string
emsgwhere to store the parser error message (if any)
Returns
NULL on error, valid LOC URI otherwise

Definition at line 496 of file fs_uri.c.

497{
498 struct GNUNET_FS_Uri *uri;
499 char h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
500 char h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)];
501 unsigned int pos;
502 unsigned int npos;
503 unsigned long long exptime;
504 unsigned long long flen;
505 struct GNUNET_TIME_Absolute et;
507 struct LocUriAssembly ass;
508 size_t slen;
509
510 slen = strlen (s);
511 pos = strlen (GNUNET_FS_URI_LOC_PREFIX);
512 if ((slen < pos + 2 * sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) + 1) ||
513 (0 != strncmp (s, GNUNET_FS_URI_LOC_PREFIX, pos)))
514 return NULL; /* not a LOC URI */
515 if ((s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] != '.') ||
516 (s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2 - 1] != '.'))
517 {
518 *emsg = GNUNET_strdup (_ ("LOC URI malformed (wrong syntax)"));
519 return NULL;
520 }
521 GNUNET_memcpy (h1, &s[pos], sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
522 h1[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
523 GNUNET_memcpy (h2,
524 &s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded)],
525 sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded));
526 h2[sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0';
527
528 if ((GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h1, &ass.fi.chk.key)) ||
529 (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (h2, &ass.fi.chk.query)) ||
530 (1 !=
531 sscanf (&s[pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2],
532 "%llu",
533 &flen)))
534 {
535 *emsg = GNUNET_strdup (_ ("LOC URI malformed (no CHK)"));
536 return NULL;
537 }
538 ass.fi.file_length = GNUNET_htonll (flen);
539
540 npos = pos + sizeof(struct GNUNET_CRYPTO_HashAsciiEncoded) * 2;
541 while ((s[npos] != '\0') && (s[npos] != '.'))
542 npos++;
543 if (s[npos] == '\0')
544 {
545 *emsg = GNUNET_strdup (_ ("LOC URI malformed (missing LOC)"));
546 goto ERR;
547 }
548 npos++;
549 if ((strlen (&s[npos]) <= GNUNET_CRYPTO_PKEY_ASCII_LENGTH + 1) ||
550 ('.' != s[npos + GNUNET_CRYPTO_PKEY_ASCII_LENGTH]))
551 {
552 *emsg =
553 GNUNET_strdup (_ ("LOC URI malformed (wrong syntax for public key)"));
554 }
555 if (
556 GNUNET_OK !=
559 &ass.peer.public_key))
560 {
561 *emsg =
562 GNUNET_strdup (_ ("LOC URI malformed (could not decode public key)"));
563 goto ERR;
564 }
566 if (s[npos++] != '.')
567 {
568 *emsg = GNUNET_strdup (_ ("LOC URI malformed (could not find signature)"));
569 goto ERR;
570 }
571 if ((strlen (&s[npos]) <= SIGNATURE_ASCII_LENGTH + 1) ||
572 ('.' != s[npos + SIGNATURE_ASCII_LENGTH]))
573 {
574 *emsg =
575 GNUNET_strdup (_ ("LOC URI malformed (wrong syntax for signature)"));
576 goto ERR;
577 }
578 if (GNUNET_OK !=
581 &sig,
582 sizeof(
584 {
585 *emsg =
586 GNUNET_strdup (_ ("LOC URI malformed (could not decode signature)"));
587 goto ERR;
588 }
590 if (s[npos++] != '.')
591 {
592 *emsg = GNUNET_strdup (
593 _ ("LOC URI malformed (wrong syntax for expiration time)"));
594 goto ERR;
595 }
596 if (1 != sscanf (&s[npos], "%llu", &exptime))
597 {
598 *emsg =
599 GNUNET_strdup (_ ("LOC URI malformed (could not parse expiration time)"));
600 goto ERR;
601 }
602 ass.purpose.size = htonl (sizeof(struct LocUriAssembly));
603 ass.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT);
604 et.abs_value_us = exptime * 1000LL * 1000LL;
605 ass.exptime = GNUNET_TIME_absolute_hton (et);
606 if (GNUNET_OK !=
608 &ass,
609 &sig,
610 &ass.peer.public_key))
611 {
612 *emsg =
613 GNUNET_strdup (_ ("LOC URI malformed (signature failed validation)"));
614 goto ERR;
615 }
616 uri = GNUNET_new (struct GNUNET_FS_Uri);
618 uri->data.loc.fi = ass.fi;
619 uri->data.loc.peer = ass.peer;
622
623 return uri;
624 ERR:
625 return NULL;
626}
@ GNUNET_FS_URI_LOC
Location (chk with identity of hosting peer).
Definition: fs_api.h:159
#define GNUNET_FS_URI_LOC_PREFIX
Definition: fs_uri.c:483
#define SIGNATURE_ASCII_LENGTH
Definition: fs_uri.c:485
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
#define GNUNET_CRYPTO_eddsa_verify(purp, ps, sig, pub)
Verify EdDSA signature.
#define GNUNET_CRYPTO_PKEY_ASCII_LENGTH
How many characters (without 0-terminator) are our ASCII-encoded public keys (ECDSA/EDDSA/ECDHE).
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:361
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:640
#define GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT
Signature by which a peer affirms that it is providing a certain bit of content for use in LOCation U...
an ECC signature using EdDSA.
union GNUNET_FS_Uri::@49 data
enum GNUNET_FS_UriType type
Type of the URI.
Definition: fs_api.h:171
struct Location loc
Information needed to retrieve a file including signed location (identity of a peer) of the content.
Definition: fs_api.h:218
Time for absolute times used by GNUnet, in microseconds.
Structure that defines how the contents of a location URI must be assembled in memory to create or ve...
Definition: fs_uri.c:459
struct GNUNET_TIME_Absolute expirationTime
Time when this location URI expires.
Definition: fs_api.h:127
struct GNUNET_CRYPTO_EddsaSignature contentSignature
Signature over the GNUNET_EC_FileIdentifier, peer identity and expiration time.
Definition: fs_api.h:133
struct FileIdentifier fi
Information about the shared file.
Definition: fs_api.h:117
struct GNUNET_PeerIdentity peer
Identity of the peer sharing the file.
Definition: fs_api.h:122

References _, GNUNET_TIME_Absolute::abs_value_us, FileIdentifier::chk, Location::contentSignature, GNUNET_FS_Uri::data, Location::expirationTime, LocUriAssembly::exptime, Location::fi, LocUriAssembly::fi, FileIdentifier::file_length, GNUNET_CRYPTO_eddsa_public_key_from_string(), GNUNET_CRYPTO_eddsa_verify, GNUNET_CRYPTO_hash_from_string, GNUNET_CRYPTO_PKEY_ASCII_LENGTH, GNUNET_FS_URI_LOC, GNUNET_FS_URI_LOC_PREFIX, GNUNET_htonll(), GNUNET_memcpy, GNUNET_new, GNUNET_OK, GNUNET_SIGNATURE_PURPOSE_PEER_PLACEMENT, GNUNET_strdup, GNUNET_STRINGS_string_to_data(), GNUNET_TIME_absolute_hton(), ContentHashKey::key, GNUNET_FS_Uri::loc, Location::peer, LocUriAssembly::peer, GNUNET_PeerIdentity::public_key, GNUNET_CRYPTO_EccSignaturePurpose::purpose, LocUriAssembly::purpose, ContentHashKey::query, SIGNATURE_ASCII_LENGTH, GNUNET_CRYPTO_EccSignaturePurpose::size, GNUNET_FS_Uri::type, and uri.

Referenced by GNUNET_FS_uri_parse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_non_mandatory_keyword()

static void insert_non_mandatory_keyword ( const char *  s,
char **  array,
int  index 
)
static

Add a keyword as non-mandatory (with ' '-prefix) to the given keyword list at offset 'index'.

The array is guaranteed to be long enough.

Parameters
skeyword to add
arrayarray to add the keyword to
indexoffset where to add the keyword

Definition at line 1417 of file fs_uri.c.

1418{
1419 char *nkword;
1420
1421 GNUNET_asprintf (&nkword,
1422 " %s", /* space to mark as 'non mandatory' */
1423 s);
1424 array[index] = nkword;
1425}
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.

References GNUNET_asprintf().

Referenced by gather_uri_data(), get_keywords_from_parens(), and get_keywords_from_tokens().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_duplicate()

static int find_duplicate ( const char *  s,
const char **  array,
int  array_length 
)
static

Test if the given keyword s is already present in the given array, ignoring the '+'-mandatory prefix in the array.

Parameters
skeyword to test
arraykeywords to test against, with ' ' or '+' prefix to ignore
array_lengthlength of the array
Returns
GNUNET_YES if the keyword exists, GNUNET_NO if not

Definition at line 1438 of file fs_uri.c.

1439{
1440 int j;
1441
1442 for (j = array_length - 1; j >= 0; j--)
1443 if (0 == strcmp (&array[j][1], s))
1444 return GNUNET_YES;
1445 return GNUNET_NO;
1446}
@ GNUNET_YES
@ GNUNET_NO

References GNUNET_NO, and GNUNET_YES.

Referenced by gather_uri_data(), get_keywords_from_parens(), and get_keywords_from_tokens().

Here is the caller graph for this function:

◆ normalize_metadata()

static char * normalize_metadata ( enum EXTRACTOR_MetaFormat  format,
const char *  data,
size_t  data_len 
)
static

FIXME: comment.

Definition at line 1453 of file fs_uri.c.

1456{
1457 uint8_t *free_str = NULL;
1458 uint8_t *str_to_normalize = (uint8_t *) data;
1459 uint8_t *normalized;
1460 size_t r_len;
1461
1462 if (str_to_normalize == NULL)
1463 return NULL;
1464 /* Don't trust libextractor */
1465 if (format == EXTRACTOR_METAFORMAT_UTF8)
1466 {
1467 free_str = (uint8_t *) u8_check ((const uint8_t *) data, data_len);
1468 if (free_str == NULL)
1469 free_str = NULL;
1470 else
1471 format = EXTRACTOR_METAFORMAT_C_STRING;
1472 }
1473 if (format == EXTRACTOR_METAFORMAT_C_STRING)
1474 {
1475 free_str = u8_strconv_from_encoding (data,
1476 locale_charset (),
1477 iconveh_escape_sequence);
1478 if (free_str == NULL)
1479 return NULL;
1480 }
1481
1482 normalized = u8_tolower (str_to_normalize,
1483 strlen ((char *) str_to_normalize),
1484 NULL,
1485 UNINORM_NFD,
1486 NULL,
1487 &r_len);
1488 /* free_str is allocated by libunistring internally, use free() */
1489 if (free_str != NULL)
1490 free (free_str);
1491 if (normalized != NULL)
1492 {
1493 /* u8_tolower allocates a non-NULL-terminated string! */
1494 free_str = GNUNET_malloc (r_len + 1);
1495 GNUNET_memcpy (free_str, normalized, r_len);
1496 free_str[r_len] = '\0';
1497 free (normalized);
1498 normalized = free_str;
1499 }
1500 return (char *) normalized;
1501}
static char * data
The data to insert into the dht.

References data, GNUNET_malloc, and GNUNET_memcpy.

Referenced by gather_uri_data(), get_keywords_from_parens(), and get_keywords_from_tokens().

Here is the caller graph for this function:

◆ u8_strcount()

static size_t u8_strcount ( const uint8_t *  s)
static

Counts the number of UTF-8 characters (not bytes) in the string, returns that count.

Definition at line 1509 of file fs_uri.c.

1510{
1511 size_t count;
1512 ucs4_t c;
1513
1514 GNUNET_assert (s != NULL);
1515 if (s[0] == 0)
1516 return 0;
1517 for (count = 0; s != NULL; count++)
1518 s = u8_next (&c, s);
1519 return count - 1;
1520}

References GNUNET_assert.

Referenced by gather_uri_data(), get_keywords_from_parens(), and get_keywords_from_tokens().

Here is the caller graph for this function:

◆ get_keywords_from_parens()

static int get_keywords_from_parens ( const char *  s,
char **  array,
int  index 
)
static

Break the filename up by matching [], () and {} pairs to make keywords.

In case of nesting parentheses only the inner pair counts. You can't escape parentheses to scan something like "[blah\{foo]" to make a "blah{foo" keyword, this function is only a heuristic!

Parameters
sstring to break down.
arrayarray to fill with enclosed tokens. If NULL, then tokens are only counted.
indexindex at which to start filling the array (entries prior to it are used to check for duplicates). ignored if array == NULL.
Returns
number of tokens counted (including duplicates), or number of tokens extracted (excluding duplicates). 0 if there are no matching parens in the string (when counting), or when all tokens were duplicates (when extracting).

Definition at line 1540 of file fs_uri.c.

1541{
1542 int count = 0;
1543 char *open_paren;
1544 char *close_paren;
1545 char *ss;
1546 char tmp;
1547
1548 if (NULL == s)
1549 return 0;
1550 ss = GNUNET_strdup (s);
1551 open_paren = ss - 1;
1552 while (NULL != (open_paren = strpbrk (open_paren + 1, "[{(")))
1553 {
1554 int match = 0;
1555
1556 close_paren = strpbrk (open_paren + 1, "]})");
1557 if (NULL == close_paren)
1558 continue;
1559 switch (open_paren[0])
1560 {
1561 case '[':
1562 if (']' == close_paren[0])
1563 match = 1;
1564 break;
1565
1566 case '{':
1567 if ('}' == close_paren[0])
1568 match = 1;
1569 break;
1570
1571 case '(':
1572 if (')' == close_paren[0])
1573 match = 1;
1574 break;
1575
1576 default:
1577 break;
1578 }
1579 if (match && (close_paren - open_paren > 1))
1580 {
1581 tmp = close_paren[0];
1582 close_paren[0] = '\0';
1583 /* Keywords must be at least 3 characters long */
1584 if (u8_strcount ((const uint8_t *) &open_paren[1]) <= 2)
1585 {
1586 close_paren[0] = tmp;
1587 continue;
1588 }
1589 if (NULL != array)
1590 {
1591 char *normalized;
1592 if (GNUNET_NO == find_duplicate ((const char *) &open_paren[1],
1593 (const char **) array,
1594 index + count))
1595 {
1596 insert_non_mandatory_keyword ((const char *) &open_paren[1],
1597 array,
1598 index + count);
1599 count++;
1600 }
1601 normalized = normalize_metadata (EXTRACTOR_METAFORMAT_UTF8,
1602 &open_paren[1],
1603 close_paren - &open_paren[1]);
1604 if (normalized != NULL)
1605 {
1606 if (GNUNET_NO == find_duplicate ((const char *) normalized,
1607 (const char **) array,
1608 index + count))
1609 {
1610 insert_non_mandatory_keyword ((const char *) normalized,
1611 array,
1612 index + count);
1613 count++;
1614 }
1615 GNUNET_free (normalized);
1616 }
1617 }
1618 else
1619 count++;
1620 close_paren[0] = tmp;
1621 }
1622 }
1623 GNUNET_free (ss);
1624 return count;
1625}
static void insert_non_mandatory_keyword(const char *s, char **array, int index)
Add a keyword as non-mandatory (with ' '-prefix) to the given keyword list at offset 'index'.
Definition: fs_uri.c:1417
static size_t u8_strcount(const uint8_t *s)
Counts the number of UTF-8 characters (not bytes) in the string, returns that count.
Definition: fs_uri.c:1509
static char * normalize_metadata(enum EXTRACTOR_MetaFormat format, const char *data, size_t data_len)
FIXME: comment.
Definition: fs_uri.c:1453
static int find_duplicate(const char *s, const char **array, int array_length)
Test if the given keyword s is already present in the given array, ignoring the '+'-mandatory prefix ...
Definition: fs_uri.c:1438

References find_duplicate(), GNUNET_free, GNUNET_NO, GNUNET_strdup, insert_non_mandatory_keyword(), normalize_metadata(), and u8_strcount().

Referenced by GNUNET_FS_uri_ksk_create_from_meta_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_keywords_from_tokens()

static int get_keywords_from_tokens ( const char *  s,
char **  array,
int  index 
)
static

Break the filename up by TOKENS to make keywords.

Parameters
sstring to break down.
arrayarray to fill with tokens. If NULL, then tokens are only counted.
indexindex at which to start filling the array (entries prior to it are used to check for duplicates). ignored if array == NULL.
Returns
number of tokens (>1) counted (including duplicates), or number of tokens extracted (excluding duplicates). 0 if there are no separators in the string (when counting), or when all tokens were duplicates (when extracting).

Definition at line 1648 of file fs_uri.c.

1649{
1650 char *p;
1651 char *ss;
1652 int seps = 0;
1653
1654 ss = GNUNET_strdup (s);
1655 for (p = strtok (ss, TOKENS); p != NULL; p = strtok (NULL, TOKENS))
1656 {
1657 /* Keywords must be at least 3 characters long */
1658 if (u8_strcount ((const uint8_t *) p) <= 2)
1659 continue;
1660 if (NULL != array)
1661 {
1662 char *normalized;
1663 if (GNUNET_NO == find_duplicate (p, (const char **) array, index + seps))
1664 {
1665 insert_non_mandatory_keyword (p, array, index + seps);
1666 seps++;
1667 }
1668 normalized =
1669 normalize_metadata (EXTRACTOR_METAFORMAT_UTF8, p, strlen (p));
1670 if (normalized != NULL)
1671 {
1672 if (GNUNET_NO == find_duplicate ((const char *) normalized,
1673 (const char **) array,
1674 index + seps))
1675 {
1676 insert_non_mandatory_keyword ((const char *) normalized,
1677 array,
1678 index + seps);
1679 seps++;
1680 }
1681 GNUNET_free (normalized);
1682 }
1683 }
1684 else
1685 seps++;
1686 }
1687 GNUNET_free (ss);
1688 return seps;
1689}
#define TOKENS
Where to break up keywords.
Definition: fs_uri.c:1631
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38

References find_duplicate(), GNUNET_free, GNUNET_NO, GNUNET_strdup, insert_non_mandatory_keyword(), normalize_metadata(), p, TOKENS, and u8_strcount().

Referenced by GNUNET_FS_uri_ksk_create_from_meta_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ gather_uri_data()

static int gather_uri_data ( void *  cls,
const char *  plugin_name,
enum EXTRACTOR_MetaType  type,
enum EXTRACTOR_MetaFormat  format,
const char *  data_mime_type,
const char *  data,
size_t  data_len 
)
static

Function called on each value in the meta data.

Adds it to the URI.

Parameters
clsURI to update
plugin_namename of the plugin that produced this value; special values can be used (e.g. '<zlib>' for zlib being used in the main libextractor library and yielding meta data).
typelibextractor-type describing the meta data
formatbasic format information about data
data_mime_typemime-type of data (not of the original file); can be NULL (if mime-type is not known)
dataactual meta-data found
data_lennumber of bytes in data
Returns
0 (always)

Definition at line 1713 of file fs_uri.c.

1720{
1721 struct GNUNET_FS_Uri *uri = cls;
1722 char *normalized_data;
1723 const char *sep;
1724
1725 if ((format != EXTRACTOR_METAFORMAT_UTF8) &&
1726 (format != EXTRACTOR_METAFORMAT_C_STRING))
1727 return 0;
1728 /* Keywords must be at least 3 characters long
1729 * If given non-utf8 string it will, most likely, find it to be invalid,
1730 * and will return the length of its valid part, skipping the keyword.
1731 * If it does - fix the extractor, not this check!
1732 */if (u8_strcount ((const uint8_t *) data) <= 2)
1733 return 0;
1734 if ((EXTRACTOR_METATYPE_MIMETYPE == type) &&
1735 (NULL != (sep = memchr (data, '/', data_len))) && (sep != data))
1736 {
1737 char *xtra;
1738
1739 GNUNET_asprintf (&xtra, "mimetype:%.*s", (int) (sep - data), data);
1740 if (! find_duplicate (xtra,
1741 (const char **) uri->data.ksk.keywords,
1743 {
1748 }
1749 GNUNET_free (xtra);
1750 }
1751
1752 normalized_data = normalize_metadata (format, data, data_len);
1753 if (! find_duplicate (data,
1754 (const char **) uri->data.ksk.keywords,
1756 {
1761 }
1762 if (NULL != normalized_data)
1763 {
1764 if (! find_duplicate (normalized_data,
1765 (const char **) uri->data.ksk.keywords,
1767 {
1768 insert_non_mandatory_keyword (normalized_data,
1772 }
1773 GNUNET_free (normalized_data);
1774 }
1775 return 0;
1776}
static uint32_t type
Type string converted to DNS type value.
struct GNUNET_FS_Uri::@49::@50 ksk
unsigned int keywordCount
Size of the keywords array.
Definition: fs_api.h:191

References data, GNUNET_FS_Uri::data, find_duplicate(), GNUNET_asprintf(), GNUNET_free, insert_non_mandatory_keyword(), GNUNET_FS_Uri::keywordCount, GNUNET_FS_Uri::keywords, GNUNET_FS_Uri::ksk, normalize_metadata(), type, u8_strcount(), and uri.

Referenced by GNUNET_FS_uri_ksk_create_from_meta_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ needs_percent()

static int needs_percent ( char  c)
static

In URI-encoding, does the given character need to be encoded using %-encoding?

Definition at line 1845 of file fs_uri.c.

1846{
1847 return(! ((isalnum ((unsigned char) c)) || (c == '-') || (c == '_') ||
1848 (c == '.') || (c == '~')));
1849}

Referenced by uri_ksk_to_string().

Here is the caller graph for this function:

◆ uri_ksk_to_string()

static char * uri_ksk_to_string ( const struct GNUNET_FS_Uri uri)
static

Convert a KSK URI to a string.

Parameters
urithe URI to convert
Returns
NULL on error (i.e. keywordCount == 0)

Definition at line 1859 of file fs_uri.c.

1860{
1861 char **keywords;
1862 unsigned int keywordCount;
1863 size_t n;
1864 char *ret;
1865 unsigned int i;
1866 unsigned int j;
1867 unsigned int wpos;
1868 size_t slen;
1869 const char *keyword;
1870
1871 if (uri->type != GNUNET_FS_URI_KSK)
1872 return NULL;
1873 keywords = uri->data.ksk.keywords;
1874 keywordCount = uri->data.ksk.keywordCount;
1875 n = keywordCount + strlen (GNUNET_FS_URI_PREFIX)
1876 + strlen (GNUNET_FS_URI_KSK_INFIX) + 1;
1877 for (i = 0; i < keywordCount; i++)
1878 {
1879 keyword = keywords[i];
1880 slen = strlen (keyword);
1881 n += slen;
1882 for (j = 0; j < slen; j++)
1883 {
1884 if ((j == 0) && (keyword[j] == ' '))
1885 {
1886 n--;
1887 continue; /* skip leading space */
1888 }
1889 if (needs_percent (keyword[j]))
1890 n += 2; /* will use %-encoding */
1891 }
1892 }
1893 ret = GNUNET_malloc (n);
1894 strcpy (ret, GNUNET_FS_URI_PREFIX);
1895 strcat (ret, GNUNET_FS_URI_KSK_INFIX);
1896 wpos = strlen (ret);
1897 for (i = 0; i < keywordCount; i++)
1898 {
1899 keyword = keywords[i];
1900 slen = strlen (keyword);
1901 for (j = 0; j < slen; j++)
1902 {
1903 if ((j == 0) && (keyword[j] == ' '))
1904 continue; /* skip leading space */
1905 if (needs_percent (keyword[j]))
1906 {
1907 sprintf (&ret[wpos], "%%%02X", (unsigned char) keyword[j]);
1908 wpos += 3;
1909 }
1910 else
1911 {
1912 ret[wpos++] = keyword[j];
1913 }
1914 }
1915 if (i != keywordCount - 1)
1916 ret[wpos++] = '+';
1917 }
1918 return ret;
1919}
static int needs_percent(char c)
In URI-encoding, does the given character need to be encoded using %-encoding?
Definition: fs_uri.c:1845
#define GNUNET_FS_URI_KSK_INFIX
#define GNUNET_FS_URI_PREFIX

References GNUNET_FS_Uri::data, GNUNET_FS_URI_KSK, GNUNET_FS_URI_KSK_INFIX, GNUNET_FS_URI_PREFIX, GNUNET_malloc, GNUNET_FS_Uri::keywordCount, GNUNET_FS_Uri::keywords, GNUNET_FS_Uri::ksk, needs_percent(), ret, GNUNET_FS_Uri::type, and uri.

Referenced by GNUNET_FS_uri_to_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_sks_to_string()

static char * uri_sks_to_string ( const struct GNUNET_FS_Uri uri)
static

Convert SKS URI to a string.

Parameters
urisks uri to convert
Returns
NULL on error

Definition at line 1929 of file fs_uri.c.

1930{
1931 char *ret;
1932 char buf[1024];
1933
1934 if (GNUNET_FS_URI_SKS != uri->type)
1935 return NULL;
1936 ret =
1938 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
1939 buf,
1940 sizeof(buf));
1941 GNUNET_assert (NULL != ret);
1942 ret[0] = '\0';
1944 "%s%s%s/%s",
1947 buf,
1949 return ret;
1950}
#define GNUNET_FS_URI_SKS_INFIX
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition: strings.c:732
struct GNUNET_FS_Uri::@49::@51 sks
struct GNUNET_CRYPTO_EcdsaPublicKey ns
Identifier of the namespace.
Definition: fs_api.h:199
char * identifier
Human-readable identifier chosen for this entry in the namespace.
Definition: fs_api.h:205

References GNUNET_FS_Uri::data, GNUNET_asprintf(), GNUNET_assert, GNUNET_FS_URI_PREFIX, GNUNET_FS_URI_SKS, GNUNET_FS_URI_SKS_INFIX, GNUNET_STRINGS_data_to_string(), GNUNET_FS_Uri::identifier, GNUNET_FS_Uri::ns, ret, GNUNET_FS_Uri::sks, GNUNET_FS_Uri::type, and uri.

Referenced by GNUNET_FS_uri_to_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_chk_to_string()

static char * uri_chk_to_string ( const struct GNUNET_FS_Uri uri)
static

Convert a CHK URI to a string.

Parameters
urichk uri to convert
Returns
NULL on error

Definition at line 1960 of file fs_uri.c.

1961{
1962 const struct FileIdentifier *fi;
1963 char *ret;
1964 struct GNUNET_CRYPTO_HashAsciiEncoded keyhash;
1965 struct GNUNET_CRYPTO_HashAsciiEncoded queryhash;
1966
1967 if (uri->type != GNUNET_FS_URI_CHK)
1968 return NULL;
1969 fi = &uri->data.chk;
1970 GNUNET_CRYPTO_hash_to_enc (&fi->chk.key, &keyhash);
1971 GNUNET_CRYPTO_hash_to_enc (&fi->chk.query, &queryhash);
1972
1974 "%s%s%s.%s.%llu",
1977 (const char *) &keyhash,
1978 (const char *) &queryhash,
1979 (unsigned long long) GNUNET_ntohll (fi->file_length));
1980 return ret;
1981}
#define GNUNET_FS_URI_CHK_INFIX
void GNUNET_CRYPTO_hash_to_enc(const struct GNUNET_HashCode *block, struct GNUNET_CRYPTO_HashAsciiEncoded *result)
Convert hash to ASCII encoding.
Definition: crypto_hash.c:55
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:54
struct GNUNET_HashCode key
Hash of the original content, used for encryption.
Definition: fs.h:59
struct GNUNET_HashCode query
Hash of the encrypted content, used for querying.
Definition: fs.h:64
struct ContentHashKey chk
Query and key of the top GNUNET_EC_IBlock.
Definition: fs_api.h:104
uint64_t file_length
Total size of the file in bytes.
Definition: fs_api.h:99
struct FileIdentifier chk
Information needed to retrieve a file (content-hash-key plus file size).
Definition: fs_api.h:212

References FileIdentifier::chk, GNUNET_FS_Uri::chk, GNUNET_FS_Uri::data, FileIdentifier::file_length, GNUNET_asprintf(), GNUNET_CRYPTO_hash_to_enc(), GNUNET_FS_URI_CHK, GNUNET_FS_URI_CHK_INFIX, GNUNET_FS_URI_PREFIX, GNUNET_ntohll(), ContentHashKey::key, ContentHashKey::query, ret, GNUNET_FS_Uri::type, and uri.

Referenced by GNUNET_FS_uri_to_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ uri_loc_to_string()

static char * uri_loc_to_string ( const struct GNUNET_FS_Uri uri)
static

Convert a LOC URI to a string.

Parameters
uriloc uri to convert
Returns
NULL on error

Definition at line 1991 of file fs_uri.c.

1992{
1993 char *ret;
1994 struct GNUNET_CRYPTO_HashAsciiEncoded keyhash;
1995 struct GNUNET_CRYPTO_HashAsciiEncoded queryhash;
1996 char *peer_id;
1997 char peer_sig[SIGNATURE_ASCII_LENGTH + 1];
1998
2001 peer_id =
2004 NULL !=
2006 sizeof(struct GNUNET_CRYPTO_EddsaSignature),
2007 peer_sig,
2008 sizeof(peer_sig)));
2010 "%s%s%s.%s.%llu.%s.%s.%llu",
2013 (const char *) &keyhash,
2014 (const char *) &queryhash,
2015 (unsigned long long) GNUNET_ntohll (
2017 peer_id,
2018 peer_sig,
2019 (unsigned long long)
2021 / 1000000LL);
2023 return ret;
2024}
static char * peer_id
Option –peer.
Definition: gnunet-cadet.c:42
#define GNUNET_FS_URI_LOC_INFIX
char * GNUNET_CRYPTO_eddsa_public_key_to_string(const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:255
struct GNUNET_CRYPTO_EddsaPublicKey public_key
uint64_t abs_value_us
The actual value.

References GNUNET_TIME_Absolute::abs_value_us, FileIdentifier::chk, Location::contentSignature, GNUNET_FS_Uri::data, Location::expirationTime, Location::fi, FileIdentifier::file_length, GNUNET_asprintf(), GNUNET_assert, GNUNET_CRYPTO_eddsa_public_key_to_string(), GNUNET_CRYPTO_hash_to_enc(), GNUNET_free, GNUNET_FS_URI_LOC_INFIX, GNUNET_FS_URI_PREFIX, GNUNET_ntohll(), GNUNET_STRINGS_data_to_string(), ContentHashKey::key, GNUNET_FS_Uri::loc, Location::peer, peer_id, GNUNET_PeerIdentity::public_key, ContentHashKey::query, ret, SIGNATURE_ASCII_LENGTH, and uri.

Referenced by GNUNET_FS_uri_to_string().

Here is the call graph for this function:
Here is the caller graph for this function: