aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/man/gnunet-pseudonym.131
-rw-r--r--src/Makefile.am1
-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
-rw-r--r--src/identity/identity_api.c25
-rw-r--r--src/include/block_fs.h9
-rw-r--r--src/include/gnunet_crypto_lib.h12
-rw-r--r--src/include/gnunet_fs_service.h375
-rw-r--r--src/include/gnunet_identity_service.h13
-rw-r--r--src/util/crypto_ecc.c25
27 files changed, 1270 insertions, 2667 deletions
diff --git a/doc/man/gnunet-pseudonym.1 b/doc/man/gnunet-pseudonym.1
index 1e6de87af..6254283ad 100644
--- a/doc/man/gnunet-pseudonym.1
+++ b/doc/man/gnunet-pseudonym.1
@@ -1,18 +1,18 @@
1.TH GNUNET-PSEUDONYM "1" "25 Feb 2012" "GNUnet" 1.TH GNUNET-PSEUDONYM "1" "6 Aug 2013" "GNUnet"
2.SH NAME 2.SH NAME
3gnunet\-pseudonym \- create, delete or list pseudonyms 3gnunet\-pseudonym \- advertise or list pseudonyms
4.SH SYNOPSIS 4.SH SYNOPSIS
5.B gnunet\-pseudonym 5.B gnunet\-pseudonym
6[options] 6[options]
7.SH DESCRIPTION 7.SH DESCRIPTION
8.PP 8.PP
9gnunet\-pseudonym is a tool for managing pseudonyms and namespaces. A pseudonym is the persona that controls a namespace. As such, it is identical to a public\-private RSA key pair. A namespace is a collection of files that have been signed by the corresponding private RSA key. A namespace is typically associated with a nickname and other metadata. 9gnunet\-pseudonym is a tool for advertising pseudonyms. A pseudonym is the persona that controls a namespace. As such, it is identical to a public\-private ECC key pair. A namespace is a collection of files that have been signed by the corresponding private ECC key. A namespace is typically associated with a nickname and other metadata.
10 10
11Namespaces are an important tool for providing assurances about content integrity and authenticity in GNUnet. Since all of the content in the namespace must have been provided by the same entity, users can form an opinion about that entity and learn to search (or avoid) certain namespaces. 11Namespaces are an important tool for providing assurances about content integrity and authenticity in GNUnet. Since all of the content in the namespace must have been provided by the same entity, users can form an opinion about that entity and learn to search (or avoid) certain namespaces.
12 12
13gnunet\-pseudonym can be used to list all of the pseudonyms that were created locally, to create new pseudonyms, to delete existing pseudonyms (the namespace will continue to exist, but it will be impossible to add additional data to it) and to list all of the namespaces (with their meta-data) known to the local user. By default, gnunet\-pseudonym lists all pseudonyms that were discovered so far. 13gnunet\-pseudonym can be used to list all of the pseudonyms that were created locally, to advertise namespaces to other users, and to list all of the namespaces (with their meta\-data) known to the local user. By default, gnunet\-pseudonym lists all pseudonyms that were discovered so far.
14 14
15Creating a new pseudonym requires using the \-C option together with a nickname that is to be used for the namespace. Nicknames must be unique for each user, global uniqueness is desirable but not necessary. If two namespaces in GNUnet use the same nickname all GNUnet tools will display the nickname together with a number which ensures that the name becomes locally unique to avoid ambiguity. Additional options can be passed together with the \-C option to provide additional meta\-data that describes the namespace. Possible meta\-data includes the 'realname' of the person controlling the namespace, a description, the mime\-type for content in the namespace (useful if the namespace is dedicated to some specific type of content) and contact information. One important piece of meta\-data that can be specified is the identifier of a document root, that is the name of a file in the namespace that is a portal to the rest of the content. This is useful to help users find this root in the absence of conventions. Note that all of this meta\-data is optional and should never be trusted blindly. 15Advertising a pseudonym requires using the \-A option together with the name of the pseudonym. Names for pseudonyms controlled by the user must be unique. However, names for namespaces of other users may not be globally unique. If two foreign namespaces in GNUnet use the same nickname, all GNUnet tools will display the nickname together with a number which ensures that the name becomes locally unique to avoid ambiguity. Additional options can be passed together with the \-A option to provide additional meta\-data that describes the namespace. Possible meta\-data includes the 'realname' of the person controlling the namespace, a description, the mime\-type for content in the namespace (useful if the namespace is dedicated to some specific type of content) and contact information. One important piece of meta\-data that can be specified is the identifier of a document root, that is the name of a file in the namespace that is a portal to the rest of the content. This is useful to help users find this root in the absence of conventions. Note that all of this meta\-data is optional and should never be trusted blindly.
16 16
17As mentioned before, by default, gnunet\-pseudonym simply lists the meta\-data available for other namespaces. Namespaces can be discovered whenever the peer obtains the namespace advertisement. Namespace advertisements can be found using ordinary keyword\-based searches (by default gnunet\-pseudonym publishes the namespace advertisement under the keyword 'namespace', but the \-k option can be used to specify other keywords) and under the 'empty' identifier of the respective namespace (using a namespace\-search if the namespace ID is already known). 17As mentioned before, by default, gnunet\-pseudonym simply lists the meta\-data available for other namespaces. Namespaces can be discovered whenever the peer obtains the namespace advertisement. Namespace advertisements can be found using ordinary keyword\-based searches (by default gnunet\-pseudonym publishes the namespace advertisement under the keyword 'namespace', but the \-k option can be used to specify other keywords) and under the 'empty' identifier of the respective namespace (using a namespace\-search if the namespace ID is already known).
18 18
@@ -23,12 +23,8 @@ For more details about GNUnet namespaces and content encoding please read the 'E
23set desired level of sender anonymity. Default is 1. 23set desired level of sender anonymity. Default is 1.
24 24
25.TP 25.TP
26\fB\-C NAME\fR, \fB\-\-create=NAME\fR 26\fB\-A NAME\fR, \fB\-\-advertise=NAME\fR
27Creates a new pseudonym with the given NAME or creates a new advertisement for the pseudonym with the given NAME (if the pseudonym already exists). 27Advertise namespace of the pseudonym with the given NAME.
28
29.TP
30\fB\-D NAME\fR, \fB\-\-delete=NAME\fR
31Delete the pseudonym with the given NAME.
32 28
33.TP 29.TP
34\fB\-h\fR, \fB\-\-help\fR 30\fB\-h\fR, \fB\-\-help\fR
@@ -43,10 +39,6 @@ Publish a namespace advertisement under the keyword 'KEYWORD'. Default is 'name
43For the main file (or directory), set the metadata of the given TYPE to the given VALUE. Note that this will not add the respective VALUE to the set of keywords under which the file can be found. 39For the main file (or directory), set the metadata of the given TYPE to the given VALUE. Note that this will not add the respective VALUE to the set of keywords under which the file can be found.
44 40
45.TP 41.TP
46\fB\-o\fR, \fB\-\-only\-local\fR
47display names of local namespaces (those that we can extend with content because we created them)
48
49.TP
50\fB\-p \fIPRIORITY\fR, \fB\-\-prio=\fIPRIORITY\fR 42\fB\-p \fIPRIORITY\fR, \fB\-\-prio=\fIPRIORITY\fR
51Set the priority of the namespace advertisement (default: 365). If the local database is full, GNUnet will discard the content with the lowest ranking. Note that ranks change over time depending on popularity. The default should be high enough to preserve the locally inserted content in favor of content that migrates from other peers. 43Set the priority of the namespace advertisement (default: 365). If the local database is full, GNUnet will discard the content with the lowest ranking. Note that ranks change over time depending on popularity. The default should be high enough to preserve the locally inserted content in favor of content that migrates from other peers.
52 44
@@ -68,10 +60,13 @@ Change the rating for the namespace identified by ID by VALUE. For example, "\-
68 60
69.SH FILES 61.SH FILES
70.TP 62.TP
71~/.gnunet/data/pseudonyms/ 63~/.gnunet/data/pseudonym/
72Directory where the pseudonyms are stored 64Directory where information about non-local pseudonyms is stored
65.TP
66~/.gnunet/fs/updates/
67Directory where information about possible updates to local pseudonyms is stored
73 68
74.SH "REPORTING BUGS" 69.SH "REPORTING BUGS"
75Report bugs by using Mantis <https://gnunet.org/bugs/> or by sending electronic mail to <gnunet\-developers@gnu.org> 70Report bugs by using Mantis <https://gnunet.org/bugs/> or by sending electronic mail to <gnunet\-developers@gnu.org>
76.SH "SEE ALSO" 71.SH "SEE ALSO"
77\fBgnunet\-publish\fP(1), \fBgnunet\-search\fP(1) 72\fBgnunet\-identity\fP(1), \fBgnunet\-publish\fP(1), \fBgnunet\-search\fP(1)
diff --git a/src/Makefile.am b/src/Makefile.am
index 9126815f4..00c4d6f93 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -64,6 +64,7 @@ SUBDIRS = \
64 dns \ 64 dns \
65 identity \ 65 identity \
66 set \ 66 set \
67 fs \
67 $(LINUX_DIR) \ 68 $(LINUX_DIR) \
68 $(MINGW_DIR) \ 69 $(MINGW_DIR) \
69 gns \ 70 gns \
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;
diff --git a/src/identity/identity_api.c b/src/identity/identity_api.c
index 2062ddc63..84ecb8765 100644
--- a/src/identity/identity_api.c
+++ b/src/identity/identity_api.c
@@ -175,6 +175,24 @@ struct GNUNET_IDENTITY_Handle
175}; 175};
176 176
177 177
178/**
179 * Obtain the ego representing 'anonymous' users.
180 */
181const struct GNUNET_IDENTITY_Ego *
182GNUNET_IDENTITY_ego_get_anonymous ()
183{
184 static struct GNUNET_IDENTITY_Ego anon;
185 struct GNUNET_CRYPTO_EccPublicKey pub;
186
187 if (NULL != anon.pk)
188 return &anon;
189 anon.pk = GNUNET_CRYPTO_ecc_key_get_anonymous ();
190 GNUNET_CRYPTO_ecc_key_get_public (anon.pk,
191 &pub);
192 GNUNET_CRYPTO_hash (&pub, sizeof (pub), &anon.id);
193 return &anon;
194}
195
178 196
179/** 197/**
180 * Try again to connect to network size estimation service. 198 * Try again to connect to network size estimation service.
@@ -566,7 +584,7 @@ GNUNET_IDENTITY_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
566 * @return associated ECC key, valid as long as the ego is valid 584 * @return associated ECC key, valid as long as the ego is valid
567 */ 585 */
568const struct GNUNET_CRYPTO_EccPrivateKey * 586const struct GNUNET_CRYPTO_EccPrivateKey *
569GNUNET_IDENTITY_ego_get_private_key (struct GNUNET_IDENTITY_Ego *ego) 587GNUNET_IDENTITY_ego_get_private_key (const struct GNUNET_IDENTITY_Ego *ego)
570{ 588{
571 return ego->pk; 589 return ego->pk;
572} 590}
@@ -579,10 +597,11 @@ GNUNET_IDENTITY_ego_get_private_key (struct GNUNET_IDENTITY_Ego *ego)
579 * @param pk set to ego's public key 597 * @param pk set to ego's public key
580 */ 598 */
581void 599void
582GNUNET_IDENTITY_ego_get_public_key (struct GNUNET_IDENTITY_Ego *ego, 600GNUNET_IDENTITY_ego_get_public_key (const struct GNUNET_IDENTITY_Ego *ego,
583 struct GNUNET_CRYPTO_EccPublicKey *pk) 601 struct GNUNET_CRYPTO_EccPublicKey *pk)
584{ 602{
585 GNUNET_assert (0); 603 GNUNET_CRYPTO_ecc_key_get_public (ego->pk,
604 pk);
586} 605}
587 606
588 607
diff --git a/src/include/block_fs.h b/src/include/block_fs.h
index a2063270e..772180fc8 100644
--- a/src/include/block_fs.h
+++ b/src/include/block_fs.h
@@ -48,18 +48,17 @@ struct UBlock
48 /** 48 /**
49 * Signature using pseudonym and search keyword / identifier. 49 * Signature using pseudonym and search keyword / identifier.
50 */ 50 */
51 struct GNUNET_FS_PseudonymSignature signature; 51 struct GNUNET_CRYPTO_EccSignature signature;
52 52
53 /** 53 /**
54 * What is being signed and why? 54 * What is being signed and why?
55 */ 55 */
56 struct GNUNET_FS_PseudonymSignaturePurpose purpose GNUNET_PACKED; 56 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
57 57
58 /** 58 /**
59 * Public key used to sign this block. Hash of this value 59 * Public key used to sign this block.
60 * is the query.
61 */ 60 */
62 struct GNUNET_FS_PseudonymIdentifier verification_key; 61 struct GNUNET_CRYPTO_EccPublicKey verification_key;
63 62
64 /* rest of the data is encrypted */ 63 /* rest of the data is encrypted */
65 64
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index 5f209efea..52bb983b0 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -884,8 +884,7 @@ GNUNET_CRYPTO_ecc_key_create_from_configuration (const struct GNUNET_CONFIGURATI
884 884
885 885
886/** 886/**
887 * Create a new private key. Caller must free return value. Blocking version 887 * Create a new private key. Caller must free return value.
888 * (blocks to gather entropy).
889 * 888 *
890 * @return fresh private key 889 * @return fresh private key
891 */ 890 */
@@ -894,6 +893,15 @@ GNUNET_CRYPTO_ecc_key_create (void);
894 893
895 894
896/** 895/**
896 * Get the shared private key we use for anonymous users.
897 *
898 * @return "anonymous" private key
899 */
900const struct GNUNET_CRYPTO_EccPrivateKey *
901GNUNET_CRYPTO_ecc_key_get_anonymous (void);
902
903
904/**
897 * Setup a hostkey file for a peer given the name of the 905 * Setup a hostkey file for a peer given the name of the
898 * configuration file (!). This function is used so that 906 * configuration file (!). This function is used so that
899 * at a later point code can be certain that reading a 907 * at a later point code can be certain that reading a
diff --git a/src/include/gnunet_fs_service.h b/src/include/gnunet_fs_service.h
index afe53b0e0..5dcee17cd 100644
--- a/src/include/gnunet_fs_service.h
+++ b/src/include/gnunet_fs_service.h
@@ -26,7 +26,6 @@
26#define GNUNET_FS_LIB_H 26#define GNUNET_FS_LIB_H
27 27
28#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
29#include "gnunet_scheduler_lib.h"
30 29
31#ifdef __cplusplus 30#ifdef __cplusplus
32extern "C" 31extern "C"
@@ -81,78 +80,6 @@ struct GNUNET_FS_Uri;
81 80
82 81
83/** 82/**
84 * Identifier for a GNUnet pseudonym (the public key). Q-point, Q=dP.
85 * Note that we (ab)use an identifier of 'Q=G=1P' to mean the
86 * 'anonymous' pseudonym.
87 */
88struct GNUNET_FS_PseudonymIdentifier
89{
90 /**
91 * Q consists of an x- and a y-value, each mod p (256 bits),
92 * given here in affine coordinates.
93 */
94 unsigned char q_x[256 / 8];
95
96 /**
97 * Q consists of an x- and a y-value, each mod p (256 bits),
98 * given here in affine coordinates.
99 */
100 unsigned char q_y[256 / 8];
101
102};
103
104
105/**
106 * Handle for a pseudonym (private key).
107 */
108struct GNUNET_FS_PseudonymHandle;
109
110
111/**
112 * Signature made with a pseudonym (includes the full public key).
113 * The ECDSA signature is a pair (r,s) with r = x1 mod n where
114 * (x1,y1) = kG for "random" k and s = k^{-1}(z + rd) mod n,
115 * where z is derived from the hash of the message that is being
116 * signed.
117 */
118struct GNUNET_FS_PseudonymSignature
119{
120
121 /**
122 * Who created the signature? (public key of the signer), 'd' value in NIST P-256.
123 */
124 struct GNUNET_FS_PseudonymIdentifier signer;
125
126 /**
127 * Binary ECDSA signature data, r-value. Value is mod n, and n is 256 bits.
128 */
129 unsigned char sig_r[256 / 8];
130
131 /**
132 * Binary ECDSA signature data, s-value. Value is mod n, and n is 256 bits.
133 */
134 unsigned char sig_s[256 / 8];
135};
136
137
138/**
139 * Purpose for signature made with a pseudonym.
140 */
141struct GNUNET_FS_PseudonymSignaturePurpose
142{
143 /**
144 * How many bytes are being signed (including this header)?
145 */
146 uint32_t size;
147
148 /**
149 * What is the context/purpose of the signature?
150 */
151 uint32_t purpose;
152};
153
154
155/**
156 * Iterator over keywords 83 * Iterator over keywords
157 * 84 *
158 * @param cls closure 85 * @param cls closure
@@ -165,120 +92,11 @@ typedef int (*GNUNET_FS_KeywordIterator) (void *cls, const char *keyword,
165 92
166 93
167 94
168
169/**
170 * Create a pseudonym.
171 *
172 * @param filename name of the file to use for storage, NULL for in-memory only
173 * @return handle to the private key of the pseudonym
174 */
175struct GNUNET_FS_PseudonymHandle *
176GNUNET_FS_pseudonym_create (const char *filename);
177
178
179/**
180 * Create a pseudonym, from a file that must already exist.
181 *
182 * @param filename name of the file to use for storage, NULL for in-memory only
183 * @return handle to the private key of the pseudonym
184 */
185struct GNUNET_FS_PseudonymHandle *
186GNUNET_FS_pseudonym_create_from_existing_file (const char *filename);
187
188
189/**
190 * Get the handle for the 'anonymous' pseudonym shared by all users.
191 * That pseudonym uses a fixed 'secret' for the private key; this
192 * construction is useful to make anonymous and pseudonymous APIs
193 * (and packets) indistinguishable on the network. See #2564.
194 *
195 * @return handle to the (non-secret) private key of the 'anonymous' pseudonym
196 */
197struct GNUNET_FS_PseudonymHandle *
198GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle (void);
199
200
201/**
202 * Destroy a pseudonym handle. Does NOT remove the private key from
203 * the disk.
204 *
205 * @param ph pseudonym handle to destroy
206 */
207void
208GNUNET_FS_pseudonym_destroy (struct GNUNET_FS_PseudonymHandle *ph);
209
210
211/**
212 * Cryptographically sign some data with the pseudonym.
213 *
214 * @param ph private key used for signing (corresponds to 'x' in #2564)
215 * @param purpose data to sign
216 * @param seed hash of the plaintext of the data that we are signing,
217 * used for deterministic PRNG for anonymous signing;
218 * corresponds to 'k' in section 2.7 of #2564
219 * @param signing_key modifier to apply to the private key for signing;
220 * corresponds to 'h' in section 2.3 of #2564.
221 * @param signature where to store the signature
222 * @return GNUNET_SYSERR on failure
223 */
224int
225GNUNET_FS_pseudonym_sign (struct GNUNET_FS_PseudonymHandle *ph,
226 const struct GNUNET_FS_PseudonymSignaturePurpose *purpose,
227 const struct GNUNET_HashCode *seed,
228 const struct GNUNET_HashCode *signing_key,
229 struct GNUNET_FS_PseudonymSignature *signature);
230
231
232/**
233 * Given a pseudonym and a signing key, derive the corresponding public
234 * key that would be used to verify the resulting signature.
235 *
236 * @param pseudonym the public key (g^x in DSA, dQ in ECDSA)
237 * @param signing_key input to derive 'h' (see section 2.4 of #2564)
238 * @param verification_key resulting public key to verify the signature
239 * created from the 'ph' of 'pseudonym' and the 'signing_key';
240 * the value stored here can then be given to GNUNET_FS_pseudonym_verify.
241 * @return GNUNET_OK on success, GNUNET_SYSERR on error
242 */
243int
244GNUNET_FS_pseudonym_derive_verification_key (struct GNUNET_FS_PseudonymIdentifier *pseudonym,
245 const struct GNUNET_HashCode *signing_key,
246 struct GNUNET_FS_PseudonymIdentifier *verification_key);
247
248
249/**
250 * Verify a signature made with a pseudonym.
251 *
252 * @param purpose data that was signed
253 * @param signature signature to verify
254 * @param verification_key public key to use for checking the signature;
255 * corresponds to 'g^(x+h)' in section 2.4 of #2564.
256 * @return GNUNET_OK on success (signature valid, 'pseudonym' set),
257 * GNUNET_SYSERR if the signature is invalid
258 */
259int
260GNUNET_FS_pseudonym_verify (const struct GNUNET_FS_PseudonymSignaturePurpose *purpose,
261 const struct GNUNET_FS_PseudonymSignature *signature,
262 const struct GNUNET_FS_PseudonymIdentifier *verification_key);
263
264
265/**
266 * Get the identifier (public key) of a pseudonym.
267 *
268 * @param ph pseudonym handle with the private key
269 * @param pseudonym pseudonym identifier (set based on 'ph')
270 */
271void
272GNUNET_FS_pseudonym_get_identifier (struct GNUNET_FS_PseudonymHandle *ph,
273 struct GNUNET_FS_PseudonymIdentifier *pseudonym);
274
275
276
277/** 95/**
278 * Iterator over all known pseudonyms. 96 * Iterator over all known pseudonyms.
279 * 97 *
280 * @param cls closure 98 * @param cls closure
281 * @param pseudonym hash code of public key of pseudonym 99 * @param pseudonym public key of pseudonym
282 * @param name name of the pseudonym (might be NULL) 100 * @param name name of the pseudonym (might be NULL)
283 * @param unique_name unique name of the pseudonym (might be NULL) 101 * @param unique_name unique name of the pseudonym (might be NULL)
284 * @param md meta data known about the pseudonym 102 * @param md meta data known about the pseudonym
@@ -286,11 +104,11 @@ GNUNET_FS_pseudonym_get_identifier (struct GNUNET_FS_PseudonymHandle *ph,
286 * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort 104 * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort
287 */ 105 */
288typedef int (*GNUNET_FS_PseudonymIterator) (void *cls, 106typedef int (*GNUNET_FS_PseudonymIterator) (void *cls,
289 const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 107 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
290 const char *name, 108 const char *name,
291 const char *unique_name, 109 const char *unique_name,
292 const struct GNUNET_CONTAINER_MetaData *md, 110 const struct GNUNET_CONTAINER_MetaData *md,
293 int32_t rating); 111 int32_t rating);
294 112
295 113
296/** 114/**
@@ -303,7 +121,7 @@ typedef int (*GNUNET_FS_PseudonymIterator) (void *cls,
303 */ 121 */
304int 122int
305GNUNET_FS_pseudonym_rank (const struct GNUNET_CONFIGURATION_Handle *cfg, 123GNUNET_FS_pseudonym_rank (const struct GNUNET_CONFIGURATION_Handle *cfg,
306 const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 124 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
307 int32_t delta); 125 int32_t delta);
308 126
309 127
@@ -319,7 +137,7 @@ GNUNET_FS_pseudonym_rank (const struct GNUNET_CONFIGURATION_Handle *cfg,
319 */ 137 */
320int 138int
321GNUNET_FS_pseudonym_add (const struct GNUNET_CONFIGURATION_Handle *cfg, 139GNUNET_FS_pseudonym_add (const struct GNUNET_CONFIGURATION_Handle *cfg,
322 const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 140 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
323 const struct GNUNET_CONTAINER_MetaData *meta); 141 const struct GNUNET_CONTAINER_MetaData *meta);
324 142
325 143
@@ -340,7 +158,7 @@ GNUNET_FS_pseudonym_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg,
340/** 158/**
341 * Handle for a discovery callback registration. 159 * Handle for a discovery callback registration.
342 */ 160 */
343struct GNUNET_FS_pseudonym_DiscoveryHandle; 161struct GNUNET_FS_Pseudonym_DiscoveryHandle;
344 162
345 163
346/** 164/**
@@ -352,7 +170,7 @@ struct GNUNET_FS_pseudonym_DiscoveryHandle;
352 * @param iterator_cls closure for iterator 170 * @param iterator_cls closure for iterator
353 * @return registration handle 171 * @return registration handle
354 */ 172 */
355struct GNUNET_FS_pseudonym_DiscoveryHandle * 173struct GNUNET_FS_Pseudonym_DiscoveryHandle *
356GNUNET_FS_pseudonym_discovery_callback_register (const struct GNUNET_CONFIGURATION_Handle *cfg, 174GNUNET_FS_pseudonym_discovery_callback_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
357 GNUNET_FS_PseudonymIterator iterator, 175 GNUNET_FS_PseudonymIterator iterator,
358 void *iterator_cls); 176 void *iterator_cls);
@@ -364,7 +182,7 @@ GNUNET_FS_pseudonym_discovery_callback_register (const struct GNUNET_CONFIGURATI
364 * @param dh registration to unregister 182 * @param dh registration to unregister
365 */ 183 */
366void 184void
367GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_pseudonym_DiscoveryHandle *dh); 185GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_Pseudonym_DiscoveryHandle *dh);
368 186
369 187
370/** 188/**
@@ -380,7 +198,7 @@ GNUNET_FS_pseudonym_discovery_callback_unregister (struct GNUNET_FS_pseudonym_Di
380 */ 198 */
381char * 199char *
382GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, 200GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg,
383 const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 201 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
384 const char *name, 202 const char *name,
385 unsigned int *suffix); 203 unsigned int *suffix);
386 204
@@ -407,7 +225,7 @@ GNUNET_FS_pseudonym_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg
407 */ 225 */
408int 226int
409GNUNET_FS_pseudonym_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, 227GNUNET_FS_pseudonym_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
410 const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 228 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
411 struct GNUNET_CONTAINER_MetaData **ret_meta, 229 struct GNUNET_CONTAINER_MetaData **ret_meta,
412 int32_t *ret_rank, 230 int32_t *ret_rank,
413 char **ret_name, 231 char **ret_name,
@@ -425,7 +243,7 @@ GNUNET_FS_pseudonym_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
425int 243int
426GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, 244GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
427 const char *ns_uname, 245 const char *ns_uname,
428 struct GNUNET_FS_PseudonymIdentifier *pseudonym); 246 struct GNUNET_CRYPTO_EccPublicKey *pseudonym);
429 247
430 248
431/** 249/**
@@ -442,25 +260,13 @@ GNUNET_FS_pseudonym_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg,
442 */ 260 */
443int 261int
444GNUNET_FS_pseudonym_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg, 262GNUNET_FS_pseudonym_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
445 const struct GNUNET_FS_PseudonymIdentifier *pseudonym, 263 const struct GNUNET_CRYPTO_EccPublicKey *pseudonym,
446 const char *name, 264 const char *name,
447 const struct GNUNET_CONTAINER_MetaData *md, 265 const struct GNUNET_CONTAINER_MetaData *md,
448 int32_t rank); 266 int32_t rank);
449 267
450 268
451/** 269/**
452 * Remove pseudonym from the set of known pseudonyms.
453 *
454 * @param cfg overall configuration
455 * @param id the pseudonym identifier
456 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
457 */
458int
459GNUNET_FS_pseudonym_remove (const struct GNUNET_CONFIGURATION_Handle *cfg,
460 const struct GNUNET_FS_PseudonymIdentifier *id);
461
462
463/**
464 * Get a unique key from a URI. This is for putting URIs 270 * Get a unique key from a URI. This is for putting URIs
465 * into HashMaps. The key may change between FS implementations. 271 * into HashMaps. The key may change between FS implementations.
466 * 272 *
@@ -468,7 +274,8 @@ GNUNET_FS_pseudonym_remove (const struct GNUNET_CONFIGURATION_Handle *cfg,
468 * @param key wherer to store the unique key 274 * @param key wherer to store the unique key
469 */ 275 */
470void 276void
471GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri, struct GNUNET_HashCode * key); 277GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri,
278 struct GNUNET_HashCode *key);
472 279
473 280
474/** 281/**
@@ -501,7 +308,8 @@ GNUNET_FS_uri_ksk_to_string_fancy (const struct GNUNET_FS_Uri *uri);
501 * @param is_mandatory is this keyword mandatory? 308 * @param is_mandatory is this keyword mandatory?
502 */ 309 */
503void 310void
504GNUNET_FS_uri_ksk_add_keyword (struct GNUNET_FS_Uri *uri, const char *keyword, 311GNUNET_FS_uri_ksk_add_keyword (struct GNUNET_FS_Uri *uri,
312 const char *keyword,
505 int is_mandatory); 313 int is_mandatory);
506 314
507 315
@@ -695,34 +503,15 @@ GNUNET_FS_uri_test_sks (const struct GNUNET_FS_Uri *uri);
695 503
696 504
697/** 505/**
698 * Handle to one of our namespaces.
699 */
700struct GNUNET_FS_Namespace;
701
702
703/**
704 * Create an SKS URI from a namespace and an identifier.
705 *
706 * @param ns namespace
707 * @param id identifier
708 * @param emsg where to store an error message
709 * @return an FS URI for the given namespace and identifier
710 */
711struct GNUNET_FS_Uri *
712GNUNET_FS_uri_sks_create (struct GNUNET_FS_Namespace *ns, const char *id,
713 char **emsg);
714
715
716/**
717 * Create an SKS URI from a namespace ID and an identifier. 506 * Create an SKS URI from a namespace ID and an identifier.
718 * 507 *
719 * @param pseudonym pseudonym to use 508 * @param ns pseudonym to use
720 * @param id identifier 509 * @param id identifier
721 * @return an FS URI for the given namespace and identifier 510 * @return an FS URI for the given namespace and identifier
722 */ 511 */
723struct GNUNET_FS_Uri * 512struct GNUNET_FS_Uri *
724GNUNET_FS_uri_sks_create_from_nsid (struct GNUNET_FS_PseudonymIdentifier *pseudonym, 513GNUNET_FS_uri_sks_create (const struct GNUNET_CRYPTO_EccPublicKey *ns,
725 const char *id); 514 const char *id);
726 515
727 516
728/** 517/**
@@ -735,7 +524,7 @@ GNUNET_FS_uri_sks_create_from_nsid (struct GNUNET_FS_PseudonymIdentifier *pseudo
735 */ 524 */
736int 525int
737GNUNET_FS_uri_sks_get_namespace (const struct GNUNET_FS_Uri *uri, 526GNUNET_FS_uri_sks_get_namespace (const struct GNUNET_FS_Uri *uri,
738 struct GNUNET_FS_PseudonymIdentifier *pseudonym); 527 struct GNUNET_CRYPTO_EccPublicKey *pseudonym);
739 528
740 529
741/** 530/**
@@ -1757,12 +1546,6 @@ struct GNUNET_FS_ProgressInfo
1757 { 1546 {
1758 1547
1759 /** 1548 /**
1760 * Handle to the namespace (NULL if it is not a local
1761 * namespace).
1762 */
1763 struct GNUNET_FS_Namespace *ns;
1764
1765 /**
1766 * Short, human-readable name of the namespace. 1549 * Short, human-readable name of the namespace.
1767 */ 1550 */
1768 const char *name; 1551 const char *name;
@@ -1780,7 +1563,7 @@ struct GNUNET_FS_ProgressInfo
1780 /** 1563 /**
1781 * Public key of the namespace. 1564 * Public key of the namespace.
1782 */ 1565 */
1783 struct GNUNET_FS_PseudonymIdentifier pseudonym; 1566 struct GNUNET_CRYPTO_EccPublicKey pseudonym;
1784 1567
1785 } ns; 1568 } ns;
1786 1569
@@ -2379,6 +2162,7 @@ enum GNUNET_FS_PublishOptions
2379 GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY = 1 2162 GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY = 1
2380}; 2163};
2381 2164
2165
2382/** 2166/**
2383 * Publish a file or directory. 2167 * Publish a file or directory.
2384 * 2168 *
@@ -2395,7 +2179,8 @@ enum GNUNET_FS_PublishOptions
2395struct GNUNET_FS_PublishContext * 2179struct GNUNET_FS_PublishContext *
2396GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h, 2180GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h,
2397 struct GNUNET_FS_FileInformation *fi, 2181 struct GNUNET_FS_FileInformation *fi,
2398 struct GNUNET_FS_Namespace *ns, const char *nid, 2182 const struct GNUNET_CRYPTO_EccPrivateKey *ns,
2183 const char *nid,
2399 const char *nuid, 2184 const char *nuid,
2400 enum GNUNET_FS_PublishOptions options); 2185 enum GNUNET_FS_PublishOptions options);
2401 2186
@@ -2421,7 +2206,7 @@ GNUNET_FS_publish_stop (struct GNUNET_FS_PublishContext *pc);
2421 * @param emsg error message, NULL on success 2206 * @param emsg error message, NULL on success
2422 */ 2207 */
2423typedef void (*GNUNET_FS_PublishContinuation) (void *cls, 2208typedef void (*GNUNET_FS_PublishContinuation) (void *cls,
2424 const struct GNUNET_FS_Uri * uri, 2209 const struct GNUNET_FS_Uri *uri,
2425 const char *emsg); 2210 const char *emsg);
2426 2211
2427 2212
@@ -2486,7 +2271,7 @@ struct GNUNET_FS_PublishSksContext;
2486 */ 2271 */
2487struct GNUNET_FS_PublishSksContext * 2272struct GNUNET_FS_PublishSksContext *
2488GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, 2273GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
2489 struct GNUNET_FS_Namespace *ns, 2274 const struct GNUNET_CRYPTO_EccPrivateKey *ns,
2490 const char *identifier, const char *update, 2275 const char *identifier, const char *update,
2491 const struct GNUNET_CONTAINER_MetaData *meta, 2276 const struct GNUNET_CONTAINER_MetaData *meta,
2492 const struct GNUNET_FS_Uri *uri, 2277 const struct GNUNET_FS_Uri *uri,
@@ -2568,110 +2353,6 @@ GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc);
2568 2353
2569 2354
2570/** 2355/**
2571 * Create a namespace with the given name; if one already
2572 * exists, return a handle to the existing namespace.
2573 *
2574 * @param h handle to the file sharing subsystem
2575 * @param name name to use for the namespace
2576 * @return handle to the namespace, NULL on error (i.e. invalid filename)
2577 */
2578struct GNUNET_FS_Namespace *
2579GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h, const char *name);
2580
2581
2582/**
2583 * Open the namespace with the given name; if it does not exist,
2584 * or the key file is corrupted, the function fails.
2585 *
2586 * @param h handle to the file sharing subsystem
2587 * @param name name of the namespace
2588 * @return handle to the namespace,
2589 * NULL on error (i.e. invalid filename, non-existent filename)
2590 */
2591struct GNUNET_FS_Namespace *
2592GNUNET_FS_namespace_open_existing (struct GNUNET_FS_Handle *h, const char *name);
2593
2594
2595/**
2596 * Rename a local namespace.
2597 *
2598 * @param h handle to the file sharing subsystem
2599 * @param old_name old name of the namespace
2600 * @param new_name new name of the namespace
2601 * @return GNUNET_OK on success, GNUNET_SYSERR on error (see errno for details)
2602 */
2603int
2604GNUNET_FS_namespace_rename (struct GNUNET_FS_Handle *h,
2605 const char *old_name,
2606 const char *new_name);
2607
2608
2609/**
2610 * Duplicate a namespace handle.
2611 *
2612 * @param ns namespace handle
2613 * @return duplicated handle to the namespace
2614 */
2615struct GNUNET_FS_Namespace *
2616GNUNET_FS_namespace_dup (struct GNUNET_FS_Namespace *ns);
2617
2618
2619/**
2620 * Get hash of the public key of a namespace.
2621 *
2622 * @param ns namespace
2623 * @param id buffer to store the key in
2624 * @return GNUNET_OK on success
2625 * GNUNET_SYSERR on failure (contents of id remain intact)
2626 */
2627int
2628GNUNET_FS_namespace_get_public_identifier (struct GNUNET_FS_Namespace *ns,
2629 struct GNUNET_FS_PseudonymIdentifier *id);
2630
2631
2632/**
2633 * Delete a namespace handle. Can be used for a clean shutdown (free
2634 * memory) or also to freeze the namespace to prevent further
2635 * insertions by anyone.
2636 *
2637 * @param ns handle to the namespace that should be deleted / freed
2638 * @param freeze prevents future insertions; creating a namespace
2639 * with the same name again will create a fresh namespace instead
2640 *
2641 * @return GNUNET_OK on success, GNUNET_SYSERR on error
2642 */
2643int
2644GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *ns, int freeze);
2645
2646
2647/**
2648 * Callback with information about local (!) namespaces.
2649 * Contains the names of the local namespace and the global
2650 * ID.
2651 *
2652 * @param cls closure
2653 * @param name human-readable identifier of the namespace
2654 * @param id identifier for the namespace
2655 */
2656typedef void (*GNUNET_FS_NamespaceInfoProcessor) (void *cls, const char *name,
2657 const struct GNUNET_FS_PseudonymIdentifier *id);
2658
2659
2660/**
2661 * Build a list of all available local (!) namespaces The returned
2662 * names are only the nicknames since we only iterate over the local
2663 * namespaces.
2664 *
2665 * @param h handle to the file sharing subsystem
2666 * @param cb function to call on each known namespace
2667 * @param cb_cls closure for cb
2668 */
2669void
2670GNUNET_FS_namespace_list (struct GNUNET_FS_Handle *h,
2671 GNUNET_FS_NamespaceInfoProcessor cb, void *cb_cls);
2672
2673
2674/**
2675 * Function called on updateable identifiers. 2356 * Function called on updateable identifiers.
2676 * 2357 *
2677 * @param cls closure 2358 * @param cls closure
@@ -2703,13 +2384,15 @@ typedef void (*GNUNET_FS_IdentifierProcessor) (void *cls, const char *last_id,
2703 * cause the library to call "ip" with all children of the node. Note 2384 * cause the library to call "ip" with all children of the node. Note
2704 * that cycles within an SCC are possible (including self-loops). 2385 * that cycles within an SCC are possible (including self-loops).
2705 * 2386 *
2387* @param h fs handle to use
2706 * @param ns namespace to inspect for updateable content 2388 * @param ns namespace to inspect for updateable content
2707 * @param next_id ID to look for; use NULL to look for SCC roots 2389 * @param next_id ID to look for; use NULL to look for SCC roots
2708 * @param ip function to call on each updateable identifier 2390 * @param ip function to call on each updateable identifier
2709 * @param ip_cls closure for ip 2391 * @param ip_cls closure for ip
2710 */ 2392 */
2711void 2393void
2712GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns, 2394GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Handle *h,
2395 const struct GNUNET_CRYPTO_EccPrivateKey *ns,
2713 const char *next_id, 2396 const char *next_id,
2714 GNUNET_FS_IdentifierProcessor ip, 2397 GNUNET_FS_IdentifierProcessor ip,
2715 void *ip_cls); 2398 void *ip_cls);
diff --git a/src/include/gnunet_identity_service.h b/src/include/gnunet_identity_service.h
index dfc643d22..23dee600f 100644
--- a/src/include/gnunet_identity_service.h
+++ b/src/include/gnunet_identity_service.h
@@ -74,7 +74,16 @@ struct GNUNET_IDENTITY_Operation;
74 * @return associated ECC key, valid as long as the ego is valid 74 * @return associated ECC key, valid as long as the ego is valid
75 */ 75 */
76const struct GNUNET_CRYPTO_EccPrivateKey * 76const struct GNUNET_CRYPTO_EccPrivateKey *
77GNUNET_IDENTITY_ego_get_private_key (struct GNUNET_IDENTITY_Ego *ego); 77GNUNET_IDENTITY_ego_get_private_key (const struct GNUNET_IDENTITY_Ego *ego);
78
79
80/**
81 * Obtain the ego representing 'anonymous' users.
82 *
83 * @returns handle for the anonymous user, must not be freed
84 */
85const struct GNUNET_IDENTITY_Ego *
86GNUNET_IDENTITY_ego_get_anonymous (void);
78 87
79 88
80/** 89/**
@@ -84,7 +93,7 @@ GNUNET_IDENTITY_ego_get_private_key (struct GNUNET_IDENTITY_Ego *ego);
84 * @param pk set to ego's public key 93 * @param pk set to ego's public key
85 */ 94 */
86void 95void
87GNUNET_IDENTITY_ego_get_public_key (struct GNUNET_IDENTITY_Ego *ego, 96GNUNET_IDENTITY_ego_get_public_key (const struct GNUNET_IDENTITY_Ego *ego,
88 struct GNUNET_CRYPTO_EccPublicKey *pk); 97 struct GNUNET_CRYPTO_EccPublicKey *pk);
89 98
90 99
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index a93512e38..122c1857d 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -446,6 +446,31 @@ GNUNET_CRYPTO_ecc_key_create ()
446 446
447 447
448/** 448/**
449 * Get the shared private key we use for anonymous users.
450 *
451 * @return "anonymous" private key
452 */
453const struct GNUNET_CRYPTO_EccPrivateKey *
454GNUNET_CRYPTO_ecc_key_get_anonymous ()
455{
456 /**
457 * 'anonymous' pseudonym (global static, d=1, public key = G
458 * (generator).
459 */
460 static struct GNUNET_CRYPTO_EccPrivateKey anonymous;
461 static int once;
462
463 if (once)
464 return &anonymous;
465 mpi_print (anonymous.d,
466 sizeof (anonymous.d),
467 GCRYMPI_CONST_ONE);
468 once = 1;
469 return &anonymous;
470}
471
472
473/**
449 * Wait for a short time (we're trying to lock a file or want 474 * Wait for a short time (we're trying to lock a file or want
450 * to give another process a shot at finishing a disk write, etc.). 475 * to give another process a shot at finishing a disk write, etc.).
451 * Sleeps for 100ms (as that should be long enough for virtually all 476 * Sleeps for 100ms (as that should be long enough for virtually all