aboutsummaryrefslogtreecommitdiff
path: root/src/fs
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs')
-rw-r--r--src/fs/Makefile.am3
-rw-r--r--src/fs/fs_api.c35
-rw-r--r--src/fs/fs_api.h128
-rw-r--r--src/fs/fs_namespace.c772
-rw-r--r--src/fs/fs_pseudonym.c977
-rw-r--r--src/fs/fs_publish.c30
-rw-r--r--src/fs/fs_publish_ksk.c179
-rw-r--r--src/fs/fs_publish_ublock.c262
-rw-r--r--src/fs/fs_publish_ublock.h108
-rw-r--r--src/fs/fs_search.c114
-rw-r--r--src/fs/fs_unindex.c25
-rw-r--r--src/fs/fs_uri.c109
-rw-r--r--src/fs/gnunet-pseudonym.c260
-rw-r--r--src/fs/gnunet-publish.c211
-rw-r--r--src/fs/plugin_block_fs.c9
-rw-r--r--src/fs/test_fs_namespace.c53
-rw-r--r--src/fs/test_fs_namespace_list_updateable.c14
-rw-r--r--src/fs/test_fs_uri.c9
-rw-r--r--src/fs/test_pseudonym.c148
19 files changed, 1155 insertions, 2291 deletions
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am
index e8928f770..ce70ff751 100644
--- a/src/fs/Makefile.am
+++ b/src/fs/Makefile.am
@@ -39,6 +39,7 @@ libgnunetfs_la_SOURCES = \
39 fs_pseudonym.c \ 39 fs_pseudonym.c \
40 fs_publish.c \ 40 fs_publish.c \
41 fs_publish_ksk.c \ 41 fs_publish_ksk.c \
42 fs_publish_ublock.c fs_publish_ublock.h \
42 fs_misc.c \ 43 fs_misc.c \
43 fs_namespace.c \ 44 fs_namespace.c \
44 fs_search.c \ 45 fs_search.c \
@@ -126,6 +127,7 @@ gnunet_download_DEPENDENCIES = \
126gnunet_publish_SOURCES = \ 127gnunet_publish_SOURCES = \
127 gnunet-publish.c 128 gnunet-publish.c
128gnunet_publish_LDADD = \ 129gnunet_publish_LDADD = \
130 $(top_builddir)/src/identity/libgnunetidentity.la \
129 $(top_builddir)/src/fs/libgnunetfs.la \ 131 $(top_builddir)/src/fs/libgnunetfs.la \
130 $(top_builddir)/src/util/libgnunetutil.la \ 132 $(top_builddir)/src/util/libgnunetutil.la \
131 -lextractor \ 133 -lextractor \
@@ -154,6 +156,7 @@ gnunet_helper_fs_publish_DEPENDENCIES = \
154gnunet_pseudonym_SOURCES = \ 156gnunet_pseudonym_SOURCES = \
155 gnunet-pseudonym.c 157 gnunet-pseudonym.c
156gnunet_pseudonym_LDADD = \ 158gnunet_pseudonym_LDADD = \
159 $(top_builddir)/src/identity/libgnunetidentity.la \
157 $(top_builddir)/src/fs/libgnunetfs.la \ 160 $(top_builddir)/src/fs/libgnunetfs.la \
158 $(top_builddir)/src/util/libgnunetutil.la \ 161 $(top_builddir)/src/util/libgnunetutil.la \
159 -lextractor \ 162 -lextractor \
diff --git a/src/fs/fs_api.c b/src/fs/fs_api.c
index ab49139b9..9676f2e3c 100644
--- a/src/fs/fs_api.c
+++ b/src/fs/fs_api.c
@@ -1467,17 +1467,17 @@ deserialize_publish_file (void *cls, const char *filename)
1467 struct GNUNET_FS_PublishContext *pc; 1467 struct GNUNET_FS_PublishContext *pc;
1468 int32_t options; 1468 int32_t options;
1469 int32_t all_done; 1469 int32_t all_done;
1470 int32_t have_ns;
1470 char *fi_root; 1471 char *fi_root;
1471 char *ns; 1472 struct GNUNET_CRYPTO_EccPrivateKey ns;
1472 char *fi_pos; 1473 char *fi_pos;
1473 char *emsg; 1474 char *emsg;
1474 1475
1475 pc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishContext)); 1476 pc = GNUNET_new (struct GNUNET_FS_PublishContext);
1476 pc->h = h; 1477 pc->h = h;
1477 pc->serialization = get_serialization_short_name (filename); 1478 pc->serialization = get_serialization_short_name (filename);
1478 fi_root = NULL; 1479 fi_root = NULL;
1479 fi_pos = NULL; 1480 fi_pos = NULL;
1480 ns = NULL;
1481 rh = GNUNET_BIO_read_open (filename); 1481 rh = GNUNET_BIO_read_open (filename);
1482 if (NULL == rh) 1482 if (NULL == rh)
1483 { 1483 {
@@ -1489,10 +1489,12 @@ deserialize_publish_file (void *cls, const char *filename)
1489 GNUNET_BIO_read_string (rh, "publish-nuid", &pc->nuid, 1024)) || 1489 GNUNET_BIO_read_string (rh, "publish-nuid", &pc->nuid, 1024)) ||
1490 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &options)) || 1490 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &options)) ||
1491 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &all_done)) || 1491 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &all_done)) ||
1492 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &have_ns)) ||
1492 (GNUNET_OK != 1493 (GNUNET_OK !=
1493 GNUNET_BIO_read_string (rh, "publish-firoot", &fi_root, 128)) || 1494 GNUNET_BIO_read_string (rh, "publish-firoot", &fi_root, 128)) ||
1494 (GNUNET_OK != GNUNET_BIO_read_string (rh, "publish-fipos", &fi_pos, 128)) 1495 (GNUNET_OK != GNUNET_BIO_read_string (rh, "publish-fipos", &fi_pos, 128))
1495 || (GNUNET_OK != GNUNET_BIO_read_string (rh, "publish-ns", &ns, 1024))) 1496 || ( (GNUNET_YES == have_ns) &&
1497 (GNUNET_OK != GNUNET_BIO_read (rh, "publish-ns", &ns, sizeof (ns)))) )
1496 { 1498 {
1497 GNUNET_break (0); 1499 GNUNET_break (0);
1498 goto cleanup; 1500 goto cleanup;
@@ -1510,17 +1512,10 @@ deserialize_publish_file (void *cls, const char *filename)
1510 GNUNET_break (0); 1512 GNUNET_break (0);
1511 goto cleanup; 1513 goto cleanup;
1512 } 1514 }
1513 if (NULL != ns) 1515 if (GNUNET_YES == have_ns)
1514 { 1516 {
1515 pc->ns = GNUNET_FS_namespace_create (h, ns); 1517 pc->ns = GNUNET_new (struct GNUNET_CRYPTO_EccPrivateKey);
1516 if (NULL == pc->ns) 1518 *pc->ns = ns;
1517 {
1518 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1519 _
1520 ("Failed to recover namespace `%s', cannot resume publishing operation.\n"),
1521 ns);
1522 goto cleanup;
1523 }
1524 } 1519 }
1525 if ((0 == (pc->options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) && 1520 if ((0 == (pc->options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) &&
1526 (GNUNET_YES != pc->all_done)) 1521 (GNUNET_YES != pc->all_done))
@@ -1563,7 +1558,6 @@ deserialize_publish_file (void *cls, const char *filename)
1563 filename, emsg); 1558 filename, emsg);
1564 GNUNET_free (emsg); 1559 GNUNET_free (emsg);
1565 } 1560 }
1566 GNUNET_free_non_null (ns);
1567 pc->top = GNUNET_FS_make_top (h, &GNUNET_FS_publish_signal_suspend_, pc); 1561 pc->top = GNUNET_FS_make_top (h, &GNUNET_FS_publish_signal_suspend_, pc);
1568 return GNUNET_OK; 1562 return GNUNET_OK;
1569cleanup: 1563cleanup:
@@ -1571,7 +1565,6 @@ cleanup:
1571 GNUNET_free_non_null (pc->nuid); 1565 GNUNET_free_non_null (pc->nuid);
1572 GNUNET_free_non_null (fi_root); 1566 GNUNET_free_non_null (fi_root);
1573 GNUNET_free_non_null (fi_pos); 1567 GNUNET_free_non_null (fi_pos);
1574 GNUNET_free_non_null (ns);
1575 if ((NULL != rh) && (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg))) 1568 if ((NULL != rh) && (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg)))
1576 { 1569 {
1577 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1570 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -1601,6 +1594,7 @@ void
1601GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc) 1594GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc)
1602{ 1595{
1603 struct GNUNET_BIO_WriteHandle *wh; 1596 struct GNUNET_BIO_WriteHandle *wh;
1597 int32_t have_ns;
1604 1598
1605 if (NULL == pc->serialization) 1599 if (NULL == pc->serialization)
1606 pc->serialization = 1600 pc->serialization =
@@ -1622,17 +1616,20 @@ GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc)
1622 GNUNET_break (0); 1616 GNUNET_break (0);
1623 goto cleanup; 1617 goto cleanup;
1624 } 1618 }
1619 have_ns = (NULL != pc->ns) ? GNUNET_YES : GNUNET_NO;
1625 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, pc->nid)) || 1620 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, pc->nid)) ||
1626 (GNUNET_OK != GNUNET_BIO_write_string (wh, pc->nuid)) || 1621 (GNUNET_OK != GNUNET_BIO_write_string (wh, pc->nuid)) ||
1627 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pc->options)) || 1622 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pc->options)) ||
1628 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pc->all_done)) || 1623 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pc->all_done)) ||
1624 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, have_ns)) ||
1629 (GNUNET_OK != GNUNET_BIO_write_string (wh, pc->fi->serialization)) || 1625 (GNUNET_OK != GNUNET_BIO_write_string (wh, pc->fi->serialization)) ||
1630 (GNUNET_OK != 1626 (GNUNET_OK !=
1631 GNUNET_BIO_write_string (wh, 1627 GNUNET_BIO_write_string (wh,
1632 (NULL == pc->fi_pos) ? NULL : pc->fi_pos->serialization)) || 1628 (NULL == pc->fi_pos) ? NULL : pc->fi_pos->serialization)) ||
1633 (GNUNET_OK != 1629 ( (NULL != pc->ns) &&
1634 GNUNET_BIO_write_string (wh, 1630 GNUNET_BIO_write (wh,
1635 (NULL == pc->ns) ? NULL : pc->ns->name))) 1631 pc->ns,
1632 sizeof (struct GNUNET_CRYPTO_EccPrivateKey)) ) )
1636 { 1633 {
1637 GNUNET_break (0); 1634 GNUNET_break (0);
1638 goto cleanup; 1635 goto cleanup;
diff --git a/src/fs/fs_api.h b/src/fs/fs_api.h
index 2fe38f604..83e8c3801 100644
--- a/src/fs/fs_api.h
+++ b/src/fs/fs_api.h
@@ -182,16 +182,13 @@ struct GNUNET_FS_Uri
182 struct 182 struct
183 { 183 {
184 /** 184 /**
185 * Keywords start with a '+' if they are 185 * Keywords start with a '+' if they are mandatory (in which
186 * mandatory (in which case the '+' is NOT 186 * case the '+' is NOT part of the keyword) and with a simple
187 * part of the keyword) and with a 187 * space if they are optional (in which case the space is ALSO
188 * simple space if they are optional 188 * not part of the actual keyword).
189 * (in which case the space is ALSO not
190 * part of the actual keyword).
191 * 189 *
192 * Double-quotes to protect spaces and 190 * Double-quotes to protect spaces and %-encoding are NOT used
193 * %-encoding are NOT used internally 191 * internally (only in URI-strings).
194 * (only in URI-strings).
195 */ 192 */
196 char **keywords; 193 char **keywords;
197 194
@@ -206,7 +203,7 @@ struct GNUNET_FS_Uri
206 /** 203 /**
207 * Identifier of the namespace. 204 * Identifier of the namespace.
208 */ 205 */
209 struct GNUNET_FS_PseudonymIdentifier ns; 206 struct GNUNET_CRYPTO_EccPublicKey ns;
210 207
211 /** 208 /**
212 * Human-readable identifier chosen for this 209 * Human-readable identifier chosen for this
@@ -1178,7 +1175,7 @@ struct GNUNET_FS_PublishContext
1178 /** 1175 /**
1179 * Namespace that we are publishing in, NULL if we have no namespace. 1176 * Namespace that we are publishing in, NULL if we have no namespace.
1180 */ 1177 */
1181 struct GNUNET_FS_Namespace *ns; 1178 struct GNUNET_CRYPTO_EccPrivateKey *ns;
1182 1179
1183 /** 1180 /**
1184 * ID of the content in the namespace, NULL if we have no namespace. 1181 * ID of the content in the namespace, NULL if we have no namespace.
@@ -1459,11 +1456,6 @@ struct GNUNET_FS_UnindexContext
1459 */ 1456 */
1460struct SearchRequestEntry 1457struct SearchRequestEntry
1461{ 1458{
1462 /**
1463 * Hash of the original keyword, used to derive the
1464 * key (for decrypting the KBlock).
1465 */
1466 struct GNUNET_HashCode ukey;
1467 1459
1468 /** 1460 /**
1469 * Hash of the public key, also known as the query. 1461 * Hash of the public key, also known as the query.
@@ -1471,6 +1463,17 @@ struct SearchRequestEntry
1471 struct GNUNET_HashCode uquery; 1463 struct GNUNET_HashCode uquery;
1472 1464
1473 /** 1465 /**
1466 * Derived public key, hashes to 'uquery'.
1467 */
1468 struct GNUNET_CRYPTO_EccPublicKey dpub;
1469
1470 /**
1471 * The original keyword, used to derive the
1472 * key (for decrypting the UBlock).
1473 */
1474 char *keyword;
1475
1476 /**
1474 * Map that contains a "struct GNUNET_FS_SearchResult" for each result that 1477 * Map that contains a "struct GNUNET_FS_SearchResult" for each result that
1475 * was found under this keyword. Note that the entries will point 1478 * was found under this keyword. Note that the entries will point
1476 * to the same locations as those in the master result map (in 1479 * to the same locations as those in the master result map (in
@@ -1963,99 +1966,6 @@ struct GNUNET_FS_DownloadContext
1963}; 1966};
1964 1967
1965 1968
1966/**
1967 * Information about an (updateable) node in the
1968 * namespace.
1969 */
1970struct NamespaceUpdateNode
1971{
1972 /**
1973 * Identifier for this node.
1974 */
1975 char *id;
1976
1977 /**
1978 * Identifier of children of this node.
1979 */
1980 char *update;
1981
1982 /**
1983 * Metadata for this entry.
1984 */
1985 struct GNUNET_CONTAINER_MetaData *md;
1986
1987 /**
1988 * URI of this entry in the namespace.
1989 */
1990 struct GNUNET_FS_Uri *uri;
1991
1992 /**
1993 * Namespace update generation ID. Used to ensure
1994 * freshness of the tree_id.
1995 */
1996 unsigned int nug;
1997
1998 /**
1999 * TREE this entry belongs to (if nug is current).
2000 */
2001 unsigned int tree_id;
2002
2003};
2004
2005
2006/**
2007 * Handle to one of our namespaces.
2008 */
2009struct GNUNET_FS_Namespace
2010{
2011
2012 /**
2013 * Handle to the FS service context.
2014 */
2015 struct GNUNET_FS_Handle *h;
2016
2017 /**
2018 * Array with information about nodes in the namespace.
2019 */
2020 struct NamespaceUpdateNode **update_nodes;
2021
2022 /**
2023 * Private key for the namespace.
2024 */
2025 struct GNUNET_FS_PseudonymHandle *key;
2026
2027 /**
2028 * Hash map mapping identifiers of update nodes
2029 * to the update nodes (initialized on-demand).
2030 */
2031 struct GNUNET_CONTAINER_MultiHashMap *update_map;
2032
2033 /**
2034 * Name of the file with the private key.
2035 */
2036 char *filename;
2037
2038 /**
2039 * Name of the namespace.
2040 */
2041 char *name;
2042
2043 /**
2044 * Size of the update nodes array.
2045 */
2046 unsigned int update_node_count;
2047
2048 /**
2049 * Reference counter.
2050 */
2051 unsigned int rc;
2052
2053 /**
2054 * Generator for unique nug numbers.
2055 */
2056 unsigned int nug_gen;
2057};
2058
2059#endif 1969#endif
2060 1970
2061/* end of fs_api.h */ 1971/* end of fs_api.h */
diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c
index d456dc34b..8537ba0e6 100644
--- a/src/fs/fs_namespace.c
+++ b/src/fs/fs_namespace.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Christian Grothoff (and other contributing authors) 3 (C) 2003-2013 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -20,7 +20,7 @@
20 20
21/** 21/**
22 * @file fs/fs_namespace.c 22 * @file fs/fs_namespace.c
23 * @brief create and destroy namespaces 23 * @brief publishing to namespaces, and tracking updateable entries
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
@@ -29,30 +29,91 @@
29#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
30#include "gnunet_fs_service.h" 30#include "gnunet_fs_service.h"
31#include "fs_api.h" 31#include "fs_api.h"
32#include "fs_publish_ublock.h"
32 33
33 34
34/** 35/**
35 * Return the name of the directory in which we store 36 * Information about an (updateable) node in the
36 * our local namespaces (or rather, their public keys). 37 * namespace.
37 *
38 * @param h global fs handle
39 * @return NULL on error, otherwise the name of the directory
40 */ 38 */
41static char * 39struct NamespaceUpdateNode
42get_namespace_directory (struct GNUNET_FS_Handle *h)
43{ 40{
44 char *dn; 41 /**
42 * Identifier for this node.
43 */
44 char *id;
45 45
46 if (GNUNET_OK != 46 /**
47 GNUNET_CONFIGURATION_get_value_filename (h->cfg, "FS", "IDENTITY_DIR", 47 * Identifier of children of this node.
48 &dn)) 48 */
49 { 49 char *update;
50 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 50
51 "fs", "IDENTITY_DIR"); 51 /**
52 return NULL; 52 * Metadata for this entry.
53 } 53 */
54 return dn; 54 struct GNUNET_CONTAINER_MetaData *md;
55} 55
56 /**
57 * URI of this entry in the namespace.
58 */
59 struct GNUNET_FS_Uri *uri;
60
61 /**
62 * Namespace update generation ID. Used to ensure
63 * freshness of the tree_id.
64 */
65 unsigned int nug;
66
67 /**
68 * TREE this entry belongs to (if nug is current).
69 */
70 unsigned int tree_id;
71
72};
73
74
75/**
76 * Handle to update information for a namespace.
77 */
78struct GNUNET_FS_UpdateInformationGraph
79{
80
81 /**
82 * Handle to the FS service context.
83 */
84 struct GNUNET_FS_Handle *h;
85
86 /**
87 * Array with information about nodes in the namespace.
88 */
89 struct NamespaceUpdateNode **update_nodes;
90
91 /**
92 * Private key for the namespace.
93 */
94 struct GNUNET_CRYPTO_EccPrivateKey ns;
95
96 /**
97 * Hash map mapping identifiers of update nodes
98 * to the update nodes (initialized on-demand).
99 */
100 struct GNUNET_CONTAINER_MultiHashMap *update_map;
101
102 /**
103 * Size of the update nodes array.
104 */
105 unsigned int update_node_count;
106
107 /**
108 * Reference counter.
109 */
110 unsigned int rc;
111
112 /**
113 * Generator for unique nug numbers.
114 */
115 unsigned int nug_gen;
116};
56 117
57 118
58/** 119/**
@@ -63,32 +124,71 @@ get_namespace_directory (struct GNUNET_FS_Handle *h)
63 * @return NULL on error, otherwise the name of the directory 124 * @return NULL on error, otherwise the name of the directory
64 */ 125 */
65static char * 126static char *
66get_update_information_directory (struct GNUNET_FS_Namespace *ns) 127get_update_information_directory (struct GNUNET_FS_Handle *h,
128 const struct GNUNET_CRYPTO_EccPrivateKey *ns)
67{ 129{
68 char *dn; 130 char *dn;
69 char *ret; 131 char *ret;
132 struct GNUNET_CRYPTO_EccPublicKey pub;
133 struct GNUNET_CRYPTO_ShortHashCode hc;
134 struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc;
70 135
71 if (GNUNET_OK != 136 if (GNUNET_OK !=
72 GNUNET_CONFIGURATION_get_value_filename (ns->h->cfg, "FS", "UPDATE_DIR", 137 GNUNET_CONFIGURATION_get_value_filename (h->cfg, "FS", "UPDATE_DIR",
73 &dn)) 138 &dn))
74 { 139 {
75 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 140 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
76 "fs", "UPDATE_DIR"); 141 "fs", "UPDATE_DIR");
77 return NULL; 142 return NULL;
78 } 143 }
79 GNUNET_asprintf (&ret, "%s%s%s", dn, DIR_SEPARATOR_STR, ns->name); 144 GNUNET_CRYPTO_ecc_key_get_public (ns, &pub);
145 GNUNET_CRYPTO_short_hash (&pub, sizeof (pub), &hc);
146 GNUNET_CRYPTO_short_hash_to_enc (&hc,
147 &enc);
148 GNUNET_asprintf (&ret, "%s%s%s",
149 dn,
150 DIR_SEPARATOR_STR,
151 (const char *) enc.short_encoding);
80 GNUNET_free (dn); 152 GNUNET_free (dn);
81 return ret; 153 return ret;
82} 154}
83 155
84 156
85/** 157/**
158 * Release memory occupied by UIG datastructure.
159 *
160 * @param uig data structure to free
161 */
162static void
163free_update_information_graph (struct GNUNET_FS_UpdateInformationGraph *uig)
164{
165 unsigned int i;
166 struct NamespaceUpdateNode *nsn;
167
168 for (i = 0; i < uig->update_node_count; i++)
169 {
170 nsn = uig->update_nodes[i];
171 GNUNET_CONTAINER_meta_data_destroy (nsn->md);
172 GNUNET_FS_uri_destroy (nsn->uri);
173 GNUNET_free (nsn->id);
174 GNUNET_free (nsn->update);
175 GNUNET_free (nsn);
176 }
177 GNUNET_array_grow (uig->update_nodes, uig->update_node_count,
178 0);
179 if (NULL != uig->update_map)
180 GNUNET_CONTAINER_multihashmap_destroy (uig->update_map);
181 GNUNET_free (uig);
182}
183
184
185/**
86 * Write the namespace update node graph to a file. 186 * Write the namespace update node graph to a file.
87 * 187 *
88 * @param ns namespace to dump 188 * @param ns namespace to dump
89 */ 189 */
90static void 190static void
91write_update_information_graph (struct GNUNET_FS_Namespace *ns) 191write_update_information_graph (struct GNUNET_FS_UpdateInformationGraph *uig)
92{ 192{
93 char *fn; 193 char *fn;
94 struct GNUNET_BIO_WriteHandle *wh; 194 struct GNUNET_BIO_WriteHandle *wh;
@@ -96,7 +196,8 @@ write_update_information_graph (struct GNUNET_FS_Namespace *ns)
96 struct NamespaceUpdateNode *n; 196 struct NamespaceUpdateNode *n;
97 char *uris; 197 char *uris;
98 198
99 fn = get_update_information_directory (ns); 199 fn = get_update_information_directory (uig->h,
200 &uig->ns);
100 wh = GNUNET_BIO_write_open (fn); 201 wh = GNUNET_BIO_write_open (fn);
101 if (NULL == wh) 202 if (NULL == wh)
102 { 203 {
@@ -105,11 +206,11 @@ write_update_information_graph (struct GNUNET_FS_Namespace *ns)
105 GNUNET_free (fn); 206 GNUNET_free (fn);
106 return; 207 return;
107 } 208 }
108 if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, ns->update_node_count)) 209 if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, uig->update_node_count))
109 goto END; 210 goto END;
110 for (i = 0; i < ns->update_node_count; i++) 211 for (i = 0; i < uig->update_node_count; i++)
111 { 212 {
112 n = ns->update_nodes[i]; 213 n = uig->update_nodes[i];
113 uris = GNUNET_FS_uri_to_string (n->uri); 214 uris = GNUNET_FS_uri_to_string (n->uri);
114 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, n->id)) || 215 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, n->id)) ||
115 (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, n->md)) || 216 (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, n->md)) ||
@@ -132,11 +233,15 @@ END:
132/** 233/**
133 * Read the namespace update node graph from a file. 234 * Read the namespace update node graph from a file.
134 * 235 *
236 * @param h FS handle to use
135 * @param ns namespace to read 237 * @param ns namespace to read
238 * @return update graph, never NULL
136 */ 239 */
137static void 240static struct GNUNET_FS_UpdateInformationGraph *
138read_update_information_graph (struct GNUNET_FS_Namespace *ns) 241read_update_information_graph (struct GNUNET_FS_Handle *h,
242 const struct GNUNET_CRYPTO_EccPrivateKey *ns)
139{ 243{
244 struct GNUNET_FS_UpdateInformationGraph *uig;
140 char *fn; 245 char *fn;
141 struct GNUNET_BIO_ReadHandle *rh; 246 struct GNUNET_BIO_ReadHandle *rh;
142 unsigned int i; 247 unsigned int i;
@@ -145,40 +250,43 @@ read_update_information_graph (struct GNUNET_FS_Namespace *ns)
145 uint32_t count; 250 uint32_t count;
146 char *emsg; 251 char *emsg;
147 252
148 fn = get_update_information_directory (ns); 253 uig = GNUNET_new (struct GNUNET_FS_UpdateInformationGraph);
254 uig->h = h;
255 uig->ns = *ns;
256 fn = get_update_information_directory (h, ns);
149 if (GNUNET_YES != GNUNET_DISK_file_test (fn)) 257 if (GNUNET_YES != GNUNET_DISK_file_test (fn))
150 { 258 {
151 GNUNET_free (fn); 259 GNUNET_free (fn);
152 return; 260 return uig;
153 } 261 }
154 rh = GNUNET_BIO_read_open (fn); 262 rh = GNUNET_BIO_read_open (fn);
155 if (NULL == rh) 263 if (NULL == rh)
156 { 264 {
157 GNUNET_free (fn); 265 GNUNET_free (fn);
158 return; 266 return uig;
159 } 267 }
160 if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &count)) 268 if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &count))
161 { 269 {
162 GNUNET_break (0); 270 GNUNET_break (0);
163 goto END; 271 goto ERROR;
164 } 272 }
165 if (count > 1024 * 1024) 273 if (count > 1024 * 1024)
166 { 274 {
167 GNUNET_break (0); 275 GNUNET_break (0);
168 goto END; 276 goto ERROR;
169 } 277 }
170 if (0 == count) 278 if (0 == count)
171 { 279 {
172 GNUNET_break (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL)); 280 GNUNET_break (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL));
173 GNUNET_free (fn); 281 GNUNET_free (fn);
174 return; 282 return uig;
175 } 283 }
176 ns->update_nodes = 284 uig->update_nodes =
177 GNUNET_malloc (count * sizeof (struct NamespaceUpdateNode *)); 285 GNUNET_malloc (count * sizeof (struct NamespaceUpdateNode *));
178 286
179 for (i = 0; i < count; i++) 287 for (i = 0; i < count; i++)
180 { 288 {
181 n = GNUNET_malloc (sizeof (struct NamespaceUpdateNode)); 289 n = GNUNET_new (struct NamespaceUpdateNode);
182 if ((GNUNET_OK != GNUNET_BIO_read_string (rh, "identifier", &n->id, 1024)) 290 if ((GNUNET_OK != GNUNET_BIO_read_string (rh, "identifier", &n->id, 1024))
183 || (GNUNET_OK != GNUNET_BIO_read_meta_data (rh, "meta", &n->md)) || 291 || (GNUNET_OK != GNUNET_BIO_read_meta_data (rh, "meta", &n->md)) ||
184 (GNUNET_OK != 292 (GNUNET_OK !=
@@ -205,304 +313,25 @@ read_update_information_graph (struct GNUNET_FS_Namespace *ns)
205 GNUNET_free (n); 313 GNUNET_free (n);
206 break; 314 break;
207 } 315 }
208 ns->update_nodes[i] = n; 316 uig->update_nodes[i] = n;
209 } 317 }
210 ns->update_node_count = i; 318 uig->update_node_count = i;
211END:
212 if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg)) 319 if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg))
213 { 320 {
214 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to write `%s': %s\n"), emsg); 321 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to read `%s': %s\n"),
322 fn, emsg);
215 GNUNET_free (emsg); 323 GNUNET_free (emsg);
216 } 324 }
217 GNUNET_free (fn); 325 return uig;
218} 326ERROR:
219 327 if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg))
220
221/**
222 * Create a namespace with the given name; if one already
223 * exists, return a handle to the existing namespace.
224 *
225 * @param h handle to the file sharing subsystem
226 * @param name name to use for the namespace
227 * @return handle to the namespace, NULL on error (i.e. invalid filename)
228 */
229struct GNUNET_FS_Namespace *
230GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h, const char *name)
231{
232 char *dn;
233 char *fn;
234 struct GNUNET_FS_Namespace *ret;
235
236 dn = get_namespace_directory (h);
237 if (NULL == dn)
238 {
239 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
240 _("Can't determine where namespace directory is\n"));
241 return NULL;
242 }
243 GNUNET_asprintf (&fn, "%s%s%s", dn, DIR_SEPARATOR_STR, name);
244 GNUNET_free (dn);
245 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Namespace));
246 ret->h = h;
247 ret->rc = 1;
248 ret->key = GNUNET_FS_pseudonym_create (fn);
249 if (NULL == ret->key)
250 {
251 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
252 _("Failed to create or read private key for namespace `%s'\n"),
253 name);
254 GNUNET_free (ret);
255 GNUNET_free (fn);
256 return NULL;
257 }
258 ret->name = GNUNET_strdup (name);
259 ret->filename = fn;
260 return ret;
261}
262
263
264/**
265 * Open the namespace with the given name; if it does not exist,
266 * or the key file is corrupted, the function fails.
267 *
268 * @param h handle to the file sharing subsystem
269 * @param name name of the namespace
270 * @return handle to the namespace,
271 * NULL on error (i.e. invalid filename, non-existent filename)
272 */
273struct GNUNET_FS_Namespace *
274GNUNET_FS_namespace_open_existing (struct GNUNET_FS_Handle *h, const char *name)
275{
276 char *dn;
277 char *fn;
278 struct GNUNET_FS_Namespace *ret;
279
280 dn = get_namespace_directory (h);
281 if (NULL == dn)
282 {
283 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
284 _("Can't determine where namespace directory is\n"));
285 return NULL;
286 }
287 GNUNET_asprintf (&fn, "%s%s%s", dn, DIR_SEPARATOR_STR, name);
288 GNUNET_free (dn);
289 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Namespace));
290 ret->h = h;
291 ret->rc = 1;
292 ret->key = GNUNET_FS_pseudonym_create_from_existing_file (fn);
293 if (NULL == ret->key)
294 {
295 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
296 _("Failed to read private key for namespace `%s'\n"), name);
297 GNUNET_free (ret);
298 GNUNET_free (fn);
299 return NULL;
300 }
301 ret->name = GNUNET_strdup (name);
302 ret->filename = fn;
303 return ret;
304}
305
306
307/**
308 * Rename a local namespace.
309 *
310 * @param h handle to the file sharing subsystem
311 * @param old_name old name of the namespace
312 * @param new_name new name of the namespace
313 * @return GNUNET_OK on success, GNUNET_SYSERR on error (see errno for details)
314 */
315int
316GNUNET_FS_namespace_rename (struct GNUNET_FS_Handle *h,
317 const char *old_name,
318 const char *new_name)
319{
320 char *dn;
321 char *fn_old;
322 char *fn_new;
323 int result;
324 int save_errno;
325
326 dn = get_namespace_directory (h);
327 if (NULL == dn)
328 {
329 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
330 _("Can't determine where namespace directory is\n"));
331 return GNUNET_SYSERR;
332 }
333 GNUNET_asprintf (&fn_old, "%s%s%s", dn, DIR_SEPARATOR_STR, old_name);
334 GNUNET_asprintf (&fn_new, "%s%s%s", dn, DIR_SEPARATOR_STR, new_name);
335 GNUNET_free (dn);
336 result = RENAME (fn_old, fn_new);
337 save_errno = errno;
338 GNUNET_free (fn_old);
339 GNUNET_free (fn_new);
340 errno = save_errno;
341 if (result == 0)
342 return GNUNET_OK;
343 return GNUNET_SYSERR;
344}
345
346
347/**
348 * Duplicate a namespace handle.
349 *
350 * @param ns namespace handle
351 * @return duplicated handle to the namespace
352 */
353struct GNUNET_FS_Namespace *
354GNUNET_FS_namespace_dup (struct GNUNET_FS_Namespace *ns)
355{
356 ns->rc++;
357 return ns;
358}
359
360
361/**
362 * Delete a namespace handle. Can be used for a clean shutdown (free
363 * memory) or also to freeze the namespace to prevent further
364 * insertions by anyone.
365 *
366 * @param ns handle to the namespace that should be deleted / freed
367 * @param freeze prevents future insertions; creating a namespace
368 * with the same name again will create a fresh namespace instead
369 *
370 * @return GNUNET_OK on success, GNUNET_SYSERR on error
371 */
372int
373GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *ns, int freeze)
374{
375 unsigned int i;
376 struct NamespaceUpdateNode *nsn;
377
378 ns->rc--;
379 if (freeze)
380 {
381 if (0 != UNLINK (ns->filename))
382 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "unlink",
383 ns->filename);
384 }
385 if (0 != ns->rc)
386 return GNUNET_OK;
387 GNUNET_FS_pseudonym_destroy (ns->key);
388 GNUNET_free (ns->filename);
389 GNUNET_free (ns->name);
390 for (i = 0; i < ns->update_node_count; i++)
391 {
392 nsn = ns->update_nodes[i];
393 GNUNET_CONTAINER_meta_data_destroy (nsn->md);
394 GNUNET_FS_uri_destroy (nsn->uri);
395 GNUNET_free (nsn->id);
396 GNUNET_free (nsn->update);
397 GNUNET_free (nsn);
398 }
399 GNUNET_array_grow (ns->update_nodes, ns->update_node_count,
400 0);
401 if (ns->update_map != NULL)
402 GNUNET_CONTAINER_multihashmap_destroy (ns->update_map);
403 GNUNET_free (ns);
404 return GNUNET_OK;
405}
406
407
408/**
409 * Context for the 'process_namespace' callback.
410 * Specifies a function to call on each namespace.
411 */
412struct ProcessNamespaceContext
413{
414 /**
415 * Function to call.
416 */
417 GNUNET_FS_NamespaceInfoProcessor cb;
418
419 /**
420 * Closure for 'cb'.
421 */
422 void *cb_cls;
423};
424
425
426/**
427 * Get hash of the public key of a namespace.
428 *
429 * @param ns namespace
430 * @param id buffer to store the key in
431 * @return GNUNET_OK on success
432 * GNUNET_SYSERR on failure (contents of id remain intact)
433 */
434int
435GNUNET_FS_namespace_get_public_identifier (struct GNUNET_FS_Namespace *ns,
436 struct GNUNET_FS_PseudonymIdentifier *id)
437{
438 if ((NULL == ns) || (NULL == id))
439 return GNUNET_SYSERR;
440 GNUNET_FS_pseudonym_get_identifier (ns->key, id);
441 return GNUNET_OK;
442}
443
444
445/**
446 * Function called with a filename of a namespace. Reads the key and
447 * calls the callback.
448 *
449 * @param cls closure (struct ProcessNamespaceContext)
450 * @param filename complete filename (absolute path)
451 * @return GNUNET_OK to continue to iterate,
452 * GNUNET_SYSERR to abort iteration with error!
453 */
454static int
455process_namespace (void *cls, const char *filename)
456{
457 struct ProcessNamespaceContext *pnc = cls;
458 struct GNUNET_FS_PseudonymHandle *ph;
459 struct GNUNET_FS_PseudonymIdentifier id;
460 const char *name;
461 const char *t;
462
463 if (NULL == (ph = GNUNET_FS_pseudonym_create (filename)))
464 { 328 {
465 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 329 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to read `%s': %s\n"),
466 _ 330 fn, emsg);
467 ("Failed to read namespace private key file `%s', deleting it!\n"), 331 GNUNET_free (emsg);
468 filename);
469 if (0 != UNLINK (filename))
470 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", filename);
471 return GNUNET_OK;
472 } 332 }
473 GNUNET_FS_pseudonym_get_identifier (ph, &id); 333 GNUNET_free (fn);
474 GNUNET_FS_pseudonym_destroy (ph); 334 return uig;
475 name = filename;
476 while (NULL != (t = strstr (name, DIR_SEPARATOR_STR)))
477 name = t + 1;
478 pnc->cb (pnc->cb_cls, name, &id);
479 return GNUNET_OK;
480}
481
482
483/**
484 * Build a list of all available local (!) namespaces The returned
485 * names are only the nicknames since we only iterate over the local
486 * namespaces.
487 *
488 * @param h handle to the file sharing subsystem
489 * @param cb function to call on each known namespace
490 * @param cb_cls closure for cb
491 */
492void
493GNUNET_FS_namespace_list (struct GNUNET_FS_Handle *h,
494 GNUNET_FS_NamespaceInfoProcessor cb, void *cb_cls)
495{
496 char *dn;
497 struct ProcessNamespaceContext ctx;
498
499 dn = get_namespace_directory (h);
500 if (NULL == dn)
501 return;
502 ctx.cb = cb;
503 ctx.cb_cls = cb_cls;
504 GNUNET_DISK_directory_scan (dn, &process_namespace, &ctx);
505 GNUNET_free (dn);
506} 335}
507 336
508 337
@@ -526,7 +355,7 @@ struct GNUNET_FS_PublishSksContext
526 /** 355 /**
527 * Namespace we're publishing to. 356 * Namespace we're publishing to.
528 */ 357 */
529 struct GNUNET_FS_Namespace *ns; 358 struct GNUNET_CRYPTO_EccPrivateKey ns;
530 359
531 /** 360 /**
532 * Handle to the datastore. 361 * Handle to the datastore.
@@ -534,6 +363,11 @@ struct GNUNET_FS_PublishSksContext
534 struct GNUNET_DATASTORE_Handle *dsh; 363 struct GNUNET_DATASTORE_Handle *dsh;
535 364
536 /** 365 /**
366 * Handle to FS.
367 */
368 struct GNUNET_FS_Handle *h;
369
370 /**
537 * Function to call once we're done. 371 * Function to call once we're done.
538 */ 372 */
539 GNUNET_FS_PublishContinuation cont; 373 GNUNET_FS_PublishContinuation cont;
@@ -544,31 +378,28 @@ struct GNUNET_FS_PublishSksContext
544 void *cont_cls; 378 void *cont_cls;
545 379
546 /** 380 /**
547 * Handle for our datastore request. 381 * Handle for our UBlock operation request.
548 */ 382 */
549 struct GNUNET_DATASTORE_QueueEntry *dqe; 383 struct GNUNET_FS_PublishUblockContext *uc;
550}; 384};
551 385
552 386
553/** 387/**
554 * Function called by the datastore API with 388 * Function called by the UBlock construction with
555 * the result from the PUT (UBlock) request. 389 * the result from the PUT (UBlock) request.
556 * 390 *
557 * @param cls closure of type "struct GNUNET_FS_PublishSksContext*" 391 * @param cls closure of type "struct GNUNET_FS_PublishSksContext*"
558 * @param success GNUNET_OK on success
559 * @param min_expiration minimum expiration time required for content to be stored
560 * @param msg error message (or NULL) 392 * @param msg error message (or NULL)
561 */ 393 */
562static void 394static void
563sb_put_cont (void *cls, int success, 395sks_publish_cont (void *cls,
564 struct GNUNET_TIME_Absolute min_expiration, 396 const char *msg)
565 const char *msg)
566{ 397{
567 struct GNUNET_FS_PublishSksContext *psc = cls; 398 struct GNUNET_FS_PublishSksContext *psc = cls;
568 struct GNUNET_HashCode hc; 399 struct GNUNET_FS_UpdateInformationGraph *uig;
569 400
570 psc->dqe = NULL; 401 psc->uc = NULL;
571 if (GNUNET_OK != success) 402 if (NULL != msg)
572 { 403 {
573 if (NULL != psc->cont) 404 if (NULL != psc->cont)
574 psc->cont (psc->cont_cls, NULL, msg); 405 psc->cont (psc->cont_cls, NULL, msg);
@@ -580,19 +411,14 @@ sb_put_cont (void *cls, int success,
580 /* FIXME: this can be done much more 411 /* FIXME: this can be done much more
581 * efficiently by simply appending to the 412 * efficiently by simply appending to the
582 * file and overwriting the 4-byte header */ 413 * file and overwriting the 4-byte header */
583 if (psc->ns->update_nodes == NULL) 414 uig = read_update_information_graph (psc->h,
584 read_update_information_graph (psc->ns); 415 &psc->ns);
585 GNUNET_array_append (psc->ns->update_nodes, 416 GNUNET_array_append (uig->update_nodes,
586 psc->ns->update_node_count, psc->nsn); 417 uig->update_node_count,
587 if (NULL != psc->ns->update_map) 418 psc->nsn);
588 {
589 GNUNET_CRYPTO_hash (psc->nsn->id, strlen (psc->nsn->id), &hc);
590 GNUNET_CONTAINER_multihashmap_put (psc->ns->update_map, &hc,
591 psc->nsn,
592 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
593 }
594 psc->nsn = NULL; 419 psc->nsn = NULL;
595 write_update_information_graph (psc->ns); 420 write_update_information_graph (uig);
421 free_update_information_graph (uig);
596 } 422 }
597 if (NULL != psc->cont) 423 if (NULL != psc->cont)
598 psc->cont (psc->cont_cls, psc->uri, NULL); 424 psc->cont (psc->cont_cls, psc->uri, NULL);
@@ -617,7 +443,7 @@ sb_put_cont (void *cls, int success,
617 */ 443 */
618struct GNUNET_FS_PublishSksContext * 444struct GNUNET_FS_PublishSksContext *
619GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, 445GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
620 struct GNUNET_FS_Namespace *ns, 446 const struct GNUNET_CRYPTO_EccPrivateKey *ns,
621 const char *identifier, const char *update, 447 const char *identifier, const char *update,
622 const struct GNUNET_CONTAINER_MetaData *meta, 448 const struct GNUNET_CONTAINER_MetaData *meta,
623 const struct GNUNET_FS_Uri *uri, 449 const struct GNUNET_FS_Uri *uri,
@@ -626,144 +452,49 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
626 GNUNET_FS_PublishContinuation cont, void *cont_cls) 452 GNUNET_FS_PublishContinuation cont, void *cont_cls)
627{ 453{
628 struct GNUNET_FS_PublishSksContext *psc; 454 struct GNUNET_FS_PublishSksContext *psc;
629 struct GNUNET_CRYPTO_AesSessionKey sk;
630 struct GNUNET_CRYPTO_AesInitializationVector iv;
631 struct GNUNET_FS_Uri *sks_uri; 455 struct GNUNET_FS_Uri *sks_uri;
632 char *uris; 456
633 size_t size; 457 sks_uri = GNUNET_new (struct GNUNET_FS_Uri);
634 size_t slen;
635 size_t nidlen;
636 size_t idlen;
637 ssize_t mdsize;
638 struct UBlock *ub;
639 struct UBlock *ub_enc;
640 char *dest;
641 struct GNUNET_CONTAINER_MetaData *mmeta;
642 struct GNUNET_HashCode id_hash; /* hash of thisId */
643 struct GNUNET_HashCode ns_hash; /* hash of namespace public key */
644 struct GNUNET_HashCode key; /* id_hash ^ ns_hash, for AES key */
645 struct GNUNET_HashCode signing_key; /* H(key) = input for public key */
646 struct GNUNET_HashCode query; /* H(verification_key) = query */
647
648 idlen = strlen (identifier);
649 if (NULL != update)
650 nidlen = strlen (update) + 1;
651 else
652 nidlen = 1;
653 uris = GNUNET_FS_uri_to_string (uri);
654 slen = strlen (uris) + 1;
655 if ( (slen >= MAX_UBLOCK_SIZE - sizeof (struct UBlock)) ||
656 (nidlen >= MAX_UBLOCK_SIZE - sizeof (struct UBlock) - slen) )
657 {
658 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
659 _("Identifiers or URI too long to create UBlock"));
660 GNUNET_free (uris);
661 return NULL;
662 }
663 if (NULL == meta)
664 mmeta = GNUNET_CONTAINER_meta_data_create ();
665 else
666 mmeta = GNUNET_CONTAINER_meta_data_duplicate (meta);
667 mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (mmeta);
668 size = sizeof (struct UBlock) + slen + nidlen + mdsize;
669 if ( (size > MAX_UBLOCK_SIZE) ||
670 (size < sizeof (struct UBlock) + slen + nidlen) )
671 {
672 size = MAX_UBLOCK_SIZE;
673 mdsize = MAX_UBLOCK_SIZE - (sizeof (struct UBlock) + slen + nidlen);
674 }
675 ub = GNUNET_malloc (sizeof (struct UBlock) + size);
676 dest = (char *) &ub[1];
677 if (NULL != update)
678 memcpy (dest, update, nidlen);
679 else
680 memset (dest, 0, 1);
681 dest += nidlen;
682 memcpy (dest, uris, slen);
683 GNUNET_free (uris);
684 dest += slen;
685 mdsize =
686 GNUNET_CONTAINER_meta_data_serialize (mmeta, &dest, mdsize,
687 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
688 GNUNET_CONTAINER_meta_data_destroy (mmeta);
689 if (-1 == mdsize)
690 {
691 GNUNET_break (0);
692 GNUNET_free (ub);
693 if (NULL != cont)
694 cont (cont_cls, NULL, _("Internal error."));
695 return NULL;
696 }
697 sks_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri));
698 sks_uri->type = GNUNET_FS_URI_SKS; 458 sks_uri->type = GNUNET_FS_URI_SKS;
699 sks_uri->data.sks.identifier = GNUNET_strdup (identifier); 459 sks_uri->data.sks.identifier = GNUNET_strdup (identifier);
700 GNUNET_FS_namespace_get_public_identifier (ns, 460 GNUNET_CRYPTO_ecc_key_get_public (ns,
701 &sks_uri->data.sks.ns); 461 &sks_uri->data.sks.ns);
702 462
703 size = sizeof (struct UBlock) + mdsize + slen + nidlen; 463 psc = GNUNET_new (struct GNUNET_FS_PublishSksContext);
704 ub_enc = GNUNET_malloc (size); 464 psc->h = h;
705 GNUNET_CRYPTO_hash (identifier, idlen, &id_hash);
706 GNUNET_CRYPTO_hash (&sks_uri->data.sks.ns,
707 sizeof (sks_uri->data.sks.ns), &ns_hash);
708 GNUNET_CRYPTO_hash_xor (&id_hash, &ns_hash, &key);
709 GNUNET_CRYPTO_hash_to_aes_key (&key, &sk, &iv);
710 GNUNET_CRYPTO_hash (&key, sizeof (struct GNUNET_HashCode), &signing_key);
711
712 GNUNET_CRYPTO_aes_encrypt (&ub[1],
713 size - sizeof (struct UBlock),
714 &sk, &iv,
715 &ub_enc[1]);
716 ub_enc->purpose.size = htonl (nidlen + slen + mdsize + sizeof (struct UBlock)
717 - sizeof (struct GNUNET_FS_PseudonymSignature));
718 ub_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK);
719 GNUNET_FS_pseudonym_derive_verification_key (&sks_uri->data.sks.ns,
720 &signing_key,
721 &ub_enc->verification_key);
722 GNUNET_CRYPTO_hash (&ub_enc->verification_key,
723 sizeof (ub_enc->verification_key),
724 &query);
725 GNUNET_FS_pseudonym_sign (ns->key,
726 &ub_enc->purpose,
727 NULL,
728 &signing_key,
729 &ub_enc->signature);
730 psc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishSksContext));
731 psc->uri = sks_uri; 465 psc->uri = sks_uri;
732 psc->cont = cont; 466 psc->cont = cont;
733 psc->ns = GNUNET_FS_namespace_dup (ns);
734 psc->cont_cls = cont_cls; 467 psc->cont_cls = cont_cls;
735 if (0 != (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) 468 psc->ns = *ns;
736 { 469 if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
737 GNUNET_free (ub_enc);
738 GNUNET_free (ub);
739 sb_put_cont (psc, GNUNET_OK, GNUNET_TIME_UNIT_ZERO_ABS, NULL);
740 return NULL;
741 }
742 psc->dsh = GNUNET_DATASTORE_connect (h->cfg);
743 if (NULL == psc->dsh)
744 { 470 {
745 GNUNET_free (ub_enc); 471 psc->dsh = GNUNET_DATASTORE_connect (h->cfg);
746 GNUNET_free (ub); 472 if (NULL == psc->dsh)
747 sb_put_cont (psc, GNUNET_NO, GNUNET_TIME_UNIT_ZERO_ABS, _("Failed to connect to datastore.")); 473 {
748 return NULL; 474 sks_publish_cont (psc,
475 _("Failed to connect to datastore."));
476 return NULL;
477 }
749 } 478 }
750
751 if (NULL != update) 479 if (NULL != update)
752 { 480 {
753 psc->nsn = GNUNET_malloc (sizeof (struct NamespaceUpdateNode)); 481 psc->nsn = GNUNET_new (struct NamespaceUpdateNode);
754 psc->nsn->id = GNUNET_strdup (identifier); 482 psc->nsn->id = GNUNET_strdup (identifier);
755 psc->nsn->update = GNUNET_strdup (update); 483 psc->nsn->update = GNUNET_strdup (update);
756 psc->nsn->md = GNUNET_CONTAINER_meta_data_duplicate (meta); 484 psc->nsn->md = GNUNET_CONTAINER_meta_data_duplicate (meta);
757 psc->nsn->uri = GNUNET_FS_uri_dup (uri); 485 psc->nsn->uri = GNUNET_FS_uri_dup (uri);
758 } 486 }
759 487 psc->uc = GNUNET_FS_publish_ublock_ (h,
760 psc->dqe = GNUNET_DATASTORE_put (psc->dsh, 0, &query, size, ub_enc, 488 psc->dsh,
761 GNUNET_BLOCK_TYPE_FS_UBLOCK, bo->content_priority, 489 identifier,
762 bo->anonymity_level, bo->replication_level, 490 update,
763 bo->expiration_time, -2, 1, 491 ns,
764 GNUNET_CONSTANTS_SERVICE_TIMEOUT, &sb_put_cont, psc); 492 meta,
765 GNUNET_free (ub); 493 uri,
766 GNUNET_free (ub_enc); 494 bo,
495 options,
496 &sks_publish_cont,
497 psc);
767 return psc; 498 return psc;
768} 499}
769 500
@@ -776,17 +507,16 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
776void 507void
777GNUNET_FS_publish_sks_cancel (struct GNUNET_FS_PublishSksContext *psc) 508GNUNET_FS_publish_sks_cancel (struct GNUNET_FS_PublishSksContext *psc)
778{ 509{
779 if (NULL != psc->dqe) 510 if (NULL != psc->uc)
780 { 511 {
781 GNUNET_DATASTORE_cancel (psc->dqe); 512 GNUNET_FS_publish_ublock_cancel_ (psc->uc);
782 psc->dqe = NULL; 513 psc->uc = NULL;
783 } 514 }
784 if (NULL != psc->dsh) 515 if (NULL != psc->dsh)
785 { 516 {
786 GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO); 517 GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO);
787 psc->dsh = NULL; 518 psc->dsh = NULL;
788 } 519 }
789 GNUNET_FS_namespace_delete (psc->ns, GNUNET_NO);
790 GNUNET_FS_uri_destroy (psc->uri); 520 GNUNET_FS_uri_destroy (psc->uri);
791 if (NULL != psc->nsn) 521 if (NULL != psc->nsn)
792 { 522 {
@@ -828,12 +558,18 @@ struct ProcessUpdateClosure
828 * GNUNET_NO if not. 558 * GNUNET_NO if not.
829 */ 559 */
830static int 560static int
831process_update_node (void *cls, const struct GNUNET_HashCode * key, void *value) 561process_update_node (void *cls,
562 const struct GNUNET_HashCode *key,
563 void *value)
832{ 564{
833 struct ProcessUpdateClosure *pc = cls; 565 struct ProcessUpdateClosure *pc = cls;
834 struct NamespaceUpdateNode *nsn = value; 566 struct NamespaceUpdateNode *nsn = value;
835 567
836 pc->ip (pc->ip_cls, nsn->id, nsn->uri, nsn->md, nsn->update); 568 pc->ip (pc->ip_cls,
569 nsn->id,
570 nsn->uri,
571 nsn->md,
572 nsn->update);
837 return GNUNET_YES; 573 return GNUNET_YES;
838} 574}
839 575
@@ -844,9 +580,9 @@ process_update_node (void *cls, const struct GNUNET_HashCode * key, void *value)
844struct FindTreeClosure 580struct FindTreeClosure
845{ 581{
846 /** 582 /**
847 * Namespace we are operating on. 583 * UIG we are operating on.
848 */ 584 */
849 struct GNUNET_FS_Namespace *ns; 585 struct GNUNET_FS_UpdateInformationGraph *uig;
850 586
851 /** 587 /**
852 * Array with 'head's of TREEs. 588 * Array with 'head's of TREEs.
@@ -891,7 +627,9 @@ struct FindTreeClosure
891 * GNUNET_NO if not. 627 * GNUNET_NO if not.
892 */ 628 */
893static int 629static int
894find_trees (void *cls, const struct GNUNET_HashCode * key, void *value) 630find_trees (void *cls,
631 const struct GNUNET_HashCode *key,
632 void *value)
895{ 633{
896 struct FindTreeClosure *fc = cls; 634 struct FindTreeClosure *fc = cls;
897 struct NamespaceUpdateNode *nsn = value; 635 struct NamespaceUpdateNode *nsn = value;
@@ -918,7 +656,7 @@ find_trees (void *cls, const struct GNUNET_HashCode * key, void *value)
918 nsn->tree_id = UINT_MAX; /* mark as undef */ 656 nsn->tree_id = UINT_MAX; /* mark as undef */
919 /* trace */ 657 /* trace */
920 GNUNET_CRYPTO_hash (nsn->update, strlen (nsn->update), &hc); 658 GNUNET_CRYPTO_hash (nsn->update, strlen (nsn->update), &hc);
921 GNUNET_CONTAINER_multihashmap_get_multiple (fc->ns->update_map, &hc, 659 GNUNET_CONTAINER_multihashmap_get_multiple (fc->uig->update_map, &hc,
922 &find_trees, fc); 660 &find_trees, fc);
923 } 661 }
924 return GNUNET_YES; 662 return GNUNET_YES;
@@ -942,13 +680,15 @@ find_trees (void *cls, const struct GNUNET_HashCode * key, void *value)
942 * I know, odd definition of a tree, but the GUI will display an actual 680 * I know, odd definition of a tree, but the GUI will display an actual
943 * tree (GtkTreeView), so that's what counts for the term here. 681 * tree (GtkTreeView), so that's what counts for the term here.
944 * 682 *
683 * @param h fs handle to use
945 * @param ns namespace to inspect for updateable content 684 * @param ns namespace to inspect for updateable content
946 * @param next_id ID to look for; use NULL to look for tree roots 685 * @param next_id ID to look for; use NULL to look for tree roots
947 * @param ip function to call on each updateable identifier 686 * @param ip function to call on each updateable identifier
948 * @param ip_cls closure for ip 687 * @param ip_cls closure for ip
949 */ 688 */
950void 689void
951GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns, 690GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Handle *h,
691 const struct GNUNET_CRYPTO_EccPrivateKey *ns,
952 const char *next_id, 692 const char *next_id,
953 GNUNET_FS_IdentifierProcessor ip, 693 GNUNET_FS_IdentifierProcessor ip,
954 void *ip_cls) 694 void *ip_cls)
@@ -959,50 +699,48 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns,
959 struct NamespaceUpdateNode *nsn; 699 struct NamespaceUpdateNode *nsn;
960 struct ProcessUpdateClosure pc; 700 struct ProcessUpdateClosure pc;
961 struct FindTreeClosure fc; 701 struct FindTreeClosure fc;
702 struct GNUNET_FS_UpdateInformationGraph *uig;
962 703
963 if (NULL == ns->update_nodes) 704 uig = read_update_information_graph (h, ns);
964 read_update_information_graph (ns); 705 if (NULL == uig->update_nodes)
965 if (NULL == ns->update_nodes)
966 { 706 {
967 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 707 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
968 "No updateable nodes found for ID `%s'\n", next_id); 708 "No updateable nodes found for ID `%s'\n", next_id);
709 free_update_information_graph (uig);
969 return; /* no nodes */ 710 return; /* no nodes */
970 } 711 }
971 if (NULL == ns->update_map) 712 uig->update_map =
713 GNUNET_CONTAINER_multihashmap_create (2 +
714 3 * uig->update_node_count /
715 4,
716 GNUNET_NO);
717 for (i = 0; i < uig->update_node_count; i++)
972 { 718 {
973 /* need to construct */ 719 nsn = uig->update_nodes[i];
974 ns->update_map = 720 GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc);
975 GNUNET_CONTAINER_multihashmap_create (2 + 721 GNUNET_CONTAINER_multihashmap_put (uig->update_map, &hc, nsn,
976 3 * ns->update_node_count / 722 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
977 4,
978 GNUNET_NO);
979 for (i = 0; i < ns->update_node_count; i++)
980 {
981 nsn = ns->update_nodes[i];
982 GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc);
983 GNUNET_CONTAINER_multihashmap_put (ns->update_map, &hc, nsn,
984 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
985 }
986 } 723 }
987 if (NULL != next_id) 724 if (NULL != next_id)
988 { 725 {
989 GNUNET_CRYPTO_hash (next_id, strlen (next_id), &hc); 726 GNUNET_CRYPTO_hash (next_id, strlen (next_id), &hc);
990 pc.ip = ip; 727 pc.ip = ip;
991 pc.ip_cls = ip_cls; 728 pc.ip_cls = ip_cls;
992 GNUNET_CONTAINER_multihashmap_get_multiple (ns->update_map, &hc, 729 GNUNET_CONTAINER_multihashmap_get_multiple (uig->update_map, &hc,
993 &process_update_node, &pc); 730 &process_update_node, &pc);
731 free_update_information_graph (uig);
994 return; 732 return;
995 } 733 }
996 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 734 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
997 "Calculating TREEs to find roots of update trees\n"); 735 "Calculating TREEs to find roots of update trees\n");
998 /* Find heads of TREEs in update graph */ 736 /* Find heads of TREEs in update graph */
999 nug = ++ns->nug_gen; 737 nug = ++uig->nug_gen;
1000 fc.tree_array = NULL; 738 fc.tree_array = NULL;
1001 fc.tree_array_size = 0; 739 fc.tree_array_size = 0;
1002 740
1003 for (i = 0; i < ns->update_node_count; i++) 741 for (i = 0; i < uig->update_node_count; i++)
1004 { 742 {
1005 nsn = ns->update_nodes[i]; 743 nsn = uig->update_nodes[i];
1006 if (nsn->nug == nug) 744 if (nsn->nug == nug)
1007 { 745 {
1008 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, 746 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id,
@@ -1014,15 +752,15 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns,
1014 nsn->tree_id = UINT_MAX; 752 nsn->tree_id = UINT_MAX;
1015 fc.id = UINT_MAX; 753 fc.id = UINT_MAX;
1016 fc.nug = nug; 754 fc.nug = nug;
1017 fc.ns = ns; 755 fc.uig = uig;
1018 GNUNET_CONTAINER_multihashmap_get_multiple (ns->update_map, &hc, 756 GNUNET_CONTAINER_multihashmap_get_multiple (uig->update_map, &hc,
1019 &find_trees, &fc); 757 &find_trees, &fc);
1020 if (UINT_MAX == fc.id) 758 if (UINT_MAX == fc.id)
1021 { 759 {
1022 /* start new TREE */ 760 /* start new TREE */
1023 for (fc.id = 0; fc.id < fc.tree_array_size; fc.id++) 761 for (fc.id = 0; fc.id < fc.tree_array_size; fc.id++)
1024 { 762 {
1025 if (fc.tree_array[fc.id] == NULL) 763 if (NULL == fc.tree_array[fc.id])
1026 { 764 {
1027 fc.tree_array[fc.id] = nsn; 765 fc.tree_array[fc.id] = nsn;
1028 nsn->tree_id = fc.id; 766 nsn->tree_id = fc.id;
@@ -1041,8 +779,8 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns,
1041 GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc); 779 GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc);
1042 fc.id = nsn->tree_id; 780 fc.id = nsn->tree_id;
1043 fc.nug = nug; 781 fc.nug = nug;
1044 fc.ns = ns; 782 fc.uig = uig;
1045 GNUNET_CONTAINER_multihashmap_get_multiple (ns->update_map, &hc, 783 GNUNET_CONTAINER_multihashmap_get_multiple (uig->update_map, &hc,
1046 &find_trees, &fc); 784 &find_trees, &fc);
1047 } 785 }
1048 else 786 else
@@ -1051,7 +789,8 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns,
1051 fc.tree_array[fc.id] = nsn; 789 fc.tree_array[fc.id] = nsn;
1052 nsn->tree_id = fc.id; 790 nsn->tree_id = fc.id;
1053 } 791 }
1054 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, 792 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
793 "TREE of node `%s' is %u\n", nsn->id,
1055 fc.id); 794 fc.id);
1056 } 795 }
1057 for (i = 0; i < fc.tree_array_size; i++) 796 for (i = 0; i < fc.tree_array_size; i++)
@@ -1066,6 +805,7 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns,
1066 } 805 }
1067 GNUNET_array_grow (fc.tree_array, fc.tree_array_size, 0); 806 GNUNET_array_grow (fc.tree_array, fc.tree_array_size, 0);
1068 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done processing TREEs\n"); 807 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Done processing TREEs\n");
808 free_update_information_graph (uig);
1069} 809}
1070 810
1071 811
diff --git a/src/fs/fs_pseudonym.c b/src/fs/fs_pseudonym.c
index 36eaab6fa..f5493ca16 100644
--- a/src/fs/fs_pseudonym.c
+++ b/src/fs/fs_pseudonym.c
@@ -21,15 +21,10 @@
21 * @file fs/fs_pseudonym.c 21 * @file fs/fs_pseudonym.c
22 * @brief pseudonym functions 22 * @brief pseudonym functions
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 *
25 * TODO:
26 * - all cryptographic operations are currently NOT implemented and
27 * provided by stubs that merely pretend to work!
28 */ 24 */
29#include "platform.h" 25#include "platform.h"
30#include "gnunet_util_lib.h" 26#include "gnunet_util_lib.h"
31#include "gnunet_fs_service.h" 27#include "gnunet_fs_service.h"
32#include <gcrypt.h>
33 28
34 29
35#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) 30#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
@@ -38,12 +33,6 @@
38 33
39#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) 34#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
40 35
41/**
42 * Log an error message at log-level 'level' that indicates
43 * a failure of the command 'cmd' with the message given
44 * by gcry_strerror(rc).
45 */
46#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0);
47 36
48/** 37/**
49 * Name of the directory which stores meta data for pseudonym 38 * Name of the directory which stores meta data for pseudonym
@@ -67,17 +56,17 @@
67/** 56/**
68 * Registered callbacks for discovery of pseudonyms. 57 * Registered callbacks for discovery of pseudonyms.
69 */ 58 */
70struct GNUNET_FS_pseudonym_DiscoveryHandle 59struct GNUNET_FS_Pseudonym_DiscoveryHandle
71{ 60{
72 /** 61 /**
73 * This is a doubly linked list. 62 * This is a doubly linked list.
74 */ 63 */
75 struct GNUNET_FS_pseudonym_DiscoveryHandle *next; 64 struct GNUNET_FS_Pseudonym_DiscoveryHandle *next;
76 65
77 /** 66 /**
78 * This is a doubly linked list. 67 * This is a doubly linked list.
79 */ 68 */
80 struct GNUNET_FS_pseudonym_DiscoveryHandle *prev; 69 struct GNUNET_FS_Pseudonym_DiscoveryHandle *prev;
81 70
82 /** 71 /**
83 * Function to call each time a pseudonym is discovered. 72 * Function to call each time a pseudonym is discovered.
@@ -95,19 +84,14 @@ struct GNUNET_FS_pseudonym_DiscoveryHandle
95 * Head of the linked list of functions to call when 84 * Head of the linked list of functions to call when
96 * new pseudonyms are added. 85 * new pseudonyms are added.
97 */ 86 */
98static struct GNUNET_FS_pseudonym_DiscoveryHandle *disco_head; 87static struct GNUNET_FS_Pseudonym_DiscoveryHandle *disco_head;
99 88
100/** 89/**
101 * Tail of the linked list of functions to call when 90 * Tail of the linked list of functions to call when
102 * new pseudonyms are added. 91 * new pseudonyms are added.
103 */ 92 */
104static struct GNUNET_FS_pseudonym_DiscoveryHandle *disco_tail; 93static struct GNUNET_FS_Pseudonym_DiscoveryHandle *disco_tail;
105 94
106/**
107 * Pointer to indiate 'anonymous' pseudonym (global static,
108 * d=1, public key = G (generator).
109 */
110static struct GNUNET_FS_PseudonymHandle anonymous;
111 95
112/** 96/**
113 * Internal notification about new tracked URI. 97 * Internal notification about new tracked URI.
@@ -117,10 +101,10 @@ static struct GNUNET_FS_PseudonymHandle anonymous;
117 * @param rating rating of pseudonym 101 * @param rating rating of pseudonym
118 */ 102 */
119static void 103static void
120internal_notify (const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 104internal_notify (const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
121 const struct GNUNET_CONTAINER_MetaData *md, int rating) 105 const struct GNUNET_CONTAINER_MetaData *md, int rating)
122{ 106{
123 struct GNUNET_FS_pseudonym_DiscoveryHandle *pos; 107 struct GNUNET_FS_Pseudonym_DiscoveryHandle *pos;
124 108
125 for (pos = disco_head; NULL != pos; pos = pos->next) 109 for (pos = disco_head; NULL != pos; pos = pos->next)
126 pos->callback (pos->callback_cls, pseudonym, NULL, NULL, md, rating); 110 pos->callback (pos->callback_cls, pseudonym, NULL, NULL, md, rating);
@@ -138,15 +122,15 @@ internal_notify (const struct GNUNET_FS_PseudonymIdentifier *pseudonym,
138 * @param iterator_cls point to a closure 122 * @param iterator_cls point to a closure
139 * @return registration handle 123 * @return registration handle
140 */ 124 */
141struct GNUNET_FS_pseudonym_DiscoveryHandle * 125struct GNUNET_FS_Pseudonym_DiscoveryHandle *
142GNUNET_FS_pseudonym_discovery_callback_register (const struct 126GNUNET_FS_pseudonym_discovery_callback_register (const struct
143 GNUNET_CONFIGURATION_Handle *cfg, 127 GNUNET_CONFIGURATION_Handle *cfg,
144 GNUNET_FS_PseudonymIterator iterator, 128 GNUNET_FS_PseudonymIterator iterator,
145 void *iterator_cls) 129 void *iterator_cls)
146{ 130{
147 struct GNUNET_FS_pseudonym_DiscoveryHandle *dh; 131 struct GNUNET_FS_Pseudonym_DiscoveryHandle *dh;
148 132
149 dh = GNUNET_malloc (sizeof (struct GNUNET_FS_pseudonym_DiscoveryHandle)); 133 dh = GNUNET_new (struct GNUNET_FS_Pseudonym_DiscoveryHandle);
150 dh->callback = iterator; 134 dh->callback = iterator;
151 dh->callback_cls = iterator_cls; 135 dh->callback_cls = iterator_cls;
152 GNUNET_CONTAINER_DLL_insert (disco_head, disco_tail, dh); 136 GNUNET_CONTAINER_DLL_insert (disco_head, disco_tail, dh);
@@ -161,7 +145,7 @@ GNUNET_FS_pseudonym_discovery_callback_register (const struct
161 * @param dh registration to unregister 145 * @param dh registration to unregister
162 */ 146 */
163void 147void
164GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_pseudonym_DiscoveryHandle *dh) 148GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_Pseudonym_DiscoveryHandle *dh)
165{ 149{
166 GNUNET_CONTAINER_DLL_remove (disco_head, disco_tail, dh); 150 GNUNET_CONTAINER_DLL_remove (disco_head, disco_tail, dh);
167 GNUNET_free (dh); 151 GNUNET_free (dh);
@@ -180,7 +164,7 @@ GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_pseudonym_Di
180static char * 164static char *
181get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg, 165get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg,
182 const char *prefix, 166 const char *prefix,
183 const struct GNUNET_FS_PseudonymIdentifier *pseudonym) 167 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym)
184{ 168{
185 struct GNUNET_CRYPTO_HashAsciiEncoded enc; 169 struct GNUNET_CRYPTO_HashAsciiEncoded enc;
186 struct GNUNET_HashCode psid; 170 struct GNUNET_HashCode psid;
@@ -188,7 +172,7 @@ get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg,
188 if (NULL != pseudonym) 172 if (NULL != pseudonym)
189 { 173 {
190 GNUNET_CRYPTO_hash (pseudonym, 174 GNUNET_CRYPTO_hash (pseudonym,
191 sizeof (struct GNUNET_FS_PseudonymIdentifier), 175 sizeof (struct GNUNET_CRYPTO_EccPublicKey),
192 &psid); 176 &psid);
193 GNUNET_CRYPTO_hash_to_enc (&psid, &enc); 177 GNUNET_CRYPTO_hash_to_enc (&psid, &enc);
194 } 178 }
@@ -243,7 +227,7 @@ get_data_filename_hash (const struct GNUNET_CONFIGURATION_Handle *cfg,
243 */ 227 */
244int 228int
245GNUNET_FS_pseudonym_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg, 229GNUNET_FS_pseudonym_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
246 const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 230 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
247 const char *name, 231 const char *name,
248 const struct GNUNET_CONTAINER_MetaData *md, 232 const struct GNUNET_CONTAINER_MetaData *md,
249 int32_t rank) 233 int32_t rank)
@@ -258,7 +242,7 @@ GNUNET_FS_pseudonym_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
258 return GNUNET_SYSERR; 242 return GNUNET_SYSERR;
259 } 243 }
260 if ((GNUNET_OK != GNUNET_BIO_write (fileW, pseudonym, 244 if ((GNUNET_OK != GNUNET_BIO_write (fileW, pseudonym,
261 sizeof (struct GNUNET_FS_PseudonymIdentifier))) || 245 sizeof (struct GNUNET_CRYPTO_EccPublicKey))) ||
262 (GNUNET_OK != GNUNET_BIO_write_int32 (fileW, rank)) || 246 (GNUNET_OK != GNUNET_BIO_write_int32 (fileW, rank)) ||
263 (GNUNET_OK != GNUNET_BIO_write_string (fileW, name)) || 247 (GNUNET_OK != GNUNET_BIO_write_string (fileW, name)) ||
264 (GNUNET_OK != GNUNET_BIO_write_meta_data (fileW, md))) 248 (GNUNET_OK != GNUNET_BIO_write_meta_data (fileW, md)))
@@ -295,12 +279,12 @@ GNUNET_FS_pseudonym_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
295 */ 279 */
296static int 280static int
297read_info (const struct GNUNET_CONFIGURATION_Handle *cfg, 281read_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
298 const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 282 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
299 struct GNUNET_CONTAINER_MetaData **meta, 283 struct GNUNET_CONTAINER_MetaData **meta,
300 int32_t *rank, 284 int32_t *rank,
301 char **ns_name) 285 char **ns_name)
302{ 286{
303 struct GNUNET_FS_PseudonymIdentifier pd; 287 struct GNUNET_CRYPTO_EccPublicKey pd;
304 char *fn; 288 char *fn;
305 char *emsg; 289 char *emsg;
306 struct GNUNET_BIO_ReadHandle *fileR; 290 struct GNUNET_BIO_ReadHandle *fileR;
@@ -367,12 +351,12 @@ read_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
367 */ 351 */
368char * 352char *
369GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, 353GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg,
370 const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 354 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
371 const char *name, 355 const char *name,
372 unsigned int *suffix) 356 unsigned int *suffix)
373{ 357{
374 struct GNUNET_HashCode nh; 358 struct GNUNET_HashCode nh;
375 struct GNUNET_FS_PseudonymIdentifier pi; 359 struct GNUNET_CRYPTO_EccPublicKey pi;
376 uint64_t len; 360 uint64_t len;
377 char *fn; 361 char *fn;
378 struct GNUNET_DISK_FileHandle *fh; 362 struct GNUNET_DISK_FileHandle *fh;
@@ -393,11 +377,11 @@ GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg
393 GNUNET_DISK_PERM_USER_WRITE); 377 GNUNET_DISK_PERM_USER_WRITE);
394 i = 0; 378 i = 0;
395 idx = -1; 379 idx = -1;
396 while ((len >= sizeof (struct GNUNET_FS_PseudonymIdentifier)) && 380 while ((len >= sizeof (struct GNUNET_CRYPTO_EccPublicKey)) &&
397 (sizeof (struct GNUNET_FS_PseudonymIdentifier) == 381 (sizeof (struct GNUNET_CRYPTO_EccPublicKey) ==
398 GNUNET_DISK_file_read (fh, &pi, sizeof (struct GNUNET_FS_PseudonymIdentifier)))) 382 GNUNET_DISK_file_read (fh, &pi, sizeof (struct GNUNET_CRYPTO_EccPublicKey))))
399 { 383 {
400 if (0 == memcmp (&pi, pseudonym, sizeof (struct GNUNET_FS_PseudonymIdentifier))) 384 if (0 == memcmp (&pi, pseudonym, sizeof (struct GNUNET_CRYPTO_EccPublicKey)))
401 { 385 {
402 idx = i; 386 idx = i;
403 break; 387 break;
@@ -408,8 +392,8 @@ GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg
408 if (-1 == idx) 392 if (-1 == idx)
409 { 393 {
410 idx = i; 394 idx = i;
411 if (sizeof (struct GNUNET_FS_PseudonymIdentifier) != 395 if (sizeof (struct GNUNET_CRYPTO_EccPublicKey) !=
412 GNUNET_DISK_file_write (fh, pseudonym, sizeof (struct GNUNET_FS_PseudonymIdentifier))) 396 GNUNET_DISK_file_write (fh, pseudonym, sizeof (struct GNUNET_CRYPTO_EccPublicKey)))
413 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "write", fn); 397 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "write", fn);
414 } 398 }
415 GNUNET_DISK_file_close (fh); 399 GNUNET_DISK_file_close (fh);
@@ -442,11 +426,11 @@ GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg
442 */ 426 */
443int 427int
444GNUNET_FS_pseudonym_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, 428GNUNET_FS_pseudonym_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
445 const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 429 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
446 struct GNUNET_CONTAINER_MetaData **ret_meta, 430 struct GNUNET_CONTAINER_MetaData **ret_meta,
447 int32_t *ret_rank, 431 int32_t *ret_rank,
448 char **ret_name, 432 char **ret_name,
449 int *name_is_a_dup) 433 int *name_is_a_dup)
450{ 434{
451 struct GNUNET_CONTAINER_MetaData *meta; 435 struct GNUNET_CONTAINER_MetaData *meta;
452 char *name; 436 char *name;
@@ -521,7 +505,7 @@ GNUNET_FS_pseudonym_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
521int 505int
522GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, 506GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
523 const char *ns_uname, 507 const char *ns_uname,
524 struct GNUNET_FS_PseudonymIdentifier *pseudonym) 508 struct GNUNET_CRYPTO_EccPublicKey *pseudonym)
525{ 509{
526 size_t slen; 510 size_t slen;
527 uint64_t len; 511 uint64_t len;
@@ -546,7 +530,7 @@ GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
546 530
547 if ((GNUNET_OK != GNUNET_DISK_file_test (fn) || 531 if ((GNUNET_OK != GNUNET_DISK_file_test (fn) ||
548 (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES))) || 532 (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES))) ||
549 ((idx + 1) * sizeof (struct GNUNET_FS_PseudonymIdentifier) > len)) 533 ((idx + 1) * sizeof (struct GNUNET_CRYPTO_EccPublicKey) > len))
550 { 534 {
551 GNUNET_free (fn); 535 GNUNET_free (fn);
552 return GNUNET_SYSERR; 536 return GNUNET_SYSERR;
@@ -558,14 +542,14 @@ GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
558 GNUNET_DISK_PERM_USER_WRITE); 542 GNUNET_DISK_PERM_USER_WRITE);
559 GNUNET_free (fn); 543 GNUNET_free (fn);
560 if (GNUNET_SYSERR == 544 if (GNUNET_SYSERR ==
561 GNUNET_DISK_file_seek (fh, idx * sizeof (struct GNUNET_FS_PseudonymIdentifier), 545 GNUNET_DISK_file_seek (fh, idx * sizeof (struct GNUNET_CRYPTO_EccPublicKey),
562 GNUNET_DISK_SEEK_SET)) 546 GNUNET_DISK_SEEK_SET))
563 { 547 {
564 GNUNET_DISK_file_close (fh); 548 GNUNET_DISK_file_close (fh);
565 return GNUNET_SYSERR; 549 return GNUNET_SYSERR;
566 } 550 }
567 if (sizeof (struct GNUNET_FS_PseudonymIdentifier) != 551 if (sizeof (struct GNUNET_CRYPTO_EccPublicKey) !=
568 GNUNET_DISK_file_read (fh, pseudonym, sizeof (struct GNUNET_FS_PseudonymIdentifier))) 552 GNUNET_DISK_file_read (fh, pseudonym, sizeof (struct GNUNET_CRYPTO_EccPublicKey)))
569 { 553 {
570 GNUNET_DISK_file_close (fh); 554 GNUNET_DISK_file_close (fh);
571 return GNUNET_SYSERR; 555 return GNUNET_SYSERR;
@@ -610,7 +594,7 @@ static int
610list_pseudonym_helper (void *cls, const char *fullname) 594list_pseudonym_helper (void *cls, const char *fullname)
611{ 595{
612 struct ListPseudonymClosure *lpc = cls; 596 struct ListPseudonymClosure *lpc = cls;
613 struct GNUNET_FS_PseudonymIdentifier pd; 597 struct GNUNET_CRYPTO_EccPublicKey pd;
614 char *emsg; 598 char *emsg;
615 struct GNUNET_BIO_ReadHandle *fileR; 599 struct GNUNET_BIO_ReadHandle *fileR;
616 int32_t rank; 600 int32_t rank;
@@ -699,7 +683,7 @@ GNUNET_FS_pseudonym_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg,
699 */ 683 */
700int 684int
701GNUNET_FS_pseudonym_rank (const struct GNUNET_CONFIGURATION_Handle *cfg, 685GNUNET_FS_pseudonym_rank (const struct GNUNET_CONFIGURATION_Handle *cfg,
702 const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 686 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
703 int32_t delta) 687 int32_t delta)
704{ 688{
705 struct GNUNET_CONTAINER_MetaData *meta; 689 struct GNUNET_CONTAINER_MetaData *meta;
@@ -734,8 +718,8 @@ GNUNET_FS_pseudonym_rank (const struct GNUNET_CONFIGURATION_Handle *cfg,
734 */ 718 */
735int 719int
736GNUNET_FS_pseudonym_add (const struct GNUNET_CONFIGURATION_Handle *cfg, 720GNUNET_FS_pseudonym_add (const struct GNUNET_CONFIGURATION_Handle *cfg,
737 const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 721 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
738 const struct GNUNET_CONTAINER_MetaData *meta) 722 const struct GNUNET_CONTAINER_MetaData *meta)
739{ 723{
740 char *name; 724 char *name;
741 int32_t rank; 725 int32_t rank;
@@ -766,888 +750,5 @@ GNUNET_FS_pseudonym_add (const struct GNUNET_CONFIGURATION_Handle *cfg,
766} 750}
767 751
768 752
769/* ***************************** cryptographic operations ************************* */
770
771/**
772 * Handle for a pseudonym (private key).
773 */
774struct GNUNET_FS_PseudonymHandle
775{
776 /**
777 * 256-bit 'd' secret value (mod 'n', where n is 256-bit for NIST P-256).
778 */
779 unsigned char d[256 / 8];
780
781 /**
782 * Public key corresponding to the private key.
783 */
784 struct GNUNET_FS_PseudonymIdentifier public_key;
785};
786
787
788/**
789 * If target != size, move target bytes to the end of the size-sized
790 * buffer and zero out the first target-size bytes.
791 *
792 * @param buf original buffer
793 * @param size number of bytes in the buffer
794 * @param target target size of the buffer
795 */
796static void
797adjust (unsigned char *buf, size_t size, size_t target)
798{
799 if (size < target)
800 {
801 memmove (&buf[target - size], buf, size);
802 memset (buf, 0, target - size);
803 }
804}
805
806
807/**
808 * Extract values from an S-expression.
809 *
810 * @param array where to store the result(s)
811 * @param sexp S-expression to parse
812 * @param topname top-level name in the S-expression that is of interest
813 * @param elems names of the elements to extract
814 * @return 0 on success
815 */
816static int
817key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname,
818 const char *elems)
819{
820 gcry_sexp_t list;
821 gcry_sexp_t l2;
822 const char *s;
823 unsigned int i;
824 unsigned int idx;
825
826 if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
827 return 1;
828 l2 = gcry_sexp_cadr (list);
829 gcry_sexp_release (list);
830 list = l2;
831 if (! list)
832 return 2;
833 idx = 0;
834 for (s = elems; *s; s++, idx++)
835 {
836 if (! (l2 = gcry_sexp_find_token (list, s, 1)))
837 {
838 for (i = 0; i < idx; i++)
839 {
840 gcry_free (array[i]);
841 array[i] = NULL;
842 }
843 gcry_sexp_release (list);
844 return 3; /* required parameter not found */
845 }
846 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
847 gcry_sexp_release (l2);
848 if (! array[idx])
849 {
850 for (i = 0; i < idx; i++)
851 {
852 gcry_free (array[i]);
853 array[i] = NULL;
854 }
855 gcry_sexp_release (list);
856 return 4; /* required parameter is invalid */
857 }
858 }
859 gcry_sexp_release (list);
860 return 0;
861}
862
863
864/**
865 * Create a pseudonym.
866 *
867 * @param filename name of the file to use for storage, NULL for in-memory only
868 * @return handle to the private key of the pseudonym
869 */
870struct GNUNET_FS_PseudonymHandle *
871GNUNET_FS_pseudonym_create (const char *filename)
872{
873 struct GNUNET_FS_PseudonymHandle *ph;
874 ssize_t ret;
875 gcry_sexp_t r_key;
876 gcry_sexp_t params;
877 gcry_ctx_t ctx;
878 gcry_mpi_point_t q;
879 gcry_mpi_t q_x;
880 gcry_mpi_t q_y;
881 gcry_error_t rc;
882 gcry_mpi_t d;
883 size_t size;
884
885 ph = GNUNET_malloc (sizeof (struct GNUNET_FS_PseudonymHandle));
886 if ( (NULL != filename) &&
887 (GNUNET_YES == GNUNET_DISK_file_test (filename)) )
888 {
889 ret = GNUNET_DISK_fn_read (filename, ph,
890 sizeof (struct GNUNET_FS_PseudonymHandle));
891 /* Note: we don't do any validation here, maybe we should? */
892 if (sizeof (struct GNUNET_FS_PseudonymHandle) == ret)
893 return ph;
894 }
895 if (0 != (rc = gcry_sexp_build (&params, NULL,
896 "(genkey(ecdsa(curve \"NIST P-256\")))")))
897 {
898 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
899 return NULL;
900 }
901 if (0 != (rc = gcry_pk_genkey (&r_key, params)))
902 {
903 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_genkey", rc);
904 gcry_sexp_release (params);
905 gcry_sexp_release (r_key);
906 return NULL;
907 }
908 gcry_sexp_release (params);
909 /* extract "d" (secret key) from r_key */
910 rc = key_from_sexp (&d, r_key, "private-key", "d");
911 if (0 != rc)
912 rc = key_from_sexp (&d, r_key, "private-key", "d");
913 if (0 != rc)
914 rc = key_from_sexp (&d, r_key, "ecc", "d");
915 if (0 != rc)
916 {
917 gcry_sexp_release (r_key);
918 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "key_from_sexp", rc);
919 return NULL;
920 }
921 size = sizeof (ph->d);
922 GNUNET_assert (0 ==
923 gcry_mpi_print (GCRYMPI_FMT_USG, ph->d, size, &size,
924 d));
925 gcry_mpi_release (d);
926 adjust (ph->d, size, sizeof (ph->d));
927
928 /* extract 'q' (public key) from r_key */
929 if (0 != (rc = gcry_mpi_ec_new (&ctx, r_key, NULL)))
930 {
931 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */
932 gcry_sexp_release (r_key);
933 return NULL;
934 }
935 gcry_sexp_release (r_key);
936 q = gcry_mpi_ec_get_point ("q", ctx, 0);
937 q_x = gcry_mpi_new (256);
938 q_y = gcry_mpi_new (256);
939 gcry_mpi_ec_get_affine (q_x, q_y, q, ctx);
940 gcry_mpi_point_release (q);
941 gcry_ctx_release (ctx);
942
943 /* store q_x/q_y in public key */
944 size = sizeof (ph->public_key.q_x);
945 if (0 !=
946 gcry_mpi_print (GCRYMPI_FMT_USG, ph->public_key.q_x, size, &size,
947 q_x))
948 {
949 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc);
950 gcry_mpi_release (q_x);
951 gcry_mpi_release (q_y);
952 return NULL;
953
954 }
955 adjust (ph->public_key.q_x, size, sizeof (ph->public_key.q_x));
956 gcry_mpi_release (q_x);
957
958 size = sizeof (ph->public_key.q_y);
959 if (0 !=
960 gcry_mpi_print (GCRYMPI_FMT_USG, ph->public_key.q_y, size, &size,
961 q_y))
962 {
963 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc);
964 gcry_mpi_release (q_y);
965 return NULL;
966 }
967 adjust (ph->public_key.q_y, size, sizeof (ph->public_key.q_y));
968 gcry_mpi_release (q_y);
969
970 /* write to disk */
971 if (NULL != filename)
972 {
973 ret = GNUNET_DISK_fn_write (filename, ph, sizeof (struct GNUNET_FS_PseudonymHandle),
974 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
975 if (sizeof (struct GNUNET_FS_PseudonymHandle) != ret)
976 {
977 GNUNET_free (ph);
978 return NULL;
979 }
980 }
981 return ph;
982}
983
984
985/**
986 * Create a pseudonym, from a file that must already exist.
987 *
988 * @param filename name of the file to use for storage, NULL for in-memory only
989 * @return handle to the private key of the pseudonym
990 */
991struct GNUNET_FS_PseudonymHandle *
992GNUNET_FS_pseudonym_create_from_existing_file (const char *filename)
993{
994 struct GNUNET_FS_PseudonymHandle *ph;
995 ssize_t ret;
996
997 ph = GNUNET_malloc (sizeof (struct GNUNET_FS_PseudonymHandle));
998 ret = GNUNET_DISK_fn_read (filename, ph,
999 sizeof (struct GNUNET_FS_PseudonymHandle));
1000 if (sizeof (struct GNUNET_FS_PseudonymHandle) != ret)
1001 {
1002 GNUNET_free (ph);
1003 return NULL;
1004 }
1005 /* Note: we don't do any validation here; maybe we should? */
1006 return ph;
1007}
1008
1009
1010/**
1011 * Get the handle for the 'anonymous' pseudonym shared by all users.
1012 * That pseudonym uses a fixed 'secret' for the private key; this
1013 * construction is useful to make anonymous and pseudonymous APIs
1014 * (and packets) indistinguishable on the network. See #2564.
1015 *
1016 * @return handle to the (non-secret) private key of the 'anonymous' pseudonym
1017 */
1018struct GNUNET_FS_PseudonymHandle *
1019GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle ()
1020{
1021 static int once;
1022 gcry_mpi_t d;
1023 size_t size;
1024 gcry_ctx_t ctx;
1025 int rc;
1026 gcry_mpi_t g_x;
1027 gcry_mpi_t g_y;
1028 gcry_mpi_point_t g;
1029
1030 if (once)
1031 return &anonymous;
1032 d = gcry_mpi_new (1);
1033 gcry_mpi_set_ui (d, 1);
1034 size = sizeof (anonymous.d);
1035 GNUNET_assert (0 ==
1036 gcry_mpi_print (GCRYMPI_FMT_USG, anonymous.d, size, &size,
1037 d));
1038 gcry_mpi_release (d);
1039 adjust (anonymous.d, size, sizeof (anonymous.d));
1040
1041 /* create basic ECC context */
1042 if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256")))
1043 {
1044 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
1045 "gcry_mpi_ec_new", rc);
1046 return NULL;
1047 }
1048
1049 g = gcry_mpi_ec_get_point ("g", ctx, 0);
1050 g_x = gcry_mpi_new (256);
1051 g_y = gcry_mpi_new (256);
1052 gcry_mpi_ec_get_affine (g_x, g_y, g, ctx);
1053 gcry_mpi_point_release (g);
1054 gcry_ctx_release (ctx);
1055
1056 /* store g_x/g_y in public key */
1057 size = sizeof (anonymous.public_key.q_x);
1058 if (0 !=
1059 gcry_mpi_print (GCRYMPI_FMT_USG, anonymous.public_key.q_x, size, &size,
1060 g_x))
1061 {
1062 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc);
1063 gcry_mpi_release (g_x);
1064 gcry_mpi_release (g_y);
1065 return NULL;
1066 }
1067 adjust (anonymous.public_key.q_x, size, sizeof (anonymous.public_key.q_x));
1068 gcry_mpi_release (g_x);
1069
1070 size = sizeof (anonymous.public_key.q_y);
1071 if (0 !=
1072 gcry_mpi_print (GCRYMPI_FMT_USG, anonymous.public_key.q_y, size, &size,
1073 g_y))
1074 {
1075 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc);
1076 gcry_mpi_release (g_y);
1077 return NULL;
1078 }
1079 adjust (anonymous.public_key.q_y, size, sizeof (anonymous.public_key.q_y));
1080 gcry_mpi_release (g_y);
1081
1082 once = 1;
1083 return &anonymous;
1084}
1085
1086
1087/**
1088 * Destroy a pseudonym handle. Does NOT remove the private key from
1089 * the disk.
1090 *
1091 * @param ph pseudonym handle to destroy
1092 */
1093void
1094GNUNET_FS_pseudonym_destroy (struct GNUNET_FS_PseudonymHandle *ph)
1095{
1096 if (&anonymous != ph)
1097 GNUNET_free (ph);
1098}
1099
1100
1101/**
1102 * Convert the data specified in the given purpose argument to an
1103 * S-expression suitable for signature operations.
1104 *
1105 * @param purpose data to convert
1106 * @param rfc6979 GNUNET_YES if we are to use deterministic ECDSA
1107 * @return converted s-expression
1108 */
1109static gcry_sexp_t
1110data_to_pkcs1 (const struct GNUNET_FS_PseudonymSignaturePurpose *purpose,
1111 int rfc6979)
1112{
1113 struct GNUNET_CRYPTO_ShortHashCode hc;
1114 size_t bufSize;
1115 gcry_sexp_t data;
1116 const char *fmt;
1117 int rc;
1118
1119 GNUNET_CRYPTO_short_hash (purpose, ntohl (purpose->size), &hc);
1120 if (rfc6979)
1121 {
1122 if (0 != (rc = gcry_sexp_build (&data, NULL,
1123 "(data(flags rfc6979)(hash %s %b))",
1124 "sha256",
1125 sizeof (hc),
1126 &hc)))
1127 {
1128 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
1129 return NULL;
1130 }
1131 }
1132 else
1133 {
1134 fmt = "(data(flags raw)(5:value32:01234567890123456789012345678901))";
1135 bufSize = strlen (fmt) + 1;
1136 {
1137 char buff[bufSize];
1138
1139 memcpy (buff, fmt, bufSize);
1140 memcpy (&buff
1141 [bufSize -
1142 strlen
1143 ("01234567890123456789012345678901))")
1144 - 1], &hc, sizeof (struct GNUNET_CRYPTO_ShortHashCode));
1145 GNUNET_assert (0 == gcry_sexp_new (&data, buff, bufSize, 0));
1146 }
1147 }
1148 return data;
1149}
1150
1151
1152/**
1153 * Cryptographically sign some data with the pseudonym.
1154 *
1155 * @param ph private key 'd' used for signing (corresponds to 'x' in #2564)
1156 * @param purpose data to sign
1157 * @param seed hash of the plaintext of the data that we are signing,
1158 * used for deterministic PRNG for anonymous signing;
1159 * corresponds to 'k' in section 2.7 of #2564
1160 * @param signing_key modifier to apply to the private key for signing ('h');
1161 * see section 2.3 of #2564.
1162 * @param signature where to store the signature
1163 * @return GNUNET_SYSERR on failure
1164 */
1165int
1166GNUNET_FS_pseudonym_sign (struct GNUNET_FS_PseudonymHandle *ph,
1167 const struct GNUNET_FS_PseudonymSignaturePurpose *purpose,
1168 const struct GNUNET_HashCode *seed,
1169 const struct GNUNET_HashCode *signing_key,
1170 struct GNUNET_FS_PseudonymSignature *signature)
1171{
1172 size_t size;
1173 size_t erroff;
1174 gcry_mpi_t d;
1175 gcry_mpi_t k;
1176 gcry_mpi_t h;
1177 gcry_mpi_t dh;
1178 gcry_mpi_t n; /* n from P-256 */
1179 gcry_sexp_t spriv;
1180 gcry_sexp_t data;
1181 gcry_sexp_t result;
1182 gcry_mpi_t rs[2];
1183 int rc;
1184
1185 /* get private key 'd' from pseudonym */
1186 size = sizeof (ph->d);
1187 if (0 != (rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG,
1188 &ph->d,
1189 size, &size)))
1190 {
1191 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
1192 return GNUNET_SYSERR;
1193 }
1194 /* get 'x' value from signing key */
1195 size = sizeof (struct GNUNET_HashCode);
1196 if (0 != (rc = gcry_mpi_scan (&h, GCRYMPI_FMT_USG,
1197 signing_key,
1198 size, &size)))
1199 {
1200 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
1201 gcry_mpi_release (d);
1202 return GNUNET_SYSERR;
1203 }
1204
1205 /* initialize 'n' from P-256; hex copied from libgcrypt code */
1206 if (0 != (rc = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX,
1207 "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 0, NULL)))
1208 {
1209 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
1210 gcry_mpi_release (d);
1211 gcry_mpi_release (h);
1212 return GNUNET_SYSERR;
1213 }
1214
1215 /* calculate dh = d * h mod n */
1216 dh = gcry_mpi_new (256);
1217 gcry_mpi_mulm (dh, d, h, n);
1218 gcry_mpi_release (d);
1219 gcry_mpi_release (h);
1220 gcry_mpi_release (n);
1221
1222 /* now build sexpression with the signing key */
1223 if (0 != (rc = gcry_sexp_build (&spriv, &erroff,
1224 "(private-key(ecdsa(curve \"NIST P-256\")(d %m)))",
1225 dh)))
1226 {
1227 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
1228 gcry_mpi_release (dh);
1229 return GNUNET_SYSERR;
1230 }
1231 gcry_mpi_release (dh);
1232 /* prepare data for signing */
1233 data = data_to_pkcs1 (purpose, NULL != seed);
1234 if (NULL == data)
1235 {
1236 gcry_sexp_release (spriv);
1237 return GNUNET_SYSERR;
1238 }
1239 /* get 'k' value from seed, if available */
1240 if (NULL != seed)
1241 {
1242 size = sizeof (struct GNUNET_HashCode);
1243 if (0 != (rc = gcry_mpi_scan (&k, GCRYMPI_FMT_USG,
1244 seed,
1245 size, &size)))
1246 {
1247 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
1248 gcry_sexp_release (spriv);
1249 gcry_sexp_release (data);
1250 return GNUNET_SYSERR;
1251 }
1252 }
1253
1254 /* actually create signature */
1255 /* FIXME: need API to pass 'k' if 'seed' was non-NULL! */
1256 if (0 != (rc = gcry_pk_sign (&result, data, spriv)))
1257 {
1258 LOG (GNUNET_ERROR_TYPE_WARNING,
1259 _("ECC signing failed at %s:%d: %s\n"), __FILE__,
1260 __LINE__, gcry_strerror (rc));
1261 gcry_sexp_release (data);
1262 gcry_sexp_release (spriv);
1263 if (NULL != seed)
1264 gcry_mpi_release (k);
1265 memset (signature, 0, sizeof (struct GNUNET_FS_PseudonymSignature));
1266 return GNUNET_SYSERR;
1267 }
1268 if (NULL != seed)
1269 gcry_mpi_release (k);
1270 gcry_sexp_release (data);
1271 gcry_sexp_release (spriv);
1272
1273
1274 /* extract 'r' and 's' values from sexpression 'result' and store in 'signature' */
1275 if (0 != (rc = key_from_sexp (rs, result, "sig-val", "rs")))
1276 {
1277 GNUNET_break (0);
1278 gcry_sexp_release (result);
1279 return GNUNET_SYSERR;
1280 }
1281 gcry_sexp_release (result);
1282 size = sizeof (signature->sig_r);
1283 if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, signature->sig_r, size,
1284 &size, rs[0])))
1285 {
1286 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc);
1287 gcry_mpi_release (rs[0]);
1288 gcry_mpi_release (rs[1]);
1289 return GNUNET_SYSERR;
1290 }
1291 adjust (signature->sig_r, size, sizeof (signature->sig_r));
1292 gcry_mpi_release (rs[0]);
1293
1294 size = sizeof (signature->sig_s);
1295 if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, signature->sig_s, size,
1296 &size, rs[1])))
1297 {
1298 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc);
1299 gcry_mpi_release (rs[1]);
1300 return GNUNET_SYSERR;
1301 }
1302 adjust (signature->sig_s, size, sizeof (signature->sig_s));
1303 gcry_mpi_release (rs[1]);
1304
1305#if EXTRA_CHECKS
1306 {
1307 struct GNUNET_FS_PseudonymIdentifier vk;
1308 struct GNUNET_FS_PseudonymIdentifier pi;
1309
1310 GNUNET_FS_pseudonym_get_identifier (ph, &pi);
1311 GNUNET_assert (GNUNET_OK ==
1312 GNUNET_FS_pseudonym_derive_verification_key (&pi, signing_key, &vk));
1313 GNUNET_assert (GNUNET_OK ==
1314 GNUNET_FS_pseudonym_verify (purpose,
1315 signature,
1316 &vk));
1317 }
1318#endif
1319
1320 GNUNET_FS_pseudonym_get_identifier (ph, &signature->signer);
1321 return GNUNET_OK;
1322}
1323
1324
1325/**
1326 * Get an ECC context (with Q set to the respective public key) from
1327 * a pseudonym.
1328 *
1329 * @param pseudonym with information on 'q'
1330 * @return curve context
1331 */
1332static gcry_ctx_t
1333get_context_from_pseudonym (struct GNUNET_FS_PseudonymIdentifier *pseudonym)
1334{
1335 static struct GNUNET_FS_PseudonymIdentifier zerop;
1336 gcry_ctx_t ctx;
1337 gcry_mpi_t q_x;
1338 gcry_mpi_t q_y;
1339 gcry_mpi_t zero;
1340 gcry_mpi_point_t q;
1341 size_t size;
1342 int rc;
1343
1344 /* extract 'q' from pseudonym */
1345 if (0 == memcmp (pseudonym, &zerop, sizeof (zerop)))
1346 {
1347 /* create basic ECC context */
1348 if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256")))
1349 {
1350 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */
1351 return NULL;
1352 }
1353 /* FIXME: initialize 'ctx' with 'q' = G */
1354 zero = gcry_mpi_new (0);
1355 gcry_mpi_set_ui (zero, 0);
1356 q = gcry_mpi_point_new (0);
1357 gcry_mpi_point_set (q, zero, zero, zero);
1358 gcry_mpi_ec_set_point ("q", q, ctx);
1359 gcry_mpi_release (zero);
1360 gcry_mpi_point_release (q);
1361 return ctx;
1362 }
1363 size = sizeof (pseudonym->q_x);
1364 if (0 != (rc = gcry_mpi_scan (&q_x, GCRYMPI_FMT_USG, pseudonym->q_x, size, &size)))
1365 {
1366 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
1367 return NULL;
1368 }
1369 size = sizeof (pseudonym->q_y);
1370 if (0 != (rc = gcry_mpi_scan (&q_y, GCRYMPI_FMT_USG, pseudonym->q_y, size, &size)))
1371 {
1372 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
1373 gcry_mpi_release (q_x);
1374 return NULL;
1375 }
1376 q = gcry_mpi_point_new (256);
1377 gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE);
1378 gcry_mpi_release (q_x);
1379 gcry_mpi_release (q_y);
1380
1381 /* create basic ECC context */
1382 if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256")))
1383 {
1384 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */
1385 gcry_mpi_point_release (q);
1386 return NULL;
1387 }
1388 /* initialize 'ctx' with 'q' */
1389 gcry_mpi_ec_set_point ("q", q, ctx);
1390 gcry_mpi_point_release (q);
1391 return ctx;
1392}
1393
1394
1395/**
1396 * Given a pseudonym and a signing key, derive the corresponding public
1397 * key that would be used to verify the resulting signature.
1398 *
1399 * @param pseudonym the public key (dQ in ECDSA)
1400 * @param signing_key input to derive 'h' (see section 2.4 of #2564)
1401 * @param verification_key resulting public key to verify the signature
1402 * created from the '(d*h)' of 'pseudonym' and the 'signing_key';
1403 * the value stored here can then be given to GNUNET_FS_pseudonym_verify.
1404 * @return GNUNET_OK on success, GNUNET_SYSERR on error
1405 */
1406int
1407GNUNET_FS_pseudonym_derive_verification_key (struct GNUNET_FS_PseudonymIdentifier *pseudonym,
1408 const struct GNUNET_HashCode *signing_key,
1409 struct GNUNET_FS_PseudonymIdentifier *verification_key)
1410{
1411 gcry_mpi_t h;
1412 size_t size;
1413 int rc;
1414 gcry_ctx_t ctx;
1415 gcry_mpi_point_t q;
1416 gcry_mpi_point_t v;
1417 gcry_mpi_t v_x;
1418 gcry_mpi_t v_y;
1419 gcry_mpi_t h_mod_n;
1420 gcry_mpi_t n; /* n from P-256 */
1421
1422 /* get 'h' value from signing key */
1423 size = sizeof (struct GNUNET_HashCode);
1424 if (0 != (rc = gcry_mpi_scan (&h, GCRYMPI_FMT_USG,
1425 signing_key,
1426 size, &size)))
1427 {
1428 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
1429 return GNUNET_SYSERR;
1430 }
1431 /* create ECC context based on Q from pseudonym */
1432 if (NULL == (ctx = get_context_from_pseudonym (pseudonym)))
1433 {
1434 gcry_mpi_release (h);
1435 return GNUNET_SYSERR;
1436 }
1437 /* initialize 'n' from P-256; hex copied from libgcrypt code */
1438 if (0 != (rc = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX,
1439 "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 0, NULL)))
1440 {
1441 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
1442 gcry_mpi_release (h);
1443 return GNUNET_SYSERR;
1444 }
1445 h_mod_n = gcry_mpi_new (0);
1446 gcry_mpi_mod (h_mod_n, h, n);
1447 gcry_mpi_release (h);
1448
1449 /* get Q = dG from 'pseudonym' */
1450 q = gcry_mpi_ec_get_point ("q", ctx, 0);
1451 /* calculate V = hQ = hdG */
1452 v = gcry_mpi_point_new (0);
1453
1454 gcry_mpi_ec_mul (v, h_mod_n, q, ctx);
1455 gcry_mpi_release (h_mod_n);
1456
1457 /* store 'v' point in "verification_key" */
1458 v_x = gcry_mpi_new (256);
1459 v_y = gcry_mpi_new (256);
1460 gcry_mpi_ec_get_affine (v_x, v_y, v, ctx);
1461
1462 gcry_mpi_point_release (v);
1463 gcry_ctx_release (ctx);
1464
1465 size = sizeof (verification_key->q_x);
1466 if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, verification_key->q_x, size,
1467 &size, v_x)))
1468 {
1469 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc);
1470 gcry_mpi_release (v_x);
1471 gcry_mpi_release (v_y);
1472 return GNUNET_SYSERR;
1473 }
1474 gcry_mpi_release (v_x);
1475 size = sizeof (verification_key->q_y);
1476 if (0 != (rc = gcry_mpi_print (GCRYMPI_FMT_USG, verification_key->q_y, size,
1477 &size, v_y)))
1478 {
1479 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc);
1480 gcry_mpi_release (v_y);
1481 return GNUNET_SYSERR;
1482 }
1483 gcry_mpi_release (v_y);
1484 return GNUNET_OK;
1485}
1486
1487
1488/**
1489 * Verify a signature made with a pseudonym.
1490 *
1491 * @param purpose data that was signed
1492 * @param signature signature to verify
1493 * @param verification_key public key to use for checking the signature;
1494 * corresponds to 'g^(x+h)' in section 2.4 of #2564.
1495 * @return GNUNET_OK on success (signature valid, 'pseudonym' set),
1496 * GNUNET_SYSERR if the signature is invalid
1497 */
1498int
1499GNUNET_FS_pseudonym_verify (const struct GNUNET_FS_PseudonymSignaturePurpose *purpose,
1500 const struct GNUNET_FS_PseudonymSignature *signature,
1501 const struct GNUNET_FS_PseudonymIdentifier *verification_key)
1502{
1503 gcry_sexp_t data;
1504 gcry_sexp_t sig_sexpr;
1505 gcry_sexp_t pk_sexpr;
1506 size_t size;
1507 gcry_ctx_t ctx;
1508 gcry_mpi_t r;
1509 gcry_mpi_t s;
1510 gcry_mpi_point_t q;
1511 gcry_mpi_t q_x;
1512 gcry_mpi_t q_y;
1513 size_t erroff;
1514 int rc;
1515
1516 /* build s-expression for signature */
1517 size = sizeof (signature->sig_r);
1518 if (0 != (rc = gcry_mpi_scan (&r, GCRYMPI_FMT_USG,
1519 signature->sig_r, size, &size)))
1520 {
1521 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
1522 return GNUNET_SYSERR;
1523 }
1524 size = sizeof (signature->sig_s);
1525 if (0 != (rc = gcry_mpi_scan (&s, GCRYMPI_FMT_USG,
1526 signature->sig_s, size, &size)))
1527 {
1528 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
1529 gcry_mpi_release (r);
1530 return GNUNET_SYSERR;
1531 }
1532 if (0 != (rc = gcry_sexp_build (&sig_sexpr, &erroff, "(sig-val(ecdsa(r %m)(s %m)))",
1533 r, s)))
1534 {
1535 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
1536 gcry_mpi_release (r);
1537 gcry_mpi_release (s);
1538 return GNUNET_SYSERR;
1539 }
1540 gcry_mpi_release (r);
1541 gcry_mpi_release (s);
1542
1543
1544 /* build s-expression for data that was signed */
1545 data = data_to_pkcs1 (purpose, GNUNET_NO);
1546 if (NULL == data)
1547 {
1548 gcry_sexp_release (sig_sexpr);
1549 return GNUNET_SYSERR;
1550 }
1551 /* create context of public key and initialize Q */
1552 size = sizeof (verification_key->q_x);
1553 if (0 != (rc = gcry_mpi_scan (&q_x, GCRYMPI_FMT_USG,
1554 verification_key->q_x, size, &size)))
1555 {
1556 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
1557 gcry_sexp_release (data);
1558 gcry_sexp_release (sig_sexpr);
1559 return GNUNET_SYSERR;
1560 }
1561 size = sizeof (verification_key->q_y);
1562 if (0 != (rc = gcry_mpi_scan (&q_y, GCRYMPI_FMT_USG,
1563 verification_key->q_y, size, &size)))
1564 {
1565 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
1566 gcry_sexp_release (data);
1567 gcry_sexp_release (sig_sexpr);
1568 gcry_mpi_release (q_x);
1569 return GNUNET_SYSERR;
1570 }
1571 q = gcry_mpi_point_new (256);
1572 gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE);
1573 gcry_mpi_release (q_x);
1574 gcry_mpi_release (q_y);
1575
1576 /* create basic ECC context */
1577 if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256")))
1578 {
1579 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */
1580 gcry_sexp_release (data);
1581 gcry_sexp_release (sig_sexpr);
1582 gcry_mpi_point_release (q);
1583 return GNUNET_SYSERR;
1584 }
1585 /* initialize 'ctx' with 'q' */
1586 gcry_mpi_ec_set_point ("q", q, ctx);
1587 gcry_mpi_point_release (q);
1588
1589 /* convert 'ctx' to 'sexp' */
1590 if (0 != (rc = gcry_pubkey_get_sexp (&pk_sexpr, GCRY_PK_GET_PUBKEY, ctx)))
1591 {
1592 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_from_context", rc);
1593 gcry_ctx_release (ctx);
1594 gcry_sexp_release (data);
1595 gcry_sexp_release (sig_sexpr);
1596 return GNUNET_SYSERR;
1597 }
1598 gcry_ctx_release (ctx);
1599
1600 /* finally, verify the signature */
1601 rc = gcry_pk_verify (sig_sexpr, data, pk_sexpr);
1602 gcry_sexp_release (sig_sexpr);
1603 gcry_sexp_release (data);
1604 gcry_sexp_release (pk_sexpr);
1605 if (rc)
1606 {
1607 LOG (GNUNET_ERROR_TYPE_WARNING,
1608 _("ECDSA signature verification failed at %s:%d: %s\n"), __FILE__,
1609 __LINE__, gcry_strerror (rc));
1610 return GNUNET_SYSERR;
1611 }
1612 return GNUNET_OK;
1613}
1614
1615
1616/**
1617 * Get the identifier (public key) of a pseudonym.
1618 *
1619 * @param ph pseudonym handle with the private key
1620 * @param pseudonym pseudonym identifier (set based on 'ph')
1621 */
1622void
1623GNUNET_FS_pseudonym_get_identifier (struct GNUNET_FS_PseudonymHandle *ph,
1624 struct GNUNET_FS_PseudonymIdentifier *pseudonym)
1625{
1626 memcpy (pseudonym, &ph->public_key,
1627 sizeof (struct GNUNET_FS_PseudonymIdentifier));
1628}
1629
1630
1631/**
1632 * Remove pseudonym from the set of known pseudonyms.
1633 *
1634 * @param cfg overall configuration
1635 * @param id the pseudonym identifier
1636 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
1637 */
1638int
1639GNUNET_FS_pseudonym_remove (const struct GNUNET_CONFIGURATION_Handle *cfg,
1640 const struct GNUNET_FS_PseudonymIdentifier *id)
1641{
1642 char *fn;
1643 int result;
1644
1645 fn = get_data_filename (cfg, PS_METADATA_DIR, id);
1646 if (NULL == fn)
1647 return GNUNET_SYSERR;
1648 result = UNLINK (fn);
1649 GNUNET_free (fn);
1650 return (0 == result) ? GNUNET_OK : GNUNET_SYSERR;
1651}
1652 753
1653/* end of pseudonym.c */ 754/* end of pseudonym.c */
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c
index 041d4213c..1ed37d7e4 100644
--- a/src/fs/fs_publish.c
+++ b/src/fs/fs_publish.c
@@ -84,11 +84,6 @@ publish_cleanup (struct GNUNET_FS_PublishContext *pc)
84 pc->fhc = NULL; 84 pc->fhc = NULL;
85 } 85 }
86 GNUNET_FS_file_information_destroy (pc->fi, NULL, NULL); 86 GNUNET_FS_file_information_destroy (pc->fi, NULL, NULL);
87 if (pc->ns != NULL)
88 {
89 GNUNET_FS_namespace_delete (pc->ns, GNUNET_NO);
90 pc->ns = NULL;
91 }
92 GNUNET_free_non_null (pc->nid); 87 GNUNET_free_non_null (pc->nid);
93 GNUNET_free_non_null (pc->nuid); 88 GNUNET_free_non_null (pc->nuid);
94 GNUNET_free_non_null (pc->serialization); 89 GNUNET_free_non_null (pc->serialization);
@@ -271,9 +266,15 @@ static void
271publish_sblock (struct GNUNET_FS_PublishContext *pc) 266publish_sblock (struct GNUNET_FS_PublishContext *pc)
272{ 267{
273 if (NULL != pc->ns) 268 if (NULL != pc->ns)
274 pc->sks_pc = GNUNET_FS_publish_sks (pc->h, pc->ns, pc->nid, pc->nuid, 269 pc->sks_pc = GNUNET_FS_publish_sks (pc->h,
275 pc->fi->meta, pc->fi->chk_uri, &pc->fi->bo, 270 pc->ns,
276 pc->options, &publish_sblocks_cont, pc); 271 pc->nid,
272 pc->nuid,
273 pc->fi->meta,
274 pc->fi->chk_uri,
275 &pc->fi->bo,
276 pc->options,
277 &publish_sblocks_cont, pc);
277 else 278 else
278 publish_sblocks_cont (pc, NULL, NULL); 279 publish_sblocks_cont (pc, NULL, NULL);
279} 280}
@@ -1117,7 +1118,8 @@ finish_reserve (void *cls, int success,
1117struct GNUNET_FS_PublishContext * 1118struct GNUNET_FS_PublishContext *
1118GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h, 1119GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h,
1119 struct GNUNET_FS_FileInformation *fi, 1120 struct GNUNET_FS_FileInformation *fi,
1120 struct GNUNET_FS_Namespace *ns, const char *nid, 1121 const struct GNUNET_CRYPTO_EccPrivateKey *ns,
1122 const char *nid,
1121 const char *nuid, 1123 const char *nuid,
1122 enum GNUNET_FS_PublishOptions options) 1124 enum GNUNET_FS_PublishOptions options)
1123{ 1125{
@@ -1135,20 +1137,20 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h,
1135 { 1137 {
1136 dsh = NULL; 1138 dsh = NULL;
1137 } 1139 }
1138 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishContext)); 1140 ret = GNUNET_new (struct GNUNET_FS_PublishContext);
1139 ret->dsh = dsh; 1141 ret->dsh = dsh;
1140 ret->h = h; 1142 ret->h = h;
1141 ret->fi = fi; 1143 ret->fi = fi;
1142 ret->ns = ns; 1144 if (NULL != ns)
1143 ret->options = options;
1144 if (ns != NULL)
1145 { 1145 {
1146 ns->rc++; 1146 ret->ns = GNUNET_new (struct GNUNET_CRYPTO_EccPrivateKey);
1147 *ret->ns = *ns;
1147 GNUNET_assert (NULL != nid); 1148 GNUNET_assert (NULL != nid);
1148 ret->nid = GNUNET_strdup (nid); 1149 ret->nid = GNUNET_strdup (nid);
1149 if (NULL != nuid) 1150 if (NULL != nuid)
1150 ret->nuid = GNUNET_strdup (nuid); 1151 ret->nuid = GNUNET_strdup (nuid);
1151 } 1152 }
1153 ret->options = options;
1152 /* signal start */ 1154 /* signal start */
1153 GNUNET_FS_file_information_inspect (ret->fi, &fip_signal_start, ret); 1155 GNUNET_FS_file_information_inspect (ret->fi, &fip_signal_start, ret);
1154 ret->fi_pos = ret->fi; 1156 ret->fi_pos = ret->fi;
diff --git a/src/fs/fs_publish_ksk.c b/src/fs/fs_publish_ksk.c
index 10512af5f..7cbc880a2 100644
--- a/src/fs/fs_publish_ksk.c
+++ b/src/fs/fs_publish_ksk.c
@@ -33,7 +33,7 @@
33#include "gnunet_fs_service.h" 33#include "gnunet_fs_service.h"
34#include "fs_api.h" 34#include "fs_api.h"
35#include "fs_tree.h" 35#include "fs_tree.h"
36 36#include "fs_publish_ublock.h"
37 37
38/** 38/**
39 * Context for the KSK publication. 39 * Context for the KSK publication.
@@ -47,33 +47,29 @@ struct GNUNET_FS_PublishKskContext
47 struct GNUNET_FS_Uri *ksk_uri; 47 struct GNUNET_FS_Uri *ksk_uri;
48 48
49 /** 49 /**
50 * Global FS context. 50 * URI to publish.
51 */ 51 */
52 struct GNUNET_FS_Handle *h; 52 struct GNUNET_FS_Uri *uri;
53 53
54 /** 54 /**
55 * The master block that we are sending 55 * Metadata to use.
56 * (in plaintext), has "mdsize+slen" more
57 * bytes than the struct would suggest.
58 */ 56 */
59 struct UBlock *ub; 57 struct GNUNET_CONTAINER_MetaData *meta;
60 58
61 /** 59 /**
62 * Buffer of the same size as "kb" for 60 * Global FS context.
63 * the encrypted version.
64 */ 61 */
65 struct UBlock *cpy; 62 struct GNUNET_FS_Handle *h;
66 63
67 /** 64 /**
68 * Handle to the datastore, NULL if we are just 65 * UBlock publishing operation that is active.
69 * simulating.
70 */ 66 */
71 struct GNUNET_DATASTORE_Handle *dsh; 67 struct GNUNET_FS_PublishUblockContext *uc;
72 68
73 /** 69 /**
74 * Handle to datastore PUT request. 70 * Handle to the datastore, NULL if we are just simulating.
75 */ 71 */
76 struct GNUNET_DATASTORE_QueueEntry *qre; 72 struct GNUNET_DATASTORE_Handle *dsh;
77 73
78 /** 74 /**
79 * Current task. 75 * Current task.
@@ -96,14 +92,9 @@ struct GNUNET_FS_PublishKskContext
96 struct GNUNET_FS_BlockOptions bo; 92 struct GNUNET_FS_BlockOptions bo;
97 93
98 /** 94 /**
99 * Size of the serialized metadata. 95 * Options to use.
100 */ 96 */
101 ssize_t mdsize; 97 enum GNUNET_FS_PublishOptions options;
102
103 /**
104 * Size of the (CHK) URI as a string.
105 */
106 size_t slen;
107 98
108 /** 99 /**
109 * Keyword that we are currently processing. 100 * Keyword that we are currently processing.
@@ -122,7 +113,8 @@ struct GNUNET_FS_PublishKskContext
122 * @param tc unused 113 * @param tc unused
123 */ 114 */
124static void 115static void
125publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 116publish_ksk_cont (void *cls,
117 const struct GNUNET_SCHEDULER_TaskContext *tc);
126 118
127 119
128/** 120/**
@@ -130,19 +122,16 @@ publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
130 * the result from the PUT request. 122 * the result from the PUT request.
131 * 123 *
132 * @param cls closure of type "struct GNUNET_FS_PublishKskContext*" 124 * @param cls closure of type "struct GNUNET_FS_PublishKskContext*"
133 * @param success GNUNET_OK on success
134 * @param min_expiration minimum expiration time required for content to be stored
135 * @param msg error message (or NULL) 125 * @param msg error message (or NULL)
136 */ 126 */
137static void 127static void
138kb_put_cont (void *cls, int success, 128kb_put_cont (void *cls,
139 struct GNUNET_TIME_Absolute min_expiration,
140 const char *msg) 129 const char *msg)
141{ 130{
142 struct GNUNET_FS_PublishKskContext *pkc = cls; 131 struct GNUNET_FS_PublishKskContext *pkc = cls;
143 132
144 pkc->qre = NULL; 133 pkc->uc = NULL;
145 if (GNUNET_OK != success) 134 if (NULL != msg)
146 { 135 {
147 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
148 "KBlock PUT operation failed: %s\n", msg); 137 "KBlock PUT operation failed: %s\n", msg);
@@ -166,15 +155,6 @@ publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
166{ 155{
167 struct GNUNET_FS_PublishKskContext *pkc = cls; 156 struct GNUNET_FS_PublishKskContext *pkc = cls;
168 const char *keyword; 157 const char *keyword;
169 struct GNUNET_HashCode key;
170 struct GNUNET_HashCode seed;
171 struct GNUNET_HashCode signing_key;
172 struct GNUNET_HashCode query;
173 struct GNUNET_CRYPTO_AesSessionKey skey;
174 struct GNUNET_CRYPTO_AesInitializationVector iv;
175 struct GNUNET_FS_PseudonymHandle *ph;
176 struct GNUNET_FS_PseudonymIdentifier pseudonym;
177 struct UBlock *ub_dst;
178 158
179 pkc->ksk_task = GNUNET_SCHEDULER_NO_TASK; 159 pkc->ksk_task = GNUNET_SCHEDULER_NO_TASK;
180 if ( (pkc->i == pkc->ksk_uri->data.ksk.keywordCount) || 160 if ( (pkc->i == pkc->ksk_uri->data.ksk.keywordCount) ||
@@ -186,61 +166,15 @@ publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
186 return; 166 return;
187 } 167 }
188 keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++]; 168 keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++];
189 pkc->sks_task = GNUNET_FS_publish_sks (pkc->h, 169 pkc->uc = GNUNET_FS_publish_ublock_ (pkc->h,
190 anonymous, 170 pkc->dsh,
191 keyword, NULL, 171 keyword, NULL,
192 pkc->meta, 172 GNUNET_CRYPTO_ecc_key_get_anonymous (),
193 pkc->uri, 173 pkc->meta,
194 &pkc->bo, 174 pkc->uri,
195 pkc->options, 175 &pkc->bo,
196 &publish_ksk_cont, pkc); 176 pkc->options,
197 177 &kb_put_cont, pkc);
198
199 /* derive signing seed from plaintext */
200 GNUNET_CRYPTO_hash (&pkc->ub[1],
201 1 + pkc->slen + pkc->mdsize,
202 &seed);
203 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing under keyword `%s'\n",
204 &keyword[1]);
205 /* first character of keyword indicates if it is
206 * mandatory or not -- ignore for hashing */
207 GNUNET_CRYPTO_hash (&keyword[1], strlen (&keyword[1]), &key);
208
209 GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv);
210 ub_dst = pkc->cpy;
211 GNUNET_CRYPTO_aes_encrypt (&pkc->ub[1],
212 1 + pkc->slen + pkc->mdsize,
213 &skey, &iv,
214 &ub_dst[1]);
215 ph = GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle ();
216 GNUNET_CRYPTO_hash (&key, sizeof (key), &signing_key);
217 ub_dst->purpose.size = htonl (1 + pkc->slen + pkc->mdsize +
218 sizeof (struct UBlock)
219 - sizeof (struct GNUNET_FS_PseudonymSignature));
220 ub_dst->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK);
221
222 GNUNET_FS_pseudonym_get_identifier (ph, &pseudonym);
223 GNUNET_FS_pseudonym_derive_verification_key (&pseudonym,
224 &signing_key,
225 &ub_dst->verification_key);
226 GNUNET_FS_pseudonym_sign (ph,
227 &ub_dst->purpose,
228 &seed,
229 &signing_key,
230 &ub_dst->signature);
231
232 GNUNET_CRYPTO_hash (&ub_dst->verification_key,
233 sizeof (ub_dst->verification_key),
234 &query);
235 GNUNET_FS_pseudonym_destroy (ph);
236 pkc->qre =
237 GNUNET_DATASTORE_put (pkc->dsh, 0, &query,
238 1 + pkc->slen + pkc->mdsize + sizeof (struct UBlock),
239 ub_dst, GNUNET_BLOCK_TYPE_FS_UBLOCK,
240 pkc->bo.content_priority, pkc->bo.anonymity_level,
241 pkc->bo.replication_level, pkc->bo.expiration_time,
242 -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT,
243 &kb_put_cont, pkc);
244} 178}
245 179
246 180
@@ -267,17 +201,15 @@ GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h,
267 GNUNET_FS_PublishContinuation cont, void *cont_cls) 201 GNUNET_FS_PublishContinuation cont, void *cont_cls)
268{ 202{
269 struct GNUNET_FS_PublishKskContext *pkc; 203 struct GNUNET_FS_PublishKskContext *pkc;
270 char *uris;
271 size_t size;
272 char *kbe;
273 char *sptr;
274 204
275 GNUNET_assert (NULL != uri); 205 GNUNET_assert (NULL != uri);
276 pkc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishKskContext)); 206 pkc = GNUNET_new (struct GNUNET_FS_PublishKskContext);
277 pkc->h = h; 207 pkc->h = h;
278 pkc->bo = *bo; 208 pkc->bo = *bo;
209 pkc->options = options;
279 pkc->cont = cont; 210 pkc->cont = cont;
280 pkc->cont_cls = cont_cls; 211 pkc->cont_cls = cont_cls;
212 pkc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
281 if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) 213 if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
282 { 214 {
283 pkc->dsh = GNUNET_DATASTORE_connect (h->cfg); 215 pkc->dsh = GNUNET_DATASTORE_connect (h->cfg);
@@ -288,44 +220,7 @@ GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h,
288 return NULL; 220 return NULL;
289 } 221 }
290 } 222 }
291 if (meta == NULL) 223 pkc->uri = GNUNET_FS_uri_dup (uri);
292 pkc->mdsize = 0;
293 else
294 pkc->mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
295 GNUNET_assert (pkc->mdsize >= 0);
296 uris = GNUNET_FS_uri_to_string (uri);
297 pkc->slen = strlen (uris) + 1;
298 size = pkc->mdsize + sizeof (struct UBlock) + pkc->slen + 1;
299 if (size > MAX_UBLOCK_SIZE)
300 {
301 size = MAX_UBLOCK_SIZE;
302 pkc->mdsize = size - sizeof (struct UBlock) - pkc->slen + 1;
303 }
304 pkc->ub = GNUNET_malloc (size);
305 kbe = (char *) &pkc->ub[1];
306 kbe++; /* leave one '\0' for the update identifier */
307 memcpy (kbe, uris, pkc->slen);
308 GNUNET_free (uris);
309 sptr = &kbe[pkc->slen];
310 if (meta != NULL)
311 pkc->mdsize =
312 GNUNET_CONTAINER_meta_data_serialize (meta, &sptr, pkc->mdsize,
313 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
314 if (-1 == pkc->mdsize)
315 {
316 GNUNET_break (0);
317 GNUNET_free (pkc->ub);
318 if (NULL != pkc->dsh)
319 {
320 GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
321 pkc->dsh = NULL;
322 }
323 GNUNET_free (pkc);
324 cont (cont_cls, NULL, _("Internal error."));
325 return NULL;
326 }
327 size = sizeof (struct UBlock) + pkc->slen + pkc->mdsize + 1;
328 pkc->cpy = GNUNET_malloc (size);
329 pkc->ksk_uri = GNUNET_FS_uri_dup (ksk_uri); 224 pkc->ksk_uri = GNUNET_FS_uri_dup (ksk_uri);
330 pkc->ksk_task = GNUNET_SCHEDULER_add_now (&publish_ksk_cont, pkc); 225 pkc->ksk_task = GNUNET_SCHEDULER_add_now (&publish_ksk_cont, pkc);
331 return pkc; 226 return pkc;
@@ -345,19 +240,19 @@ GNUNET_FS_publish_ksk_cancel (struct GNUNET_FS_PublishKskContext *pkc)
345 GNUNET_SCHEDULER_cancel (pkc->ksk_task); 240 GNUNET_SCHEDULER_cancel (pkc->ksk_task);
346 pkc->ksk_task = GNUNET_SCHEDULER_NO_TASK; 241 pkc->ksk_task = GNUNET_SCHEDULER_NO_TASK;
347 } 242 }
348 if (NULL != pkc->qre) 243 if (NULL != pkc->uc)
349 { 244 {
350 GNUNET_DATASTORE_cancel (pkc->qre); 245 GNUNET_FS_publish_ublock_cancel_ (pkc->uc);
351 pkc->qre = NULL; 246 pkc->uc = NULL;
352 } 247 }
353 if (NULL != pkc->dsh) 248 if (NULL != pkc->dsh)
354 { 249 {
355 GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO); 250 GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
356 pkc->dsh = NULL; 251 pkc->dsh = NULL;
357 } 252 }
358 GNUNET_free (pkc->cpy); 253 GNUNET_CONTAINER_meta_data_destroy (pkc->meta);
359 GNUNET_free (pkc->ub);
360 GNUNET_FS_uri_destroy (pkc->ksk_uri); 254 GNUNET_FS_uri_destroy (pkc->ksk_uri);
255 GNUNET_FS_uri_destroy (pkc->uri);
361 GNUNET_free (pkc); 256 GNUNET_free (pkc);
362} 257}
363 258
diff --git a/src/fs/fs_publish_ublock.c b/src/fs/fs_publish_ublock.c
new file mode 100644
index 000000000..9ddff0655
--- /dev/null
+++ b/src/fs/fs_publish_ublock.c
@@ -0,0 +1,262 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009, 2010, 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file fs/fs_publish_ublock.c
23 * @brief publish a UBLOCK in GNUnet
24 * @see https://gnunet.org/encoding and #2564
25 * @author Krista Bennett
26 * @author Christian Grothoff
27 */
28#include "platform.h"
29#include "gnunet_constants.h"
30#include "gnunet_signatures.h"
31#include "fs_publish_ublock.h"
32#include "fs_api.h"
33#include "fs_tree.h"
34
35
36/**
37 * Decrypt the given UBlock, storing the result in output.
38 *
39 * @param input input data
40 * @param input_len number of bytes in input
41 * @param ns public key under which the UBlock was stored
42 * @param label label under which the UBlock was stored
43 * @param output where to write the result, has input_len bytes
44 */
45void
46GNUNET_FS_ublock_decrypt_ (const void *input,
47 size_t input_len,
48 const struct GNUNET_CRYPTO_EccPublicKey *ns,
49 const char *label,
50 void *output)
51{
52 GNUNET_break (0);
53}
54
55
56/**
57 * Context for 'ublock_put_cont'.
58 */
59struct GNUNET_FS_PublishUblockContext
60{
61
62 /**
63 * Function to call when done.
64 */
65 GNUNET_FS_UBlockContinuation cont;
66
67 /**
68 * Closure of 'cont'.
69 */
70 void *cont_cls;
71
72 /**
73 * Handle for active datastore operation.
74 */
75 struct GNUNET_DATASTORE_QueueEntry *qre;
76};
77
78
79/**
80 * Continuation of "GNUNET_FS_publish_ublock_".
81 *
82 * @param cls closure of type "struct GNUNET_FS_PublishUblockContext*"
83 * @param success GNUNET_SYSERR on failure (including timeout/queue drop)
84 * GNUNET_NO if content was already there
85 * GNUNET_YES (or other positive value) on success
86 * @param min_expiration minimum expiration time required for 0-priority content to be stored
87 * by the datacache at this time, zero for unknown, forever if we have no
88 * space for 0-priority content
89 * @param msg NULL on success, otherwise an error message
90 */
91static void
92ublock_put_cont (void *cls,
93 int32_t success,
94 struct GNUNET_TIME_Absolute min_expiration,
95 const char *msg)
96{
97 struct GNUNET_FS_PublishUblockContext *uc = cls;
98
99 uc->qre = NULL;
100 uc->cont (uc->cont_cls, msg);
101 GNUNET_free (uc);
102}
103
104
105/**
106 * Publish a UBlock.
107 *
108 * @param h handle to the file sharing subsystem
109 * @param dsh datastore handle to use for storage operation
110 * @param label identifier to use
111 * @param ulabel update label to use, may be an empty string for none
112 * @param ns namespace to publish in
113 * @param meta metadata to use
114 * @param uri URI to refer to in the UBlock
115 * @param bo per-block options
116 * @param options publication options
117 * @param cont continuation
118 * @param cont_cls closure for cont
119 * @return NULL on error ('cont' will still be called)
120 */
121struct GNUNET_FS_PublishUblockContext *
122GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h,
123 struct GNUNET_DATASTORE_Handle *dsh,
124 const char *label,
125 const char *ulabel,
126 const struct GNUNET_CRYPTO_EccPrivateKey *ns,
127 const struct GNUNET_CONTAINER_MetaData *meta,
128 const struct GNUNET_FS_Uri *uri,
129 const struct GNUNET_FS_BlockOptions *bo,
130 enum GNUNET_FS_PublishOptions options,
131 GNUNET_FS_UBlockContinuation cont, void *cont_cls)
132{
133 struct GNUNET_FS_PublishUblockContext *uc;
134 struct GNUNET_HashCode key;
135 struct GNUNET_HashCode seed;
136 struct GNUNET_HashCode signing_key;
137 struct GNUNET_HashCode query;
138 struct GNUNET_CRYPTO_AesSessionKey skey;
139 struct GNUNET_CRYPTO_AesInitializationVector iv;
140 struct GNUNET_CRYPTO_EccPrivateKey *nsd;
141 struct GNUNET_CRYPTO_EccPublicKey pub;
142 char *uris;
143 size_t size;
144 char *kbe;
145 char *sptr;
146 ssize_t mdsize;
147 size_t slen;
148 size_t ulen;
149 struct UBlock *ub_plain;
150 struct UBlock *ub_enc;
151
152 /* compute ublock to publish */
153 if (NULL == meta)
154 mdsize = 0;
155 else
156 mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
157 GNUNET_assert (mdsize >= 0);
158 uris = GNUNET_FS_uri_to_string (uri);
159 slen = strlen (uris) + 1;
160 ulen = strlen (ulabel) + 1;
161 size = mdsize + sizeof (struct UBlock) + slen + ulen;
162 if (size > MAX_UBLOCK_SIZE)
163 {
164 size = MAX_UBLOCK_SIZE;
165 mdsize = size - sizeof (struct UBlock) - (slen + ulen);
166 }
167 ub_plain = GNUNET_malloc (size);
168 kbe = (char *) &ub_plain[1];
169 memcpy (kbe, ulabel, ulen);
170 kbe += ulen;
171 memcpy (kbe, uris, slen);
172 kbe += slen;
173 GNUNET_free (uris);
174 sptr = kbe;
175 if (NULL != meta)
176 mdsize =
177 GNUNET_CONTAINER_meta_data_serialize (meta, &sptr, mdsize,
178 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
179 if (-1 == mdsize)
180 {
181 GNUNET_break (0);
182 GNUNET_free (ub_plain);
183 cont (cont_cls, _("Internal error."));
184 return NULL;
185 }
186 size = sizeof (struct UBlock) + slen + mdsize + ulen;
187
188 /* derive signing seed from plaintext */
189 GNUNET_CRYPTO_hash (&ub_plain[1],
190 ulen + slen + mdsize,
191 &seed);
192 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
193 "Publishing under identifier `%s'\n",
194 label);
195 /* get public key of the namespace */
196 GNUNET_CRYPTO_ecc_key_get_public (ns,
197 &pub);
198 /* derive key from 'label' and public key of the namespace */
199 GNUNET_assert (GNUNET_YES ==
200 GNUNET_CRYPTO_kdf (&key, sizeof (key),
201 "UBLOCK-ENC", strlen ("UBLOCK-ENC"),
202 label, strlen (label),
203 &pub, sizeof (pub),
204 NULL, 0));
205 GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv);
206
207 /* encrypt ublock */
208 ub_enc = GNUNET_malloc (size);
209 GNUNET_CRYPTO_aes_encrypt (&ub_plain[1],
210 ulen + slen + mdsize,
211 &skey, &iv,
212 &ub_enc[1]);
213 ub_enc->purpose.size = htonl (ulen + slen + mdsize +
214 sizeof (struct UBlock)
215 - sizeof (struct GNUNET_CRYPTO_EccSignature));
216 ub_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK);
217
218 /* derive signing-key from 'label' and public key of the namespace */
219 GNUNET_assert (GNUNET_YES ==
220 GNUNET_CRYPTO_kdf (&signing_key, sizeof (signing_key),
221 "UBLOCK-SIGN", strlen ("UBLOCK-SIGN"),
222 label, strlen (label),
223 &pub, sizeof (pub),
224 NULL, 0));
225 nsd = GNUNET_CRYPTO_ecc_key_derive (ns, label);
226 GNUNET_CRYPTO_ecc_key_get_public (nsd,
227 &ub_enc->verification_key);
228 GNUNET_assert (GNUNET_OK ==
229 GNUNET_CRYPTO_ecc_sign (nsd,
230 &ub_enc->purpose,
231 &ub_enc->signature));
232 GNUNET_CRYPTO_hash (&ub_enc->verification_key,
233 sizeof (ub_enc->verification_key),
234 &query);
235 GNUNET_CRYPTO_ecc_key_free (nsd);
236
237 uc = GNUNET_new (struct GNUNET_FS_PublishUblockContext);
238 uc->cont = cont;
239 uc->cont_cls = cont_cls;
240 uc->qre =
241 GNUNET_DATASTORE_put (dsh, 0, &query,
242 ulen + slen + mdsize + sizeof (struct UBlock),
243 ub_enc, GNUNET_BLOCK_TYPE_FS_UBLOCK,
244 bo->content_priority, bo->anonymity_level,
245 bo->replication_level, bo->expiration_time,
246 -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT,
247 &ublock_put_cont, uc);
248 return uc;
249}
250
251
252/**
253 * Abort UBlock publishing operation.
254 *
255 * @param uc operation to abort.
256 */
257void
258GNUNET_FS_publish_ublock_cancel_ (struct GNUNET_FS_PublishUblockContext *uc)
259{
260 GNUNET_DATASTORE_cancel (uc->qre);
261 GNUNET_free (uc);
262}
diff --git a/src/fs/fs_publish_ublock.h b/src/fs/fs_publish_ublock.h
new file mode 100644
index 000000000..9a2db54ac
--- /dev/null
+++ b/src/fs/fs_publish_ublock.h
@@ -0,0 +1,108 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009, 2010, 2012, 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file fs/fs_publish_ublock.h
23 * @brief publish a UBLOCK in GNUnet
24 * @see https://gnunet.org/encoding and #2564
25 * @author Krista Bennett
26 * @author Christian Grothoff
27 */
28#ifndef FS_PUBLISH_UBLOCK_H
29#define FS_PUBLISH_UBLOCK_H
30
31#include "gnunet_util_lib.h"
32#include "gnunet_datastore_service.h"
33#include "gnunet_fs_service.h"
34#include "gnunet_identity_service.h"
35
36
37/**
38 * Decrypt the given UBlock, storing the result in output.
39 *
40 * @param input input data
41 * @param input_len number of bytes in input
42 * @param ns public key under which the UBlock was stored
43 * @param label label under which the UBlock was stored
44 * @param output where to write the result, has input_len bytes
45 */
46void
47GNUNET_FS_ublock_decrypt_ (const void *input,
48 size_t input_len,
49 const struct GNUNET_CRYPTO_EccPublicKey *ns,
50 const char *label,
51 void *output);
52
53
54/**
55 * Context for 'ublock_put_cont'.
56 */
57struct GNUNET_FS_PublishUblockContext;
58
59
60/**
61 * Signature of a function called as the continuation of a UBlock
62 * publication.
63 *
64 * @param cls closure
65 * @param emsg error message, NULL on success
66 */
67typedef void (*GNUNET_FS_UBlockContinuation) (void *cls,
68 const char *emsg);
69
70
71/**
72 * Publish a UBlock.
73 *
74 * @param h handle to the file sharing subsystem
75 * @param dsh datastore handle to use for storage operation
76 * @param label identifier to use
77 * @param ulabel update label to use, may be an empty string for none
78 * @param ns namespace to publish in
79 * @param meta metadata to use
80 * @param uri URI to refer to in the UBlock
81 * @param bo per-block options
82 * @param options publication options
83 * @param cont continuation
84 * @param cont_cls closure for cont
85 * @return NULL on error ('cont' will still be called)
86 */
87struct GNUNET_FS_PublishUblockContext *
88GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h,
89 struct GNUNET_DATASTORE_Handle *dsh,
90 const char *label,
91 const char *ulabel,
92 const struct GNUNET_CRYPTO_EccPrivateKey *ns,
93 const struct GNUNET_CONTAINER_MetaData *meta,
94 const struct GNUNET_FS_Uri *uri,
95 const struct GNUNET_FS_BlockOptions *bo,
96 enum GNUNET_FS_PublishOptions options,
97 GNUNET_FS_UBlockContinuation cont, void *cont_cls);
98
99
100/**
101 * Abort UBlock publishing operation.
102 *
103 * @param uc operation to abort.
104 */
105void
106GNUNET_FS_publish_ublock_cancel_ (struct GNUNET_FS_PublishUblockContext *uc);
107
108#endif
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c
index 10627753a..3b0db0429 100644
--- a/src/fs/fs_search.c
+++ b/src/fs/fs_search.c
@@ -27,6 +27,7 @@
27#include "gnunet_fs_service.h" 27#include "gnunet_fs_service.h"
28#include "gnunet_protocols.h" 28#include "gnunet_protocols.h"
29#include "fs_api.h" 29#include "fs_api.h"
30#include "fs_publish_ublock.h"
30 31
31 32
32/** 33/**
@@ -669,7 +670,7 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc, const char *id_update,
669 * given ciphertext block. 670 * given ciphertext block.
670 * 671 *
671 * @param sc search context with the keywords 672 * @param sc search context with the keywords
672 * @param verification_key public key to use to lookup the keyword 673 * @param dpub derived public key used for the search
673 * @param edata encrypted data 674 * @param edata encrypted data
674 * @param edata_size number of bytes in 'edata' (and 'data') 675 * @param edata_size number of bytes in 'edata' (and 'data')
675 * @param data where to store the plaintext 676 * @param data where to store the plaintext
@@ -678,22 +679,20 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc, const char *id_update,
678 */ 679 */
679static int 680static int
680decrypt_block_with_keyword (const struct GNUNET_FS_SearchContext *sc, 681decrypt_block_with_keyword (const struct GNUNET_FS_SearchContext *sc,
681 const struct GNUNET_FS_PseudonymIdentifier *verification_key, 682 const struct GNUNET_CRYPTO_EccPublicKey *dpub,
682 const void *edata, 683 const void *edata,
683 size_t edata_size, 684 size_t edata_size,
684 char *data) 685 char *data)
685{ 686{
686 struct GNUNET_HashCode q; 687 const struct GNUNET_CRYPTO_EccPrivateKey *anon;
687 struct GNUNET_CRYPTO_AesSessionKey skey; 688 struct GNUNET_CRYPTO_EccPublicKey anon_pub;
688 struct GNUNET_CRYPTO_AesInitializationVector iv; 689 unsigned int i;
689 int i;
690 690
691 GNUNET_CRYPTO_hash (verification_key,
692 sizeof (struct GNUNET_FS_PseudonymIdentifier),
693 &q);
694 /* find key */ 691 /* find key */
695 for (i = 0; i < sc->uri->data.ksk.keywordCount; i++) 692 for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
696 if (0 == memcmp (&q, &sc->requests[i].uquery, sizeof (struct GNUNET_HashCode))) 693 if (0 == memcmp (dpub,
694 &sc->requests[i].dpub,
695 sizeof (struct GNUNET_CRYPTO_EccPublicKey)))
697 break; 696 break;
698 if (i == sc->uri->data.ksk.keywordCount) 697 if (i == sc->uri->data.ksk.keywordCount)
699 { 698 {
@@ -702,14 +701,12 @@ decrypt_block_with_keyword (const struct GNUNET_FS_SearchContext *sc,
702 return GNUNET_SYSERR; 701 return GNUNET_SYSERR;
703 } 702 }
704 /* decrypt */ 703 /* decrypt */
705 GNUNET_CRYPTO_hash_to_aes_key (&sc->requests[i].ukey, &skey, &iv); 704 anon = GNUNET_CRYPTO_ecc_key_get_anonymous ();
706 if (-1 == 705 GNUNET_CRYPTO_ecc_key_get_public (anon, &anon_pub);
707 GNUNET_CRYPTO_aes_decrypt (edata, edata_size, &skey, 706 GNUNET_FS_ublock_decrypt_ (edata, edata_size,
708 &iv, data)) 707 &anon_pub,
709 { 708 sc->requests[i].keyword,
710 GNUNET_break (0); 709 data);
711 return GNUNET_SYSERR;
712 }
713 return i; 710 return i;
714} 711}
715 712
@@ -789,31 +786,18 @@ process_sblock (struct GNUNET_FS_SearchContext *sc,
789{ 786{
790 size_t len = size - sizeof (struct UBlock); 787 size_t len = size - sizeof (struct UBlock);
791 char pt[len]; 788 char pt[len];
792 struct GNUNET_CRYPTO_AesSessionKey skey;
793 struct GNUNET_CRYPTO_AesInitializationVector iv;
794 struct GNUNET_FS_Uri *uri; 789 struct GNUNET_FS_Uri *uri;
795 struct GNUNET_CONTAINER_MetaData *meta; 790 struct GNUNET_CONTAINER_MetaData *meta;
796 const char *id; 791 const char *id;
797 const char *uris; 792 const char *uris;
798 size_t off; 793 size_t off;
799 char *emsg; 794 char *emsg;
800 struct GNUNET_HashCode key;
801 struct GNUNET_HashCode id_hash;
802 struct GNUNET_HashCode ns_hash;
803 char *identifier;
804 795
805 /* decrypt */ 796 /* decrypt */
806 identifier = sc->uri->data.sks.identifier; 797 GNUNET_FS_ublock_decrypt_ (&ub[1], len,
807 GNUNET_CRYPTO_hash (identifier, strlen (identifier), &id_hash); 798 &sc->uri->data.sks.ns,
808 GNUNET_CRYPTO_hash (&sc->uri->data.sks.ns, 799 sc->uri->data.sks.identifier,
809 sizeof (sc->uri->data.sks.ns), &ns_hash); 800 pt);
810 GNUNET_CRYPTO_hash_xor (&id_hash, &ns_hash, &key);
811 GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv);
812 if (-1 == GNUNET_CRYPTO_aes_decrypt (&ub[1], len, &skey, &iv, pt))
813 {
814 GNUNET_break (0);
815 return;
816 }
817 /* parse */ 801 /* parse */
818 if (0 == (off = GNUNET_STRINGS_buffer_tokenize (pt, len, 2, &id, &uris))) 802 if (0 == (off = GNUNET_STRINGS_buffer_tokenize (pt, len, 2, &id, &uris)))
819 { 803 {
@@ -1050,12 +1034,7 @@ transmit_search_request (void *cls, size_t size, void *buf)
1050 struct MessageBuilderContext mbc; 1034 struct MessageBuilderContext mbc;
1051 size_t msize; 1035 size_t msize;
1052 struct SearchMessage *sm; 1036 struct SearchMessage *sm;
1053 const char *identifier; 1037 struct GNUNET_CRYPTO_EccPublicKey dpub;
1054 struct GNUNET_HashCode key;
1055 struct GNUNET_HashCode signing_key;
1056 struct GNUNET_HashCode ns_hash;
1057 struct GNUNET_HashCode id_hash;
1058 struct GNUNET_FS_PseudonymIdentifier verification_key;
1059 unsigned int sqms; 1038 unsigned int sqms;
1060 uint32_t options; 1039 uint32_t options;
1061 1040
@@ -1122,18 +1101,11 @@ transmit_search_request (void *cls, size_t size, void *buf)
1122 sm->type = htonl (GNUNET_BLOCK_TYPE_FS_UBLOCK); 1101 sm->type = htonl (GNUNET_BLOCK_TYPE_FS_UBLOCK);
1123 sm->anonymity_level = htonl (sc->anonymity); 1102 sm->anonymity_level = htonl (sc->anonymity);
1124 memset (&sm->target, 0, sizeof (struct GNUNET_HashCode)); 1103 memset (&sm->target, 0, sizeof (struct GNUNET_HashCode));
1125 1104 GNUNET_CRYPTO_ecc_public_key_derive (&sc->uri->data.sks.ns,
1126 identifier = sc->uri->data.sks.identifier; 1105 sc->uri->data.sks.identifier,
1127 GNUNET_CRYPTO_hash (identifier, strlen (identifier), &id_hash); 1106 &dpub);
1128 GNUNET_CRYPTO_hash (&sc->uri->data.sks.ns, 1107 GNUNET_CRYPTO_hash (&dpub,
1129 sizeof (sc->uri->data.sks.ns), &ns_hash); 1108 sizeof (dpub),
1130 GNUNET_CRYPTO_hash_xor (&id_hash, &ns_hash, &key);
1131 GNUNET_CRYPTO_hash (&key, sizeof (struct GNUNET_HashCode), &signing_key);
1132 GNUNET_FS_pseudonym_derive_verification_key (&sc->uri->data.sks.ns,
1133 &signing_key,
1134 &verification_key);
1135 GNUNET_CRYPTO_hash (&verification_key,
1136 sizeof (verification_key),
1137 &sm->query); 1109 &sm->query);
1138 mbc.put_cnt = (size - msize) / sizeof (struct GNUNET_HashCode); 1110 mbc.put_cnt = (size - msize) / sizeof (struct GNUNET_HashCode);
1139 sqms = GNUNET_CONTAINER_multihashmap_size (sc->master_result_map); 1111 sqms = GNUNET_CONTAINER_multihashmap_size (sc->master_result_map);
@@ -1297,35 +1269,34 @@ GNUNET_FS_search_start_searching_ (struct GNUNET_FS_SearchContext *sc)
1297{ 1269{
1298 unsigned int i; 1270 unsigned int i;
1299 const char *keyword; 1271 const char *keyword;
1300 struct GNUNET_HashCode signing_key; 1272 const struct GNUNET_CRYPTO_EccPrivateKey *anon;
1301 struct GNUNET_FS_PseudonymHandle *ph; 1273 struct GNUNET_CRYPTO_EccPublicKey anon_pub;
1302 struct GNUNET_FS_PseudonymIdentifier anon; 1274 struct SearchRequestEntry *sre;
1303 struct GNUNET_FS_PseudonymIdentifier verification_key;
1304 1275
1305 GNUNET_assert (NULL == sc->client); 1276 GNUNET_assert (NULL == sc->client);
1306 if (GNUNET_FS_uri_test_ksk (sc->uri)) 1277 if (GNUNET_FS_uri_test_ksk (sc->uri))
1307 { 1278 {
1308 GNUNET_assert (0 != sc->uri->data.ksk.keywordCount); 1279 GNUNET_assert (0 != sc->uri->data.ksk.keywordCount);
1309 ph = GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle (); 1280 anon = GNUNET_CRYPTO_ecc_key_get_anonymous ();
1310 GNUNET_FS_pseudonym_get_identifier (ph, &anon); 1281 GNUNET_CRYPTO_ecc_key_get_public (anon, &anon_pub);
1311 GNUNET_FS_pseudonym_destroy (ph);
1312 sc->requests = 1282 sc->requests =
1313 GNUNET_malloc (sizeof (struct SearchRequestEntry) * 1283 GNUNET_malloc (sizeof (struct SearchRequestEntry) *
1314 sc->uri->data.ksk.keywordCount); 1284 sc->uri->data.ksk.keywordCount);
1315 for (i = 0; i < sc->uri->data.ksk.keywordCount; i++) 1285 for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1316 { 1286 {
1317 keyword = &sc->uri->data.ksk.keywords[i][1]; 1287 keyword = &sc->uri->data.ksk.keywords[i][1];
1318 GNUNET_CRYPTO_hash (keyword, strlen (keyword), &sc->requests[i].ukey); 1288 sre = &sc->requests[i];
1319 GNUNET_CRYPTO_hash (&sc->requests[i].ukey, sizeof (struct GNUNET_HashCode), &signing_key); 1289 sre->keyword = GNUNET_strdup (keyword);
1320 GNUNET_FS_pseudonym_derive_verification_key (&anon, 1290 GNUNET_CRYPTO_ecc_public_key_derive (&anon_pub,
1321 &signing_key, 1291 keyword,
1322 &verification_key); 1292 &sre->dpub);
1323 GNUNET_CRYPTO_hash (&verification_key, sizeof (struct GNUNET_FS_PseudonymIdentifier), 1293 GNUNET_CRYPTO_hash (&sre->dpub,
1324 &sc->requests[i].uquery); 1294 sizeof (struct GNUNET_CRYPTO_EccPublicKey),
1325 sc->requests[i].mandatory = (sc->uri->data.ksk.keywords[i][0] == '+'); 1295 &sre->uquery);
1326 if (sc->requests[i].mandatory) 1296 sre->mandatory = (sc->uri->data.ksk.keywords[i][0] == '+');
1297 if (sre->mandatory)
1327 sc->mandatory_count++; 1298 sc->mandatory_count++;
1328 sc->requests[i].results = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO); 1299 sre->results = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
1329 } 1300 }
1330 } 1301 }
1331 sc->client = GNUNET_CLIENT_connect ("fs", sc->h->cfg); 1302 sc->client = GNUNET_CLIENT_connect ("fs", sc->h->cfg);
@@ -1475,7 +1446,10 @@ GNUNET_FS_search_signal_suspend_ (void *cls)
1475 { 1446 {
1476 GNUNET_assert (GNUNET_FS_uri_test_ksk (sc->uri)); 1447 GNUNET_assert (GNUNET_FS_uri_test_ksk (sc->uri));
1477 for (i = 0; i < sc->uri->data.ksk.keywordCount; i++) 1448 for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
1449 {
1478 GNUNET_CONTAINER_multihashmap_destroy (sc->requests[i].results); 1450 GNUNET_CONTAINER_multihashmap_destroy (sc->requests[i].results);
1451 GNUNET_free (sc->requests[i].keyword);
1452 }
1479 } 1453 }
1480 GNUNET_free_non_null (sc->requests); 1454 GNUNET_free_non_null (sc->requests);
1481 GNUNET_free_non_null (sc->emsg); 1455 GNUNET_free_non_null (sc->emsg);
diff --git a/src/fs/fs_unindex.c b/src/fs/fs_unindex.c
index 132109c59..cfe73d617 100644
--- a/src/fs/fs_unindex.c
+++ b/src/fs/fs_unindex.c
@@ -553,10 +553,9 @@ void
553GNUNET_FS_unindex_do_remove_kblocks_ (struct GNUNET_FS_UnindexContext *uc) 553GNUNET_FS_unindex_do_remove_kblocks_ (struct GNUNET_FS_UnindexContext *uc)
554{ 554{
555 const char *keyword; 555 const char *keyword;
556 struct GNUNET_FS_PseudonymHandle *ph; 556 const struct GNUNET_CRYPTO_EccPrivateKey *anon;
557 struct GNUNET_FS_PseudonymIdentifier anon; 557 struct GNUNET_CRYPTO_EccPublicKey anon_pub;
558 struct GNUNET_FS_PseudonymIdentifier verification_key; 558 struct GNUNET_CRYPTO_EccPublicKey dpub;
559 struct GNUNET_HashCode signing_key;
560 559
561 if (NULL == uc->dsh) 560 if (NULL == uc->dsh)
562 uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg); 561 uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg);
@@ -574,18 +573,14 @@ GNUNET_FS_unindex_do_remove_kblocks_ (struct GNUNET_FS_UnindexContext *uc)
574 unindex_finish (uc); 573 unindex_finish (uc);
575 return; 574 return;
576 } 575 }
577 /* FIXME: code duplication with fs_search.c here... */ 576 anon = GNUNET_CRYPTO_ecc_key_get_anonymous ();
578 ph = GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle (); 577 GNUNET_CRYPTO_ecc_key_get_public (anon, &anon_pub);
579 GNUNET_FS_pseudonym_get_identifier (ph, &anon);
580 GNUNET_FS_pseudonym_destroy (ph);
581 keyword = &uc->ksk_uri->data.ksk.keywords[uc->ksk_offset][1]; 578 keyword = &uc->ksk_uri->data.ksk.keywords[uc->ksk_offset][1];
582 GNUNET_CRYPTO_hash (keyword, strlen (keyword), &uc->ukey); 579 GNUNET_CRYPTO_ecc_public_key_derive (&anon_pub,
583 GNUNET_CRYPTO_hash (&uc->ukey, sizeof (struct GNUNET_HashCode), &signing_key); 580 keyword,
584 GNUNET_FS_pseudonym_derive_verification_key (&anon, 581 &dpub);
585 &signing_key, 582 GNUNET_CRYPTO_hash (&dpub,
586 &verification_key); 583 sizeof (dpub),
587 GNUNET_CRYPTO_hash (&verification_key,
588 sizeof (struct GNUNET_FS_PseudonymIdentifier),
589 &uc->uquery); 584 &uc->uquery);
590 uc->first_uid = 0; 585 uc->first_uid = 0;
591 uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh, 586 uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh,
diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c
index 78b5459fd..e0bdc7ed6 100644
--- a/src/fs/fs_uri.c
+++ b/src/fs/fs_uri.c
@@ -95,10 +95,11 @@
95 * into HashMaps. The key may change between FS implementations. 95 * into HashMaps. The key may change between FS implementations.
96 * 96 *
97 * @param uri uri to convert to a unique key 97 * @param uri uri to convert to a unique key
98 * @param key wherer to store the unique key 98 * @param key where to store the unique key
99 */ 99 */
100void 100void
101GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri, struct GNUNET_HashCode * key) 101GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri,
102 struct GNUNET_HashCode *key)
102{ 103{
103 switch (uri->type) 104 switch (uri->type)
104 { 105 {
@@ -144,7 +145,7 @@ GNUNET_FS_uri_ksk_to_string_fancy (const struct GNUNET_FS_Uri *uri)
144 char **keywords; 145 char **keywords;
145 unsigned int keywordCount; 146 unsigned int keywordCount;
146 147
147 if ((uri == NULL) || (uri->type != GNUNET_FS_URI_KSK)) 148 if ((NULL == uri) || (GNUNET_FS_URI_KSK != uri->type))
148 { 149 {
149 GNUNET_break (0); 150 GNUNET_break (0);
150 return NULL; 151 return NULL;
@@ -269,7 +270,7 @@ uri_ksk_parse (const char *s, char **emsg)
269 char *dup; 270 char *dup;
270 int saw_quote; 271 int saw_quote;
271 272
272 GNUNET_assert (s != NULL); 273 GNUNET_assert (NULL != s);
273 slen = strlen (s); 274 slen = strlen (s);
274 pos = strlen (GNUNET_FS_URI_KSK_PREFIX); 275 pos = strlen (GNUNET_FS_URI_KSK_PREFIX);
275 if ((slen <= pos) || (0 != strncmp (s, GNUNET_FS_URI_KSK_PREFIX, pos))) 276 if ((slen <= pos) || (0 != strncmp (s, GNUNET_FS_URI_KSK_PREFIX, pos)))
@@ -329,7 +330,7 @@ uri_ksk_parse (const char *s, char **emsg)
329 goto CLEANUP; 330 goto CLEANUP;
330 GNUNET_assert (max == 0); 331 GNUNET_assert (max == 0);
331 GNUNET_free (dup); 332 GNUNET_free (dup);
332 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); 333 ret = GNUNET_new (struct GNUNET_FS_Uri);
333 ret->type = GNUNET_FS_URI_KSK; 334 ret->type = GNUNET_FS_URI_KSK;
334 ret->data.ksk.keywordCount = iret; 335 ret->data.ksk.keywordCount = iret;
335 ret->data.ksk.keywords = keywords; 336 ret->data.ksk.keywords = keywords;
@@ -356,7 +357,7 @@ static struct GNUNET_FS_Uri *
356uri_sks_parse (const char *s, char **emsg) 357uri_sks_parse (const char *s, char **emsg)
357{ 358{
358 struct GNUNET_FS_Uri *ret; 359 struct GNUNET_FS_Uri *ret;
359 struct GNUNET_FS_PseudonymIdentifier id; 360 struct GNUNET_CRYPTO_EccPublicKey ns;
360 size_t pos; 361 size_t pos;
361 char *end; 362 char *end;
362 363
@@ -369,16 +370,16 @@ uri_sks_parse (const char *s, char **emsg)
369 (GNUNET_OK != 370 (GNUNET_OK !=
370 GNUNET_STRINGS_string_to_data (&s[pos], 371 GNUNET_STRINGS_string_to_data (&s[pos],
371 end - &s[pos], 372 end - &s[pos],
372 &id, 373 &ns,
373 sizeof (id))) ) 374 sizeof (ns))) )
374 { 375 {
375 *emsg = GNUNET_strdup (_("Malformed SKS URI")); 376 *emsg = GNUNET_strdup (_("Malformed SKS URI"));
376 return NULL; /* malformed */ 377 return NULL; /* malformed */
377 } 378 }
378 end++; /* skip over '/' */ 379 end++; /* skip over '/' */
379 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); 380 ret = GNUNET_new (struct GNUNET_FS_Uri);
380 ret->type = GNUNET_FS_URI_SKS; 381 ret->type = GNUNET_FS_URI_SKS;
381 ret->data.sks.ns = id; 382 ret->data.sks.ns = ns;
382 ret->data.sks.identifier = GNUNET_strdup (end); 383 ret->data.sks.identifier = GNUNET_strdup (end);
383 return ret; 384 return ret;
384} 385}
@@ -434,7 +435,7 @@ uri_chk_parse (const char *s, char **emsg)
434 return NULL; 435 return NULL;
435 } 436 }
436 fi.file_length = GNUNET_htonll (flen); 437 fi.file_length = GNUNET_htonll (flen);
437 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); 438 ret = GNUNET_new (struct GNUNET_FS_Uri);
438 ret->type = GNUNET_FS_URI_CHK; 439 ret->type = GNUNET_FS_URI_CHK;
439 ret->data.chk = fi; 440 ret->data.chk = fi;
440 return ret; 441 return ret;
@@ -505,24 +506,36 @@ enc2bin (const char *input, void *data, size_t size)
505} 506}
506 507
507 508
509GNUNET_NETWORK_STRUCT_BEGIN
508/** 510/**
509 * Structure that defines how the 511 * Structure that defines how the contents of a location URI must be
510 * contents of a location URI must be 512 * assembled in memory to create or verify the signature of a location
511 * assembled in memory to create or
512 * verify the signature of a location
513 * URI. 513 * URI.
514 */ 514 */
515struct LocUriAssembly 515struct LocUriAssembly
516{ 516{
517 /**
518 * What is being signed (rest of this struct).
519 */
517 struct GNUNET_CRYPTO_EccSignaturePurpose purpose; 520 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
518 521
522 /**
523 * Expiration time of the offer.
524 */
519 struct GNUNET_TIME_AbsoluteNBO exptime; 525 struct GNUNET_TIME_AbsoluteNBO exptime;
520 526
527 /**
528 * File being offered.
529 */
521 struct FileIdentifier fi; 530 struct FileIdentifier fi;
522 531
532 /**
533 * Peer offering the file.
534 */
523 struct GNUNET_CRYPTO_EccPublicKey peer; 535 struct GNUNET_CRYPTO_EccPublicKey peer;
524 536
525}; 537};
538GNUNET_NETWORK_STRUCT_END
526 539
527 540
528#define GNUNET_FS_URI_LOC_PREFIX GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX 541#define GNUNET_FS_URI_LOC_PREFIX GNUNET_FS_URI_PREFIX GNUNET_FS_URI_LOC_INFIX
@@ -635,7 +648,7 @@ uri_loc_parse (const char *s, char **emsg)
635 GNUNET_strdup (_("SKS URI malformed (signature failed validation)")); 648 GNUNET_strdup (_("SKS URI malformed (signature failed validation)"));
636 goto ERR; 649 goto ERR;
637 } 650 }
638 uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); 651 uri = GNUNET_new (struct GNUNET_FS_Uri);
639 uri->type = GNUNET_FS_URI_LOC; 652 uri->type = GNUNET_FS_URI_LOC;
640 uri->data.loc.fi = ass.fi; 653 uri->data.loc.fi = ass.fi;
641 uri->data.loc.peer = ass.peer; 654 uri->data.loc.peer = ass.peer;
@@ -862,7 +875,7 @@ GNUNET_FS_uri_loc_get_uri (const struct GNUNET_FS_Uri *uri)
862 875
863 if (uri->type != GNUNET_FS_URI_LOC) 876 if (uri->type != GNUNET_FS_URI_LOC)
864 return NULL; 877 return NULL;
865 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); 878 ret = GNUNET_new (struct GNUNET_FS_Uri);
866 ret->type = GNUNET_FS_URI_CHK; 879 ret->type = GNUNET_FS_URI_CHK;
867 ret->data.chk = uri->data.loc.fi; 880 ret->data.chk = uri->data.loc.fi;
868 return ret; 881 return ret;
@@ -912,7 +925,7 @@ GNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *baseUri,
912 ass.exptime = GNUNET_TIME_absolute_hton (expiration_time); 925 ass.exptime = GNUNET_TIME_absolute_hton (expiration_time);
913 ass.fi = baseUri->data.chk; 926 ass.fi = baseUri->data.chk;
914 ass.peer = my_public_key; 927 ass.peer = my_public_key;
915 uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); 928 uri = GNUNET_new (struct GNUNET_FS_Uri);
916 uri->type = GNUNET_FS_URI_LOC; 929 uri->type = GNUNET_FS_URI_LOC;
917 uri->data.loc.fi = baseUri->data.chk; 930 uri->data.loc.fi = baseUri->data.chk;
918 uri->data.loc.expirationTime = expiration_time; 931 uri->data.loc.expirationTime = expiration_time;
@@ -926,57 +939,21 @@ GNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *baseUri,
926 939
927 940
928/** 941/**
929 * Create an SKS URI from a namespace and an identifier.
930 *
931 * @param ns namespace
932 * @param id identifier
933 * @param emsg where to store an error message
934 * @return an FS URI for the given namespace and identifier
935 */
936struct GNUNET_FS_Uri *
937GNUNET_FS_uri_sks_create (struct GNUNET_FS_Namespace *ns, const char *id,
938 char **emsg)
939{
940 struct GNUNET_FS_Uri *ns_uri;
941
942 if (NULL == id)
943 {
944 if (NULL != emsg)
945 *emsg = GNUNET_strdup (_("identifier is NULL!"));
946 return NULL;
947 }
948 else if ('\0' == id[0])
949 {
950 if (NULL != emsg)
951 *emsg = GNUNET_strdup (_("identifier has zero length!"));
952 return NULL;
953 }
954 if (NULL != emsg)
955 *emsg = NULL;
956 ns_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri));
957 ns_uri->type = GNUNET_FS_URI_SKS;
958 GNUNET_FS_namespace_get_public_identifier (ns, &ns_uri->data.sks.ns);
959 ns_uri->data.sks.identifier = GNUNET_strdup (id);
960 return ns_uri;
961}
962
963
964/**
965 * Create an SKS URI from a namespace ID and an identifier. 942 * Create an SKS URI from a namespace ID and an identifier.
966 * 943 *
967 * @param pseudonym namespace ID 944 * @param ns namespace ID
968 * @param id identifier 945 * @param id identifier
969 * @return an FS URI for the given namespace and identifier 946 * @return an FS URI for the given namespace and identifier
970 */ 947 */
971struct GNUNET_FS_Uri * 948struct GNUNET_FS_Uri *
972GNUNET_FS_uri_sks_create_from_nsid (struct GNUNET_FS_PseudonymIdentifier *pseudonym, 949GNUNET_FS_uri_sks_create (const struct GNUNET_CRYPTO_EccPublicKey *ns,
973 const char *id) 950 const char *id)
974{ 951{
975 struct GNUNET_FS_Uri *ns_uri; 952 struct GNUNET_FS_Uri *ns_uri;
976 953
977 ns_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); 954 ns_uri = GNUNET_new (struct GNUNET_FS_Uri);
978 ns_uri->type = GNUNET_FS_URI_SKS; 955 ns_uri->type = GNUNET_FS_URI_SKS;
979 ns_uri->data.sks.ns = *pseudonym; 956 ns_uri->data.sks.ns = *ns;
980 ns_uri->data.sks.identifier = GNUNET_strdup (id); 957 ns_uri->data.sks.identifier = GNUNET_strdup (id);
981 return ns_uri; 958 return ns_uri;
982} 959}
@@ -1033,7 +1010,7 @@ GNUNET_FS_uri_ksk_merge (const struct GNUNET_FS_Uri *u1,
1033 if (0 == found) 1010 if (0 == found)
1034 kl[kc++] = GNUNET_strdup (kp); 1011 kl[kc++] = GNUNET_strdup (kp);
1035 } 1012 }
1036 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); 1013 ret = GNUNET_new (struct GNUNET_FS_Uri);
1037 ret->type = GNUNET_FS_URI_KSK; 1014 ret->type = GNUNET_FS_URI_KSK;
1038 ret->data.ksk.keywordCount = kc; 1015 ret->data.ksk.keywordCount = kc;
1039 ret->data.ksk.keywords = kl; 1016 ret->data.ksk.keywords = kl;
@@ -1055,7 +1032,7 @@ GNUNET_FS_uri_dup (const struct GNUNET_FS_Uri *uri)
1055 1032
1056 if (uri == NULL) 1033 if (uri == NULL)
1057 return NULL; 1034 return NULL;
1058 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); 1035 ret = GNUNET_new (struct GNUNET_FS_Uri);
1059 memcpy (ret, uri, sizeof (struct GNUNET_FS_Uri)); 1036 memcpy (ret, uri, sizeof (struct GNUNET_FS_Uri));
1060 switch (ret->type) 1037 switch (ret->type)
1061 { 1038 {
@@ -1224,7 +1201,7 @@ GNUNET_FS_uri_ksk_create_from_args (unsigned int argc, const char **argv)
1224 && (NULL != (uri = GNUNET_FS_uri_parse (argv[0], &emsg)))) 1201 && (NULL != (uri = GNUNET_FS_uri_parse (argv[0], &emsg))))
1225 return uri; 1202 return uri;
1226 GNUNET_free_non_null (emsg); 1203 GNUNET_free_non_null (emsg);
1227 uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); 1204 uri = GNUNET_new (struct GNUNET_FS_Uri);
1228 uri->type = GNUNET_FS_URI_KSK; 1205 uri->type = GNUNET_FS_URI_KSK;
1229 uri->data.ksk.keywordCount = argc; 1206 uri->data.ksk.keywordCount = argc;
1230 uri->data.ksk.keywords = GNUNET_malloc (argc * sizeof (char *)); 1207 uri->data.ksk.keywords = GNUNET_malloc (argc * sizeof (char *));
@@ -1280,7 +1257,7 @@ GNUNET_FS_uri_test_equal (const struct GNUNET_FS_Uri *u1,
1280 case GNUNET_FS_URI_SKS: 1257 case GNUNET_FS_URI_SKS:
1281 if ((0 == 1258 if ((0 ==
1282 memcmp (&u1->data.sks.ns, &u2->data.sks.ns, 1259 memcmp (&u1->data.sks.ns, &u2->data.sks.ns,
1283 sizeof (struct GNUNET_FS_PseudonymIdentifier))) && 1260 sizeof (struct GNUNET_CRYPTO_EccPublicKey))) &&
1284 (0 == strcmp (u1->data.sks.identifier, u2->data.sks.identifier))) 1261 (0 == strcmp (u1->data.sks.identifier, u2->data.sks.identifier)))
1285 1262
1286 return GNUNET_YES; 1263 return GNUNET_YES;
@@ -1341,7 +1318,7 @@ GNUNET_FS_uri_test_sks (const struct GNUNET_FS_Uri *uri)
1341 */ 1318 */
1342int 1319int
1343GNUNET_FS_uri_sks_get_namespace (const struct GNUNET_FS_Uri *uri, 1320GNUNET_FS_uri_sks_get_namespace (const struct GNUNET_FS_Uri *uri,
1344 struct GNUNET_FS_PseudonymIdentifier *pseudonym) 1321 struct GNUNET_CRYPTO_EccPublicKey *pseudonym)
1345{ 1322{
1346 if (!GNUNET_FS_uri_test_sks (uri)) 1323 if (!GNUNET_FS_uri_test_sks (uri))
1347 { 1324 {
@@ -1812,7 +1789,7 @@ GNUNET_FS_uri_ksk_create_from_meta_data (const struct GNUNET_CONTAINER_MetaData
1812 1789
1813 if (md == NULL) 1790 if (md == NULL)
1814 return NULL; 1791 return NULL;
1815 ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); 1792 ret = GNUNET_new (struct GNUNET_FS_Uri);
1816 ret->type = GNUNET_FS_URI_KSK; 1793 ret->type = GNUNET_FS_URI_KSK;
1817 ent = GNUNET_CONTAINER_meta_data_iterate (md, NULL, NULL); 1794 ent = GNUNET_CONTAINER_meta_data_iterate (md, NULL, NULL);
1818 if (ent > 0) 1795 if (ent > 0)
@@ -1944,7 +1921,7 @@ uri_sks_to_string (const struct GNUNET_FS_Uri *uri)
1944 if (GNUNET_FS_URI_SKS != uri->type) 1921 if (GNUNET_FS_URI_SKS != uri->type)
1945 return NULL; 1922 return NULL;
1946 ret = GNUNET_STRINGS_data_to_string (&uri->data.sks.ns, 1923 ret = GNUNET_STRINGS_data_to_string (&uri->data.sks.ns,
1947 sizeof (struct GNUNET_FS_PseudonymIdentifier), 1924 sizeof (struct GNUNET_CRYPTO_EccPublicKey),
1948 buf, 1925 buf,
1949 sizeof (buf)); 1926 sizeof (buf));
1950 GNUNET_assert (NULL != ret); 1927 GNUNET_assert (NULL != ret);
diff --git a/src/fs/gnunet-pseudonym.c b/src/fs/gnunet-pseudonym.c
index 61975e463..c87679641 100644
--- a/src/fs/gnunet-pseudonym.c
+++ b/src/fs/gnunet-pseudonym.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009, 2010 Christian Grothoff (and other contributing authors) 3 (C) 2001-2013 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -24,16 +24,13 @@
24 */ 24 */
25#include "platform.h" 25#include "platform.h"
26#include "gnunet_fs_service.h" 26#include "gnunet_fs_service.h"
27#include "gnunet_identity_service.h"
27 28
28/**
29 * -C option
30 */
31static char *create_ns;
32 29
33/** 30/**
34 * -D option 31 * -A option
35 */ 32 */
36static char *delete_ns; 33static char *advertise_ns;
37 34
38/** 35/**
39 * -k option 36 * -k option
@@ -41,11 +38,6 @@ static char *delete_ns;
41static struct GNUNET_FS_Uri *ksk_uri; 38static struct GNUNET_FS_Uri *ksk_uri;
42 39
43/** 40/**
44 * -l option.
45 */
46static int print_local_only;
47
48/**
49 * -m option. 41 * -m option.
50 */ 42 */
51static struct GNUNET_CONTAINER_MetaData *adv_metadata; 43static struct GNUNET_CONTAINER_MetaData *adv_metadata;
@@ -76,17 +68,37 @@ static char *rating_change;
76static struct GNUNET_FS_Handle *h; 68static struct GNUNET_FS_Handle *h;
77 69
78/** 70/**
79 * Namespace we are looking at. 71 * Our configuration.
72 */
73static const struct GNUNET_CONFIGURATION_Handle *cfg;
74
75/**
76 * Handle to identity service.
80 */ 77 */
81static struct GNUNET_FS_Namespace *ns; 78static struct GNUNET_IDENTITY_Handle *identity;
82 79
83/** 80/**
84 * Our configuration. 81 * Target namespace.
85 */ 82 */
86static const struct GNUNET_CONFIGURATION_Handle *cfg; 83static struct GNUNET_IDENTITY_Ego *namespace;
87 84
85/**
86 * URI to advertise.
87 */
88static struct GNUNET_FS_Uri *sks_uri;
89
90/**
91 * Global return value.
92 */
88static int ret; 93static int ret;
89 94
95
96/**
97 * Progress callback given to FS.
98 *
99 * @param cls unused
100 * @param info progress information, unused
101 */
90static void * 102static void *
91progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) 103progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
92{ 104{
@@ -94,20 +106,6 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
94} 106}
95 107
96 108
97static void
98ns_printer (void *cls, const char *name, const struct GNUNET_FS_PseudonymIdentifier *pseudonym)
99{
100 struct GNUNET_CRYPTO_HashAsciiEncoded enc;
101 struct GNUNET_HashCode hc;
102
103 GNUNET_CRYPTO_hash (pseudonym,
104 sizeof (struct GNUNET_FS_PseudonymIdentifier),
105 &hc);
106 GNUNET_CRYPTO_hash_to_enc (&hc, &enc);
107 FPRINTF (stdout, "%s (%s)\n", name, (const char *) &enc);
108}
109
110
111/** 109/**
112 * Output information about a pseudonym. 110 * Output information about a pseudonym.
113 * 111 *
@@ -121,7 +119,7 @@ ns_printer (void *cls, const char *name, const struct GNUNET_FS_PseudonymIdentif
121 */ 119 */
122static int 120static int
123pseudo_printer (void *cls, 121pseudo_printer (void *cls,
124 const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 122 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
125 const char *name, 123 const char *name,
126 const char *unique_name, 124 const char *unique_name,
127 const struct GNUNET_CONTAINER_MetaData *md, 125 const struct GNUNET_CONTAINER_MetaData *md,
@@ -135,77 +133,105 @@ pseudo_printer (void *cls,
135 * GNUNET_FS_pseudonym_get_info () never returns NULL. 133 * GNUNET_FS_pseudonym_get_info () never returns NULL.
136 */ 134 */
137 getinfo_result = GNUNET_FS_pseudonym_get_info (cfg, pseudonym, 135 getinfo_result = GNUNET_FS_pseudonym_get_info (cfg, pseudonym,
138 NULL, NULL, &id, NULL); 136 NULL, NULL, &id, NULL);
139 if (getinfo_result != GNUNET_OK) 137 if (GNUNET_OK != getinfo_result)
140 { 138 {
141 GNUNET_break (0); 139 GNUNET_break (0);
142 return GNUNET_OK; 140 return GNUNET_OK;
143 } 141 }
144 unique_id = GNUNET_FS_pseudonym_name_uniquify (cfg, pseudonym, id, NULL); 142 unique_id = GNUNET_FS_pseudonym_name_uniquify (cfg, pseudonym, id, NULL);
145 GNUNET_free (id); 143 GNUNET_free (id);
146 FPRINTF (stdout, "%s (%d):\n", unique_id, rating); 144 FPRINTF (stdout,
145 "%s (%d):\n",
146 unique_id, rating);
147 GNUNET_CONTAINER_meta_data_iterate (md, &EXTRACTOR_meta_data_print, stdout); 147 GNUNET_CONTAINER_meta_data_iterate (md, &EXTRACTOR_meta_data_print, stdout);
148 FPRINTF (stdout, "%s", "\n"); 148 FPRINTF (stdout,
149 "%s",
150 "\n");
149 GNUNET_free (unique_id); 151 GNUNET_free (unique_id);
150 return GNUNET_OK; 152 return GNUNET_OK;
151} 153}
152 154
153 155
156/**
157 * Function called once advertising is finished.
158 *
159 * @param cls closure (NULL)
160 * @param uri the advertised URI
161 * @param emsg error message, NULL on success
162 */
154static void 163static void
155post_advertising (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) 164post_advertising (void *cls,
165 const struct GNUNET_FS_Uri *uri,
166 const char *emsg)
156{ 167{
157 struct GNUNET_FS_PseudonymIdentifier nsid;
158 char *set;
159 int delta;
160
161 if (emsg != NULL) 168 if (emsg != NULL)
162 { 169 {
163 FPRINTF (stderr, "%s", emsg); 170 FPRINTF (stderr, "%s", emsg);
164 ret = 1; 171 ret = 1;
165 } 172 }
166 if (ns != NULL) 173 GNUNET_FS_stop (h);
167 { 174 GNUNET_IDENTITY_disconnect (identity);
168 if (GNUNET_OK != GNUNET_FS_namespace_delete (ns, GNUNET_NO)) 175}
169 ret = 1; 176
170 } 177
171 if (NULL != rating_change) 178/**
179 * Function called by identity service with known pseudonyms.
180 *
181 * @param cls closure, NULL
182 * @param ego ego handle
183 * @param ego_ctx context for application to store data for this ego
184 * (during the lifetime of this process, initially NULL)
185 * @param name name assigned by the user for this ego,
186 * NULL if the user just deleted the ego and it
187 * must thus no longer be used
188 */
189static void
190identity_cb (void *cls,
191 struct GNUNET_IDENTITY_Ego *ego,
192 void **ctx,
193 const char *name)
194{
195 char *emsg;
196 struct GNUNET_CRYPTO_EccPublicKey pub;
197
198 if (NULL == ego)
172 { 199 {
173 set = rating_change; 200 if (NULL == namespace)
174 while ((*set != '\0') && (*set != ':'))
175 set++;
176 if (*set != ':')
177 { 201 {
178 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Invalid argument `%s'\n"), 202 ret = 1;
179 rating_change); 203 return;
180 } 204 }
181 else 205 if (NULL != root_identifier)
182 { 206 {
183 *set = '\0'; 207 if (NULL == ksk_uri)
184 delta = strtol (&set[1], NULL, /* no error handling yet */
185 10);
186 if (GNUNET_OK == GNUNET_FS_pseudonym_name_to_id (cfg, rating_change, &nsid))
187 { 208 {
188 (void) GNUNET_FS_pseudonym_rank (cfg, &nsid, delta); 209 emsg = NULL;
189 } 210 ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/namespace", &emsg);
190 else 211 GNUNET_assert (NULL == emsg);
191 {
192 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
193 ("Namespace `%s' unknown. Make sure you specify its numeric suffix, if any.\n"),
194 rating_change);
195 } 212 }
213 GNUNET_IDENTITY_ego_get_public_key (namespace,
214 &pub);
215 sks_uri = GNUNET_FS_uri_sks_create (&pub,
216 root_identifier);
217 GNUNET_FS_publish_ksk (h, ksk_uri, adv_metadata, sks_uri,
218 &bo,
219 GNUNET_FS_PUBLISH_OPTION_NONE,
220 &post_advertising, NULL);
221 GNUNET_FS_uri_destroy (sks_uri);
222 return;
196 } 223 }
197 GNUNET_free (rating_change); 224 else
198 rating_change = NULL; 225 {
199 } 226 if (NULL != ksk_uri)
200 if (0 != print_local_only) 227 FPRINTF (stderr, _("Option `%s' ignored\n"), "-k");
201 { 228 if (NULL != advertise_ns)
202 GNUNET_FS_namespace_list (h, &ns_printer, NULL); 229 FPRINTF (stderr, _("Option `%s' ignored\n"), "-A");
203 } 230 }
204 else if (0 == no_remote_printing) 231 return;
205 {
206 GNUNET_FS_pseudonym_list_all (cfg, &pseudo_printer, NULL);
207 } 232 }
208 GNUNET_FS_stop (h); 233 if (0 == strcmp (name, advertise_ns))
234 namespace = ego;
209} 235}
210 236
211 237
@@ -221,68 +247,50 @@ static void
221run (void *cls, char *const *args, const char *cfgfile, 247run (void *cls, char *const *args, const char *cfgfile,
222 const struct GNUNET_CONFIGURATION_Handle *c) 248 const struct GNUNET_CONFIGURATION_Handle *c)
223{ 249{
224 struct GNUNET_FS_Uri *sks_uri; 250 struct GNUNET_CRYPTO_EccPublicKey nsid;
225 char *emsg; 251 char *set;
252 int delta;
226 253
227 cfg = c; 254 cfg = c;
228 h = GNUNET_FS_start (cfg, "gnunet-pseudonym", &progress_cb, NULL, 255 h = GNUNET_FS_start (cfg, "gnunet-pseudonym", &progress_cb, NULL,
229 GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); 256 GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END);
230 if (NULL != delete_ns) 257 if (NULL != rating_change)
231 {
232 ns = GNUNET_FS_namespace_create (h, delete_ns);
233 if (ns == NULL)
234 {
235 ret = 1;
236 }
237 else
238 {
239 if (GNUNET_OK != GNUNET_FS_namespace_delete (ns, GNUNET_YES))
240 ret = 1;
241 ns = NULL;
242 }
243 }
244 if (NULL != create_ns)
245 { 258 {
246 ns = GNUNET_FS_namespace_create (h, create_ns); 259 set = rating_change;
247 if (ns == NULL) 260 while ((*set != '\0') && (*set != ':'))
261 set++;
262 if (*set != ':')
248 { 263 {
249 ret = 1; 264 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
265 _("Invalid argument `%s'\n"),
266 rating_change);
250 } 267 }
251 else 268 else
252 { 269 {
253 if (NULL != root_identifier) 270 *set = '\0';
271 delta = strtol (&set[1], NULL, /* no error handling yet */
272 10);
273 if (GNUNET_OK == GNUNET_FS_pseudonym_name_to_id (cfg, rating_change, &nsid))
254 { 274 {
255 if (ksk_uri == NULL) 275 (void) GNUNET_FS_pseudonym_rank (cfg, &nsid, delta);
256 {
257 emsg = NULL;
258 ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/namespace", &emsg);
259 GNUNET_assert (NULL == emsg);
260 }
261 sks_uri = GNUNET_FS_uri_sks_create (ns, root_identifier, &emsg);
262 GNUNET_assert (NULL == emsg);
263 GNUNET_FS_publish_ksk (h, ksk_uri, adv_metadata, sks_uri,
264 &bo,
265 GNUNET_FS_PUBLISH_OPTION_NONE,
266 &post_advertising, NULL);
267 GNUNET_FS_uri_destroy (sks_uri);
268 return;
269 } 276 }
270 else 277 else
271 { 278 {
272 if (ksk_uri != NULL) 279 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
273 FPRINTF (stderr, _("Option `%s' ignored\n"), "-k"); 280 ("Namespace `%s' unknown. Make sure you specify its numeric suffix, if any.\n"),
281 rating_change);
274 } 282 }
275 } 283 }
284 GNUNET_free (rating_change);
285 rating_change = NULL;
276 } 286 }
277 else 287 if (0 == no_remote_printing)
278 { 288 GNUNET_FS_pseudonym_list_all (cfg, &pseudo_printer, NULL);
279 if (root_identifier != NULL)
280 FPRINTF (stderr, _("Option `%s' ignored\n"), "-r");
281 if (ksk_uri != NULL)
282 FPRINTF (stderr, _("Option `%s' ignored\n"), "-k");
283 }
284 289
285 post_advertising (NULL, NULL, NULL); 290 if (NULL != advertise_ns)
291 identity = GNUNET_IDENTITY_connect (cfg,
292 &identity_cb,
293 NULL);
286} 294}
287 295
288 296
@@ -301,12 +309,9 @@ main (int argc, char *const *argv)
301 {'a', "anonymity", "LEVEL", 309 {'a', "anonymity", "LEVEL",
302 gettext_noop ("set the desired LEVEL of sender-anonymity"), 310 gettext_noop ("set the desired LEVEL of sender-anonymity"),
303 1, &GNUNET_GETOPT_set_uint, &bo.anonymity_level}, 311 1, &GNUNET_GETOPT_set_uint, &bo.anonymity_level},
304 {'C', "create", "NAME", 312 {'A', "advertise", "NAME",
305 gettext_noop ("create or advertise namespace NAME"), 313 gettext_noop ("advertise namespace NAME"),
306 1, &GNUNET_GETOPT_set_string, &create_ns}, 314 1, &GNUNET_GETOPT_set_string, &advertise_ns},
307 {'D', "delete", "NAME",
308 gettext_noop ("delete namespace NAME "),
309 1, &GNUNET_GETOPT_set_string, &delete_ns},
310 {'k', "keyword", "VALUE", 315 {'k', "keyword", "VALUE",
311 gettext_noop ("add an additional keyword for the advertisment" 316 gettext_noop ("add an additional keyword for the advertisment"
312 " (this option can be specified multiple times)"), 317 " (this option can be specified multiple times)"),
@@ -314,9 +319,6 @@ main (int argc, char *const *argv)
314 {'m', "meta", "TYPE:VALUE", 319 {'m', "meta", "TYPE:VALUE",
315 gettext_noop ("set the meta-data for the given TYPE to the given VALUE"), 320 gettext_noop ("set the meta-data for the given TYPE to the given VALUE"),
316 1, &GNUNET_FS_getopt_set_metadata, &adv_metadata}, 321 1, &GNUNET_FS_getopt_set_metadata, &adv_metadata},
317 {'o', "only-local", NULL,
318 gettext_noop ("print names of local namespaces"),
319 0, &GNUNET_GETOPT_set_one, &print_local_only},
320 {'p', "priority", "PRIORITY", 322 {'p', "priority", "PRIORITY",
321 gettext_noop ("use the given PRIORITY for the advertisments"), 323 gettext_noop ("use the given PRIORITY for the advertisments"),
322 1, &GNUNET_GETOPT_set_uint, &bo.content_priority}, 324 1, &GNUNET_GETOPT_set_uint, &bo.content_priority},
diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c
index 59b40a5e4..39235683c 100644
--- a/src/fs/gnunet-publish.c
+++ b/src/fs/gnunet-publish.c
@@ -27,6 +27,7 @@
27 */ 27 */
28#include "platform.h" 28#include "platform.h"
29#include "gnunet_fs_service.h" 29#include "gnunet_fs_service.h"
30#include "gnunet_identity_service.h"
30 31
31/** 32/**
32 * Global return value from 'main'. 33 * Global return value from 'main'.
@@ -137,7 +138,12 @@ static struct GNUNET_FS_DirScanner *ds;
137 * Which namespace do we publish to? NULL if we do not publish to 138 * Which namespace do we publish to? NULL if we do not publish to
138 * a namespace. 139 * a namespace.
139 */ 140 */
140static struct GNUNET_FS_Namespace *namespace; 141static struct GNUNET_IDENTITY_Ego *namespace;
142
143/**
144 * Handle to identity service.
145 */
146static struct GNUNET_IDENTITY_Handle *identity;
141 147
142 148
143/** 149/**
@@ -153,7 +159,7 @@ do_stop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
153 struct GNUNET_FS_PublishContext *p; 159 struct GNUNET_FS_PublishContext *p;
154 160
155 kill_task = GNUNET_SCHEDULER_NO_TASK; 161 kill_task = GNUNET_SCHEDULER_NO_TASK;
156 if (pc != NULL) 162 if (NULL != pc)
157 { 163 {
158 p = pc; 164 p = pc;
159 pc = NULL; 165 pc = NULL;
@@ -182,10 +188,10 @@ stop_scanner_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
182 GNUNET_FS_directory_scan_abort (ds); 188 GNUNET_FS_directory_scan_abort (ds);
183 ds = NULL; 189 ds = NULL;
184 } 190 }
185 if (NULL != namespace) 191 if (NULL != identity)
186 { 192 {
187 GNUNET_FS_namespace_delete (namespace, GNUNET_NO); 193 GNUNET_IDENTITY_disconnect (identity);
188 namespace = NULL; 194 identity = NULL;
189 } 195 }
190 GNUNET_FS_stop (ctx); 196 GNUNET_FS_stop (ctx);
191 ctx = NULL; 197 ctx = NULL;
@@ -432,29 +438,20 @@ static void
432uri_ksk_continuation (void *cls, const struct GNUNET_FS_Uri *ksk_uri, 438uri_ksk_continuation (void *cls, const struct GNUNET_FS_Uri *ksk_uri,
433 const char *emsg) 439 const char *emsg)
434{ 440{
435 struct GNUNET_FS_Namespace *ns; 441 const struct GNUNET_CRYPTO_EccPrivateKey *priv;
436 442
437 if (NULL != emsg) 443 if (NULL != emsg)
438 { 444 {
439 FPRINTF (stderr, "%s\n", emsg); 445 FPRINTF (stderr, "%s\n", emsg);
440 ret = 1; 446 ret = 1;
441 } 447 }
442 if (NULL != pseudonym) 448 if (NULL != namespace)
443 { 449 {
444 ns = GNUNET_FS_namespace_create (ctx, pseudonym); 450 priv = GNUNET_IDENTITY_ego_get_private_key (namespace);
445 if (NULL == ns) 451 GNUNET_FS_publish_sks (ctx, priv, this_id, next_id, meta, uri, &bo,
446 { 452 GNUNET_FS_PUBLISH_OPTION_NONE,
447 FPRINTF (stderr, _("Failed to create namespace `%s' (illegal filename?)\n"), pseudonym); 453 &uri_sks_continuation, NULL);
448 ret = 1; 454 return;
449 }
450 else
451 {
452 GNUNET_FS_publish_sks (ctx, ns, this_id, next_id, meta, uri, &bo,
453 GNUNET_FS_PUBLISH_OPTION_NONE,
454 &uri_sks_continuation, NULL);
455 GNUNET_assert (GNUNET_OK == GNUNET_FS_namespace_delete (ns, GNUNET_NO));
456 return;
457 }
458 } 455 }
459 GNUNET_FS_uri_destroy (uri); 456 GNUNET_FS_uri_destroy (uri);
460 uri = NULL; 457 uri = NULL;
@@ -523,40 +520,37 @@ static void
523directory_trim_complete (struct GNUNET_FS_ShareTreeItem *directory_scan_result) 520directory_trim_complete (struct GNUNET_FS_ShareTreeItem *directory_scan_result)
524{ 521{
525 struct GNUNET_FS_FileInformation *fi; 522 struct GNUNET_FS_FileInformation *fi;
523 const struct GNUNET_CRYPTO_EccPrivateKey *priv;
526 524
527 fi = get_file_information (directory_scan_result); 525 fi = get_file_information (directory_scan_result);
528 GNUNET_FS_share_tree_free (directory_scan_result); 526 GNUNET_FS_share_tree_free (directory_scan_result);
529 if (NULL == fi) 527 if (NULL == fi)
530 { 528 {
531 FPRINTF (stderr, "%s", _("Could not publish\n")); 529 FPRINTF (stderr, "%s", _("Could not publish\n"));
532 if (NULL != namespace) 530 GNUNET_SCHEDULER_shutdown ();
533 GNUNET_FS_namespace_delete (namespace, GNUNET_NO);
534 GNUNET_FS_stop (ctx);
535 ret = 1; 531 ret = 1;
536 return; 532 return;
537 } 533 }
538 GNUNET_FS_file_information_inspect (fi, &publish_inspector, NULL); 534 GNUNET_FS_file_information_inspect (fi, &publish_inspector, NULL);
539 if (extract_only) 535 if (extract_only)
540 { 536 {
541 if (NULL != namespace)
542 GNUNET_FS_namespace_delete (namespace, GNUNET_NO);
543 GNUNET_FS_file_information_destroy (fi, NULL, NULL); 537 GNUNET_FS_file_information_destroy (fi, NULL, NULL);
544 GNUNET_FS_stop (ctx); 538 GNUNET_SCHEDULER_shutdown ();
545 if (GNUNET_SCHEDULER_NO_TASK != kill_task)
546 {
547 GNUNET_SCHEDULER_cancel (kill_task);
548 kill_task = GNUNET_SCHEDULER_NO_TASK;
549 }
550 return; 539 return;
551 } 540 }
552 pc = GNUNET_FS_publish_start (ctx, fi, namespace, this_id, next_id, 541 if (NULL == namespace)
542 priv = NULL;
543 else
544 priv = GNUNET_IDENTITY_ego_get_private_key (namespace);
545 pc = GNUNET_FS_publish_start (ctx, fi,
546 priv, this_id, next_id,
553 (do_simulate) ? 547 (do_simulate) ?
554 GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY : 548 GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY :
555 GNUNET_FS_PUBLISH_OPTION_NONE); 549 GNUNET_FS_PUBLISH_OPTION_NONE);
556 if (NULL == pc) 550 if (NULL == pc)
557 { 551 {
558 FPRINTF (stderr, "%s", _("Could not start publishing.\n")); 552 FPRINTF (stderr, "%s", _("Could not start publishing.\n"));
559 GNUNET_FS_stop (ctx); 553 GNUNET_SCHEDULER_shutdown ();
560 ret = 1; 554 ret = 1;
561 return; 555 return;
562 } 556 }
@@ -632,6 +626,94 @@ directory_scan_cb (void *cls,
632 626
633 627
634/** 628/**
629 * Continuation proceeding with initialization after identity subsystem
630 * has been initialized.
631 *
632 * @param args0 filename to publish
633 */
634static void
635identity_continuation (const char *args0)
636{
637 char *ex;
638 char *emsg;
639
640 if ( (NULL != pseudonym) &&
641 (NULL == namespace) )
642 {
643 FPRINTF (stderr, _("Selected pseudonym `%s' unknown\n"), pseudonym);
644 GNUNET_SCHEDULER_shutdown ();
645 return;
646 }
647 if (NULL != uri_string)
648 {
649 emsg = NULL;
650 if (NULL == (uri = GNUNET_FS_uri_parse (uri_string, &emsg)))
651 {
652 FPRINTF (stderr, _("Failed to parse URI: %s\n"), emsg);
653 GNUNET_free (emsg);
654 GNUNET_SCHEDULER_shutdown ();
655 ret = 1;
656 return;
657 }
658 GNUNET_FS_publish_ksk (ctx, topKeywords, meta, uri, &bo,
659 GNUNET_FS_PUBLISH_OPTION_NONE, &uri_ksk_continuation,
660 NULL);
661 return;
662 }
663 if (GNUNET_OK !=
664 GNUNET_CONFIGURATION_get_value_string (cfg, "FS", "EXTRACTORS", &ex))
665 ex = NULL;
666 if (0 != ACCESS (args0, R_OK))
667 {
668 FPRINTF (stderr,
669 _("Failed to access `%s': %s\n"),
670 args0,
671 STRERROR (errno));
672 return;
673 }
674 ds = GNUNET_FS_directory_scan_start (args0,
675 disable_extractor,
676 ex,
677 &directory_scan_cb, NULL);
678 if (NULL == ds)
679 {
680 FPRINTF (stderr,
681 "%s", _("Failed to start meta directory scanner. Is gnunet-helper-publish-fs installed?\n"));
682 return;
683 }
684}
685
686
687/**
688 * Function called by identity service with known pseudonyms.
689 *
690 * @param cls closure with 'const char *' of filename to publish
691 * @param ego ego handle
692 * @param ego_ctx context for application to store data for this ego
693 * (during the lifetime of this process, initially NULL)
694 * @param name name assigned by the user for this ego,
695 * NULL if the user just deleted the ego and it
696 * must thus no longer be used
697 */
698static void
699identity_cb (void *cls,
700 struct GNUNET_IDENTITY_Ego *ego,
701 void **ctx,
702 const char *name)
703{
704 const char *args0 = cls;
705
706 if (NULL == ego)
707 {
708 identity_continuation (args0);
709 return;
710 }
711 if (0 == strcmp (name, pseudonym))
712 namespace = ego;
713}
714
715
716/**
635 * Main function that will be run by the scheduler. 717 * Main function that will be run by the scheduler.
636 * 718 *
637 * @param cls closure 719 * @param cls closure
@@ -643,9 +725,6 @@ static void
643run (void *cls, char *const *args, const char *cfgfile, 725run (void *cls, char *const *args, const char *cfgfile,
644 const struct GNUNET_CONFIGURATION_Handle *c) 726 const struct GNUNET_CONFIGURATION_Handle *c)
645{ 727{
646 char *ex;
647 char *emsg;
648
649 /* check arguments */ 728 /* check arguments */
650 if ((NULL != uri_string) && (extract_only)) 729 if ((NULL != uri_string) && (extract_only))
651 { 730 {
@@ -703,62 +782,14 @@ run (void *cls, char *const *args, const char *cfgfile,
703 ret = 1; 782 ret = 1;
704 return; 783 return;
705 } 784 }
706 namespace = NULL;
707 if (NULL != pseudonym)
708 {
709 namespace = GNUNET_FS_namespace_create (ctx, pseudonym);
710 if (NULL == namespace)
711 {
712 FPRINTF (stderr, _("Failed to create namespace `%s' (illegal filename?)\n"), pseudonym);
713 GNUNET_FS_stop (ctx);
714 ret = 1;
715 return;
716 }
717 }
718 if (NULL != uri_string)
719 {
720 emsg = NULL;
721 if (NULL == (uri = GNUNET_FS_uri_parse (uri_string, &emsg)))
722 {
723 FPRINTF (stderr, _("Failed to parse URI: %s\n"), emsg);
724 GNUNET_free (emsg);
725 if (namespace != NULL)
726 GNUNET_FS_namespace_delete (namespace, GNUNET_NO);
727 GNUNET_FS_stop (ctx);
728 ret = 1;
729 return;
730 }
731 GNUNET_FS_publish_ksk (ctx, topKeywords, meta, uri, &bo,
732 GNUNET_FS_PUBLISH_OPTION_NONE, &uri_ksk_continuation,
733 NULL);
734 if (NULL != namespace)
735 GNUNET_FS_namespace_delete (namespace, GNUNET_NO);
736 return;
737 }
738 if (GNUNET_OK !=
739 GNUNET_CONFIGURATION_get_value_string (cfg, "FS", "EXTRACTORS", &ex))
740 ex = NULL;
741 if (0 != ACCESS (args[0], R_OK))
742 {
743 FPRINTF (stderr,
744 _("Failed to access `%s': %s\n"),
745 args[0],
746 STRERROR (errno));
747 return;
748 }
749 ds = GNUNET_FS_directory_scan_start (args[0],
750 disable_extractor,
751 ex,
752 &directory_scan_cb, NULL);
753 if (NULL == ds)
754 {
755 FPRINTF (stderr,
756 "%s", _("Failed to start meta directory scanner. Is gnunet-helper-publish-fs installed?\n"));
757 return;
758 }
759 kill_task = 785 kill_task =
760 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_stop_task, 786 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_stop_task,
761 NULL); 787 NULL);
788 if (NULL != pseudonym)
789 identity = GNUNET_IDENTITY_connect (cfg,
790 &identity_cb, args[0]);
791 else
792 identity_continuation (args[0]);
762} 793}
763 794
764 795
diff --git a/src/fs/plugin_block_fs.c b/src/fs/plugin_block_fs.c
index 453338614..e493319be 100644
--- a/src/fs/plugin_block_fs.c
+++ b/src/fs/plugin_block_fs.c
@@ -105,15 +105,16 @@ block_plugin_fs_evaluate (void *cls, enum GNUNET_BLOCK_Type type,
105 GNUNET_break_op (0); 105 GNUNET_break_op (0);
106 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; 106 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
107 } 107 }
108 if (reply_block_size != ntohl (ub->purpose.size) + sizeof (struct GNUNET_FS_PseudonymSignature)) 108 if (reply_block_size != ntohl (ub->purpose.size) + sizeof (struct GNUNET_CRYPTO_EccSignature))
109 { 109 {
110 GNUNET_break_op (0); 110 GNUNET_break_op (0);
111 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; 111 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
112 } 112 }
113 if (GNUNET_OK != 113 if (GNUNET_OK !=
114 GNUNET_FS_pseudonym_verify (&ub->purpose, 114 GNUNET_CRYPTO_ecc_verify (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK,
115 &ub->signature, 115 &ub->purpose,
116 &ub->verification_key)) 116 &ub->signature,
117 &ub->verification_key))
117 { 118 {
118 GNUNET_break_op (0); 119 GNUNET_break_op (0);
119 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; 120 return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
diff --git a/src/fs/test_fs_namespace.c b/src/fs/test_fs_namespace.c
index c720cb919..c8371f0b5 100644
--- a/src/fs/test_fs_namespace.c
+++ b/src/fs/test_fs_namespace.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2005, 2006, 2008, 2009 Christian Grothoff (and other contributing authors) 3 (C) 2005-2013 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -29,7 +29,7 @@
29#include "gnunet_fs_service.h" 29#include "gnunet_fs_service.h"
30 30
31 31
32static struct GNUNET_FS_PseudonymIdentifier nsid; 32static struct GNUNET_CRYPTO_EccPublicKey nsid;
33 33
34static struct GNUNET_FS_Uri *sks_expect_uri; 34static struct GNUNET_FS_Uri *sks_expect_uri;
35 35
@@ -68,15 +68,10 @@ abort_ksk_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
68static void 68static void
69abort_sks_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 69abort_sks_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
70{ 70{
71 struct GNUNET_FS_Namespace *ns;
72
73 if (sks_search == NULL) 71 if (sks_search == NULL)
74 return; 72 return;
75 GNUNET_FS_search_stop (sks_search); 73 GNUNET_FS_search_stop (sks_search);
76 sks_search = NULL; 74 sks_search = NULL;
77 ns = GNUNET_FS_namespace_create (fs, "testNamespace");
78 GNUNET_assert (NULL != ns);
79 GNUNET_assert (GNUNET_OK == GNUNET_FS_namespace_delete (ns, GNUNET_YES));
80 if (ksk_search == NULL) 75 if (ksk_search == NULL)
81 { 76 {
82 GNUNET_FS_stop (fs); 77 GNUNET_FS_stop (fs);
@@ -242,7 +237,7 @@ static void
242adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) 237adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
243{ 238{
244 struct GNUNET_CONTAINER_MetaData *meta; 239 struct GNUNET_CONTAINER_MetaData *meta;
245 struct GNUNET_FS_Namespace *ns; 240 struct GNUNET_CRYPTO_EccPrivateKey *ns;
246 struct GNUNET_FS_BlockOptions bo; 241 struct GNUNET_FS_BlockOptions bo;
247 242
248 if (NULL != emsg) 243 if (NULL != emsg)
@@ -252,57 +247,32 @@ adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
252 GNUNET_FS_stop (fs); 247 GNUNET_FS_stop (fs);
253 return; 248 return;
254 } 249 }
255 ns = GNUNET_FS_namespace_create (fs, "testNamespace"); 250 ns = GNUNET_CRYPTO_ecc_key_create ();
256 GNUNET_assert (NULL != ns);
257 meta = GNUNET_CONTAINER_meta_data_create (); 251 meta = GNUNET_CONTAINER_meta_data_create ();
258 GNUNET_assert (NULL == emsg);
259 sks_expect_uri = GNUNET_FS_uri_dup (uri); 252 sks_expect_uri = GNUNET_FS_uri_dup (uri);
260 bo.content_priority = 1; 253 bo.content_priority = 1;
261 bo.anonymity_level = 1; 254 bo.anonymity_level = 1;
262 bo.replication_level = 0; 255 bo.replication_level = 0;
263 bo.expiration_time = 256 bo.expiration_time =
264 GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); 257 GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
258 GNUNET_CRYPTO_ecc_key_get_public (ns, &nsid);
265 GNUNET_FS_publish_sks (fs, ns, "this", "next", meta, uri, 259 GNUNET_FS_publish_sks (fs, ns, "this", "next", meta, uri,
266 &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &sks_cont, NULL); 260 &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &sks_cont, NULL);
267 GNUNET_CONTAINER_meta_data_destroy (meta); 261 GNUNET_CONTAINER_meta_data_destroy (meta);
268 GNUNET_FS_namespace_delete (ns, GNUNET_NO); 262 GNUNET_CRYPTO_ecc_key_free (ns);
269}
270
271
272static void
273ns_iterator (void *cls, const char *name, const struct GNUNET_FS_PseudonymIdentifier *id)
274{
275 int *ok = cls;
276
277 if (0 != strcmp (name, "testNamespace"))
278 return;
279 *ok = GNUNET_YES;
280 nsid = *id;
281} 263}
282 264
283 265
284static void 266static void
285testNamespace () 267testNamespace ()
286{ 268{
287 struct GNUNET_FS_Namespace *ns; 269 struct GNUNET_CRYPTO_EccPrivateKey *ns;
288 struct GNUNET_FS_BlockOptions bo; 270 struct GNUNET_FS_BlockOptions bo;
289 struct GNUNET_CONTAINER_MetaData *meta; 271 struct GNUNET_CONTAINER_MetaData *meta;
290 struct GNUNET_FS_Uri *ksk_uri; 272 struct GNUNET_FS_Uri *ksk_uri;
291 struct GNUNET_FS_Uri *sks_uri; 273 struct GNUNET_FS_Uri *sks_uri;
292 int ok;
293 274
294 ns = GNUNET_FS_namespace_create (fs, "testNamespace"); 275 ns = GNUNET_CRYPTO_ecc_key_create ();
295 GNUNET_assert (NULL != ns);
296 ok = GNUNET_NO;
297 GNUNET_FS_namespace_list (fs, &ns_iterator, &ok);
298 if (GNUNET_NO == ok)
299 {
300 FPRINTF (stderr, "%s", "namespace_list failed to find namespace!\n");
301 GNUNET_FS_namespace_delete (ns, GNUNET_YES);
302 GNUNET_FS_stop (fs);
303 err = 1;
304 return;
305 }
306 meta = GNUNET_CONTAINER_meta_data_create (); 276 meta = GNUNET_CONTAINER_meta_data_create ();
307 ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/testnsa", NULL); 277 ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/testnsa", NULL);
308 bo.content_priority = 1; 278 bo.content_priority = 1;
@@ -310,17 +280,18 @@ testNamespace ()
310 bo.replication_level = 0; 280 bo.replication_level = 0;
311 bo.expiration_time = 281 bo.expiration_time =
312 GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); 282 GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
313 sks_uri = GNUNET_FS_uri_sks_create (ns, "root", NULL); 283 sks_uri = GNUNET_FS_uri_sks_create (&nsid, "root");
314 GNUNET_FS_publish_ksk (fs, 284 GNUNET_FS_publish_ksk (fs,
315 ksk_uri, meta, sks_uri, &bo, GNUNET_FS_PUBLISH_OPTION_NONE, 285 ksk_uri, meta, sks_uri,
286 &bo, GNUNET_FS_PUBLISH_OPTION_NONE,
316 &adv_cont, NULL); 287 &adv_cont, NULL);
317 GNUNET_FS_uri_destroy (sks_uri); 288 GNUNET_FS_uri_destroy (sks_uri);
318 kill_task = 289 kill_task =
319 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &do_timeout, 290 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &do_timeout,
320 NULL); 291 NULL);
321 GNUNET_FS_uri_destroy (ksk_uri); 292 GNUNET_FS_uri_destroy (ksk_uri);
322 GNUNET_FS_namespace_delete (ns, GNUNET_NO);
323 GNUNET_CONTAINER_meta_data_destroy (meta); 293 GNUNET_CONTAINER_meta_data_destroy (meta);
294 GNUNET_CRYPTO_ecc_key_free (ns);
324} 295}
325 296
326 297
diff --git a/src/fs/test_fs_namespace_list_updateable.c b/src/fs/test_fs_namespace_list_updateable.c
index dc17ce458..ff662c9e6 100644
--- a/src/fs/test_fs_namespace_list_updateable.c
+++ b/src/fs/test_fs_namespace_list_updateable.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2005, 2006, 2008, 2009 Christian Grothoff (and other contributing authors) 3 (C) 2005-2013 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -33,7 +33,7 @@ static struct GNUNET_FS_Handle *fs;
33 33
34static int err; 34static int err;
35 35
36static struct GNUNET_FS_Namespace *ns; 36static struct GNUNET_CRYPTO_EccPrivateKey *ns;
37 37
38static struct GNUNET_CONTAINER_MetaData *meta; 38static struct GNUNET_CONTAINER_MetaData *meta;
39 39
@@ -59,7 +59,7 @@ do_shutdown ()
59 if (uri_next != NULL) 59 if (uri_next != NULL)
60 GNUNET_FS_uri_destroy (uri_next); 60 GNUNET_FS_uri_destroy (uri_next);
61 if (ns != NULL) 61 if (ns != NULL)
62 GNUNET_FS_namespace_delete (ns, GNUNET_NO); 62 GNUNET_CRYPTO_ecc_key_free (ns);
63 if (meta != NULL) 63 if (meta != NULL)
64 GNUNET_CONTAINER_meta_data_destroy (meta); 64 GNUNET_CONTAINER_meta_data_destroy (meta);
65} 65}
@@ -87,7 +87,7 @@ check_this_next (void *cls, const char *last_id,
87 GNUNET_break (0 == strcmp (next_id, "next")); 87 GNUNET_break (0 == strcmp (next_id, "next"));
88 err -= 2; 88 err -= 2;
89 err += 4; 89 err += 4;
90 GNUNET_FS_namespace_list_updateable (ns, next_id, &check_next, NULL); 90 GNUNET_FS_namespace_list_updateable (fs, ns, next_id, &check_next, NULL);
91} 91}
92 92
93 93
@@ -96,7 +96,7 @@ sks_cont_next (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
96{ 96{
97 GNUNET_assert (NULL == emsg); 97 GNUNET_assert (NULL == emsg);
98 err += 2; 98 err += 2;
99 GNUNET_FS_namespace_list_updateable (ns, NULL, &check_this_next, NULL); 99 GNUNET_FS_namespace_list_updateable (fs, ns, NULL, &check_this_next, NULL);
100} 100}
101 101
102 102
@@ -117,7 +117,7 @@ sks_cont_this (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
117{ 117{
118 GNUNET_assert (NULL == emsg); 118 GNUNET_assert (NULL == emsg);
119 err = 1; 119 err = 1;
120 GNUNET_FS_namespace_list_updateable (ns, NULL, &check_this, NULL); 120 GNUNET_FS_namespace_list_updateable (fs, ns, NULL, &check_this, NULL);
121 GNUNET_FS_publish_sks (fs, ns, "next", "future", meta, uri_next, &bo, 121 GNUNET_FS_publish_sks (fs, ns, "next", "future", meta, uri_next, &bo,
122 GNUNET_FS_PUBLISH_OPTION_NONE, &sks_cont_next, NULL); 122 GNUNET_FS_PUBLISH_OPTION_NONE, &sks_cont_next, NULL);
123 123
@@ -127,7 +127,7 @@ sks_cont_this (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
127static void 127static void
128testNamespace () 128testNamespace ()
129{ 129{
130 ns = GNUNET_FS_namespace_create (fs, "testNamespace"); 130 ns = GNUNET_CRYPTO_ecc_key_create ();
131 GNUNET_assert (NULL != ns); 131 GNUNET_assert (NULL != ns);
132 bo.content_priority = 1; 132 bo.content_priority = 1;
133 bo.anonymity_level = 1; 133 bo.anonymity_level = 1;
diff --git a/src/fs/test_fs_uri.c b/src/fs/test_fs_uri.c
index d0aa26b79..ca89a7652 100644
--- a/src/fs/test_fs_uri.c
+++ b/src/fs/test_fs_uri.c
@@ -162,8 +162,8 @@ testNamespace (int i)
162 char *uri; 162 char *uri;
163 struct GNUNET_FS_Uri *ret; 163 struct GNUNET_FS_Uri *ret;
164 char *emsg; 164 char *emsg;
165 struct GNUNET_FS_PseudonymHandle *ph; 165 struct GNUNET_CRYPTO_EccPrivateKey *ph;
166 struct GNUNET_FS_PseudonymIdentifier id; 166 struct GNUNET_CRYPTO_EccPublicKey id;
167 char buf[1024]; 167 char buf[1024];
168 char ubuf[1024]; 168 char ubuf[1024];
169 char *sret; 169 char *sret;
@@ -192,8 +192,8 @@ testNamespace (int i)
192 GNUNET_assert (0); 192 GNUNET_assert (0);
193 } 193 }
194 GNUNET_free (emsg); 194 GNUNET_free (emsg);
195 ph = GNUNET_FS_pseudonym_create (NULL); 195 ph = GNUNET_CRYPTO_ecc_key_create ();
196 GNUNET_FS_pseudonym_get_identifier (ph, &id); 196 GNUNET_CRYPTO_ecc_key_get_public (ph, &id);
197 sret = GNUNET_STRINGS_data_to_string (&id, sizeof (id), 197 sret = GNUNET_STRINGS_data_to_string (&id, sizeof (id),
198 ubuf, sizeof (ubuf) - 1); 198 ubuf, sizeof (ubuf) - 1);
199 GNUNET_assert (NULL != sret); 199 GNUNET_assert (NULL != sret);
@@ -232,6 +232,7 @@ testNamespace (int i)
232 return 0; 232 return 0;
233} 233}
234 234
235
235static int 236static int
236testFile (int i) 237testFile (int i)
237{ 238{
diff --git a/src/fs/test_pseudonym.c b/src/fs/test_pseudonym.c
index a6e258038..c3b459420 100644
--- a/src/fs/test_pseudonym.c
+++ b/src/fs/test_pseudonym.c
@@ -33,17 +33,18 @@
33 33
34static struct GNUNET_CONTAINER_MetaData *meta; 34static struct GNUNET_CONTAINER_MetaData *meta;
35 35
36static struct GNUNET_FS_PseudonymIdentifier id1; 36static struct GNUNET_CRYPTO_EccPublicKey id1;
37 37
38 38
39static int 39static int
40iter (void *cls, const struct GNUNET_FS_PseudonymIdentifier * pseudonym, 40iter (void *cls,
41 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
41 const char *name, const char *unique_name, 42 const char *name, const char *unique_name,
42 const struct GNUNET_CONTAINER_MetaData *md, int32_t rating) 43 const struct GNUNET_CONTAINER_MetaData *md, int32_t rating)
43{ 44{
44 int *ok = cls; 45 int *ok = cls;
45 46
46 if ((0 == memcmp (pseudonym, &id1, sizeof (struct GNUNET_FS_PseudonymIdentifier))) && 47 if ((0 == memcmp (pseudonym, &id1, sizeof (struct GNUNET_CRYPTO_EccPublicKey))) &&
47 (!GNUNET_CONTAINER_meta_data_test_equal (md, meta))) 48 (!GNUNET_CONTAINER_meta_data_test_equal (md, meta)))
48 { 49 {
49 *ok = GNUNET_NO; 50 *ok = GNUNET_NO;
@@ -54,7 +55,7 @@ iter (void *cls, const struct GNUNET_FS_PseudonymIdentifier * pseudonym,
54 55
55 56
56static int 57static int
57noti_callback (void *cls, const struct GNUNET_FS_PseudonymIdentifier * pseudonym, 58noti_callback (void *cls, const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
58 const char *name, const char *unique_name, 59 const char *name, const char *unique_name,
59 const struct GNUNET_CONTAINER_MetaData *md, int32_t rating) 60 const struct GNUNET_CONTAINER_MetaData *md, int32_t rating)
60{ 61{
@@ -66,7 +67,8 @@ noti_callback (void *cls, const struct GNUNET_FS_PseudonymIdentifier * pseudonym
66 67
67 68
68static int 69static int
69fake_noti_callback (void *cls, const struct GNUNET_FS_PseudonymIdentifier * pseudonym, 70fake_noti_callback (void *cls,
71 const struct GNUNET_CRYPTO_EccPublicKey * pseudonym,
70 const char *name, const char *unique_name, 72 const char *name, const char *unique_name,
71 const struct GNUNET_CONTAINER_MetaData *md, int32_t rating) 73 const struct GNUNET_CONTAINER_MetaData *md, int32_t rating)
72{ 74{
@@ -78,13 +80,13 @@ fake_noti_callback (void *cls, const struct GNUNET_FS_PseudonymIdentifier * pseu
78 80
79 81
80static void 82static void
81create_pseu (struct GNUNET_FS_PseudonymIdentifier *pseu) 83create_pseu (struct GNUNET_CRYPTO_EccPublicKey *pseu)
82{ 84{
83 struct GNUNET_FS_PseudonymHandle *ph; 85 struct GNUNET_CRYPTO_EccPrivateKey *ph;
84 86
85 ph = GNUNET_FS_pseudonym_create (NULL); 87 ph = GNUNET_CRYPTO_ecc_key_create ();
86 GNUNET_FS_pseudonym_get_identifier (ph, pseu); 88 GNUNET_CRYPTO_ecc_key_get_public (ph, pseu);
87 GNUNET_FS_pseudonym_destroy (ph); 89 GNUNET_CRYPTO_ecc_key_free (ph);
88} 90}
89 91
90 92
@@ -95,11 +97,11 @@ static int
95test_io () 97test_io ()
96{ 98{
97 int ok; 99 int ok;
98 struct GNUNET_FS_PseudonymIdentifier rid1; 100 struct GNUNET_CRYPTO_EccPublicKey rid1;
99 struct GNUNET_FS_PseudonymIdentifier id2; 101 struct GNUNET_CRYPTO_EccPublicKey id2;
100 struct GNUNET_FS_PseudonymIdentifier rid2; 102 struct GNUNET_CRYPTO_EccPublicKey rid2;
101 struct GNUNET_FS_PseudonymIdentifier fid; 103 struct GNUNET_CRYPTO_EccPublicKey fid;
102 struct GNUNET_FS_PseudonymIdentifier id3; 104 struct GNUNET_CRYPTO_EccPublicKey id3;
103 int old; 105 int old;
104 int newVal; 106 int newVal;
105 struct GNUNET_CONFIGURATION_Handle *cfg; 107 struct GNUNET_CONFIGURATION_Handle *cfg;
@@ -112,12 +114,11 @@ test_io ()
112 int noname_is_a_dup; 114 int noname_is_a_dup;
113 int notiCount, fakenotiCount; 115 int notiCount, fakenotiCount;
114 static char m[1024 * 1024 * 10]; 116 static char m[1024 * 1024 * 10];
115 struct GNUNET_FS_pseudonym_DiscoveryHandle *dh1; 117 struct GNUNET_FS_Pseudonym_DiscoveryHandle *dh1;
116 struct GNUNET_FS_pseudonym_DiscoveryHandle *dh2; 118 struct GNUNET_FS_Pseudonym_DiscoveryHandle *dh2;
117 119
118 memset (m, 'b', sizeof (m)); 120 memset (m, 'b', sizeof (m));
119 m[sizeof (m) - 1] = '\0'; 121 m[sizeof (m) - 1] = '\0';
120
121 GNUNET_log_setup ("test-pseudonym", "WARNING", NULL); 122 GNUNET_log_setup ("test-pseudonym", "WARNING", NULL);
122 ok = GNUNET_YES; 123 ok = GNUNET_YES;
123 (void) GNUNET_DISK_directory_remove ("/tmp/gnunet-pseudonym-test"); 124 (void) GNUNET_DISK_directory_remove ("/tmp/gnunet-pseudonym-test");
@@ -178,8 +179,8 @@ test_io ()
178 CHECK (GNUNET_SYSERR == GNUNET_FS_pseudonym_name_to_id (cfg, name1, &rid1)); 179 CHECK (GNUNET_SYSERR == GNUNET_FS_pseudonym_name_to_id (cfg, name1, &rid1));
179 CHECK (GNUNET_OK == GNUNET_FS_pseudonym_name_to_id (cfg, name2_unique, &rid2)); 180 CHECK (GNUNET_OK == GNUNET_FS_pseudonym_name_to_id (cfg, name2_unique, &rid2));
180 CHECK (GNUNET_OK == GNUNET_FS_pseudonym_name_to_id (cfg, name1_unique, &rid1)); 181 CHECK (GNUNET_OK == GNUNET_FS_pseudonym_name_to_id (cfg, name1_unique, &rid1));
181 CHECK (0 == memcmp (&id1, &rid1, sizeof (struct GNUNET_FS_PseudonymIdentifier))); 182 CHECK (0 == memcmp (&id1, &rid1, sizeof (struct GNUNET_CRYPTO_EccPublicKey)));
182 CHECK (0 == memcmp (&id2, &rid2, sizeof (struct GNUNET_FS_PseudonymIdentifier))); 183 CHECK (0 == memcmp (&id2, &rid2, sizeof (struct GNUNET_CRYPTO_EccPublicKey)));
183 184
184 create_pseu (&fid); 185 create_pseu (&fid);
185 GNUNET_log_skip (1, GNUNET_NO); 186 GNUNET_log_skip (1, GNUNET_NO);
@@ -207,119 +208,12 @@ FAILURE:
207} 208}
208 209
209 210
210/**
211 * Use the given input to sign and check the resulting signature.
212 */
213static void
214test_signature (struct GNUNET_FS_PseudonymHandle *ph,
215 struct GNUNET_FS_PseudonymSignaturePurpose *purpose,
216 struct GNUNET_HashCode *seed,
217 struct GNUNET_HashCode *signing_key,
218 char *bit)
219{
220 struct GNUNET_FS_PseudonymSignature signature;
221 struct GNUNET_FS_PseudonymSignature signature2;
222 struct GNUNET_FS_PseudonymIdentifier pseudonym;
223 struct GNUNET_FS_PseudonymIdentifier verification_key;
224
225 GNUNET_FS_pseudonym_sign (ph, purpose, seed, signing_key, &signature);
226 GNUNET_FS_pseudonym_sign (ph, purpose, seed, signing_key, &signature2);
227 /* with seed, two sigs must be identical, without, they must be different! */
228 if (NULL != seed)
229 GNUNET_break (0 == memcmp (&signature, &signature2, sizeof (signature)));
230 else /* crypto not implemented, thus for now 'break' */
231 GNUNET_break (0 != memcmp (&signature, &signature2, sizeof (signature)));
232 GNUNET_FS_pseudonym_get_identifier (ph, &pseudonym);
233 GNUNET_FS_pseudonym_derive_verification_key (&pseudonym,
234 signing_key,
235 &verification_key);
236 GNUNET_break (GNUNET_OK ==
237 GNUNET_FS_pseudonym_verify (purpose, &signature, &verification_key));
238 /* also check that if the data is changed, the signature no longer matches */
239 (*bit)++;
240 GNUNET_log_skip (1, GNUNET_NO);
241 /* crypto not implemented, thus for now 'break' */
242 GNUNET_break (GNUNET_OK !=
243 GNUNET_FS_pseudonym_verify (purpose, &signature, &verification_key));
244 (*bit)--;
245}
246
247
248/**
249 * Test cryptographic operations for a given private key.
250 *
251 * @param ph private key to test
252 */
253static void
254test_crypto_ops (struct GNUNET_FS_PseudonymHandle *ph)
255{
256 char data[16];
257 struct GNUNET_FS_PseudonymSignaturePurpose *purpose;
258 struct GNUNET_HashCode seed;
259 struct GNUNET_HashCode signing_key;
260
261 memset (data, 42, sizeof (data));
262 purpose = (struct GNUNET_FS_PseudonymSignaturePurpose *) data;
263 purpose->size = htonl (sizeof (data));
264 purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
265 memset (&seed, 41, sizeof (seed));
266 memset (&signing_key, 40, sizeof (signing_key));
267 test_signature (ph, purpose, &seed,
268 &signing_key, &data[sizeof (struct GNUNET_FS_PseudonymSignaturePurpose)]);
269 test_signature (ph, purpose, NULL,
270 &signing_key, &data[sizeof (struct GNUNET_FS_PseudonymSignaturePurpose)]);
271}
272
273
274/**
275 * Test cryptographic operations.
276 */
277static int
278test_crypto ()
279{
280 struct GNUNET_FS_PseudonymHandle *ph;
281 struct GNUNET_FS_PseudonymIdentifier pseudonym;
282 struct GNUNET_FS_PseudonymIdentifier pseudonym2;
283
284 /* check writing to and reading from disk */
285 ph = GNUNET_FS_pseudonym_create ("/tmp/gnunet-pseudonym-test/pseu.dsa");
286 GNUNET_FS_pseudonym_get_identifier (ph, &pseudonym);
287 GNUNET_FS_pseudonym_destroy (ph);
288 ph = GNUNET_FS_pseudonym_create ("/tmp/gnunet-pseudonym-test/pseu.dsa");
289 GNUNET_FS_pseudonym_get_identifier (ph, &pseudonym2);
290 test_crypto_ops (ph);
291 GNUNET_FS_pseudonym_destroy (ph);
292 if (0 != memcmp (&pseudonym, &pseudonym2, sizeof (pseudonym)))
293 return 1;
294
295 /* check in-memory generation */
296 ph = GNUNET_FS_pseudonym_create (NULL);
297 GNUNET_FS_pseudonym_get_identifier (ph, &pseudonym2);
298 if (0 == memcmp (&pseudonym, &pseudonym2, sizeof (pseudonym)))
299 return 1;
300 test_crypto_ops (ph);
301 GNUNET_FS_pseudonym_destroy (ph);
302
303 /* check anonymous pseudonym operations generation */
304 fprintf (stderr, "Checking anonymous ops\n");
305 ph = GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle ();
306 GNUNET_FS_pseudonym_get_identifier (ph, &pseudonym2);
307 if (0 == memcmp (&pseudonym, &pseudonym2, sizeof (pseudonym)))
308 return 1;
309 test_crypto_ops (ph);
310 GNUNET_FS_pseudonym_destroy (ph);
311 return 0;
312}
313
314
315int 211int
316main (int argc, char *argv[]) 212main (int argc, char *argv[])
317{ 213{
318 GNUNET_log_setup ("test-pseudonym", "WARNING", NULL); 214 GNUNET_log_setup ("test-pseudonym", "WARNING", NULL);
319 if (0 != test_io ()) 215 if (0 != test_io ())
320 return 1; 216 return 1;
321 if (0 != test_crypto ())
322 return 1;
323 GNUNET_break (GNUNET_OK == 217 GNUNET_break (GNUNET_OK ==
324 GNUNET_DISK_directory_remove ("/tmp/gnunet-pseudonym-test")); 218 GNUNET_DISK_directory_remove ("/tmp/gnunet-pseudonym-test"));
325 return 0; 219 return 0;