aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_publish_ublock.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/fs_publish_ublock.c')
-rw-r--r--src/fs/fs_publish_ublock.c324
1 files changed, 0 insertions, 324 deletions
diff --git a/src/fs/fs_publish_ublock.c b/src/fs/fs_publish_ublock.c
deleted file mode 100644
index fd6f2bd72..000000000
--- a/src/fs/fs_publish_ublock.c
+++ /dev/null
@@ -1,324 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2012, 2013 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file 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 * Derive the key for symmetric encryption/decryption from
38 * the public key and the label.
39 *
40 * @param skey where to store symmetric key
41 * @param iv where to store the IV
42 * @param label label to use for key derivation
43 * @param pub public key to use for key derivation
44 */
45static void
46derive_ublock_encryption_key (struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
47 struct GNUNET_CRYPTO_SymmetricInitializationVector
48 *iv,
49 const char *label,
50 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
51{
52 struct GNUNET_HashCode key;
53
54 /* derive key from 'label' and public key of the namespace */
55 GNUNET_assert (GNUNET_YES ==
56 GNUNET_CRYPTO_kdf (&key, sizeof(key),
57 "UBLOCK-ENC", strlen ("UBLOCK-ENC"),
58 label, strlen (label),
59 pub, sizeof(*pub),
60 NULL, 0));
61 GNUNET_CRYPTO_hash_to_aes_key (&key, skey, iv);
62}
63
64
65/**
66 * Decrypt the given UBlock, storing the result in output.
67 *
68 * @param input input data
69 * @param input_len number of bytes in @a input
70 * @param ns public key under which the UBlock was stored
71 * @param label label under which the UBlock was stored
72 * @param output where to write the result, has input_len bytes
73 */
74void
75GNUNET_FS_ublock_decrypt_ (const void *input,
76 size_t input_len,
77 const struct GNUNET_CRYPTO_EcdsaPublicKey *ns,
78 const char *label,
79 void *output)
80{
81 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
82 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
83
84 derive_ublock_encryption_key (&skey, &iv,
85 label, ns);
86 GNUNET_CRYPTO_symmetric_decrypt (input, input_len,
87 &skey, &iv,
88 output);
89}
90
91
92/**
93 * Context for 'ublock_put_cont'.
94 */
95struct GNUNET_FS_PublishUblockContext
96{
97 /**
98 * Function to call when done.
99 */
100 GNUNET_FS_UBlockContinuation cont;
101
102 /**
103 * Closure of 'cont'.
104 */
105 void *cont_cls;
106
107 /**
108 * Handle for active datastore operation.
109 */
110 struct GNUNET_DATASTORE_QueueEntry *qre;
111
112 /**
113 * Task to run continuation asynchronously.
114 */
115 struct GNUNET_SCHEDULER_Task *task;
116};
117
118
119/**
120 * Continuation of #GNUNET_FS_publish_ublock_().
121 *
122 * @param cls closure of type "struct GNUNET_FS_PublishUblockContext*"
123 * @param success #GNUNET_SYSERR on failure (including timeout/queue drop)
124 * #GNUNET_NO if content was already there
125 * #GNUNET_YES (or other positive value) on success
126 * @param min_expiration minimum expiration time required for 0-priority content to be stored
127 * by the datacache at this time, zero for unknown, forever if we have no
128 * space for 0-priority content
129 * @param msg NULL on success, otherwise an error message
130 */
131static void
132ublock_put_cont (void *cls,
133 int32_t success,
134 struct GNUNET_TIME_Absolute min_expiration,
135 const char *msg)
136{
137 struct GNUNET_FS_PublishUblockContext *uc = cls;
138
139 uc->qre = NULL;
140 uc->cont (uc->cont_cls, msg);
141 GNUNET_free (uc);
142}
143
144
145/**
146 * Run the continuation.
147 *
148 * @param cls the `struct GNUNET_FS_PublishUblockContext *`
149 */
150static void
151run_cont (void *cls)
152{
153 struct GNUNET_FS_PublishUblockContext *uc = cls;
154
155 uc->task = NULL;
156 uc->cont (uc->cont_cls, NULL);
157 GNUNET_free (uc);
158}
159
160
161/**
162 * Publish a UBlock.
163 *
164 * @param h handle to the file sharing subsystem
165 * @param dsh datastore handle to use for storage operation
166 * @param label identifier to use
167 * @param ulabel update label to use, may be an empty string for none
168 * @param ns namespace to publish in
169 * @param meta metadata to use
170 * @param uri URI to refer to in the UBlock
171 * @param bo per-block options
172 * @param options publication options
173 * @param cont continuation
174 * @param cont_cls closure for @a cont
175 * @return NULL on error (@a cont will still be called)
176 */
177struct GNUNET_FS_PublishUblockContext *
178GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h,
179 struct GNUNET_DATASTORE_Handle *dsh,
180 const char *label,
181 const char *ulabel,
182 const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns,
183 const struct GNUNET_CONTAINER_MetaData *meta,
184 const struct GNUNET_FS_Uri *uri,
185 const struct GNUNET_FS_BlockOptions *bo,
186 enum GNUNET_FS_PublishOptions options,
187 GNUNET_FS_UBlockContinuation cont, void *cont_cls)
188{
189 struct GNUNET_FS_PublishUblockContext *uc;
190 struct GNUNET_HashCode query;
191 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
192 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
193 struct GNUNET_CRYPTO_EcdsaPrivateKey *nsd;
194 struct GNUNET_CRYPTO_EcdsaPublicKey pub;
195 char *uris;
196 size_t size;
197 char *kbe;
198 char *sptr;
199 ssize_t mdsize;
200 size_t slen;
201 size_t ulen;
202 struct UBlock *ub_plain;
203 struct UBlock *ub_enc;
204
205 /* compute ublock to publish */
206 if (NULL == meta)
207 mdsize = 0;
208 else
209 mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
210 GNUNET_assert (mdsize >= 0);
211 uris = GNUNET_FS_uri_to_string (uri);
212 slen = strlen (uris) + 1;
213 if (NULL == ulabel)
214 ulen = 1;
215 else
216 ulen = strlen (ulabel) + 1;
217 size = mdsize + sizeof(struct UBlock) + slen + ulen;
218 if (size > MAX_UBLOCK_SIZE)
219 {
220 size = MAX_UBLOCK_SIZE;
221 mdsize = size - sizeof(struct UBlock) - (slen + ulen);
222 }
223 ub_plain = GNUNET_malloc (size);
224 kbe = (char *) &ub_plain[1];
225 if (NULL != ulabel)
226 GNUNET_memcpy (kbe, ulabel, ulen);
227 kbe += ulen;
228 GNUNET_memcpy (kbe, uris, slen);
229 kbe += slen;
230 GNUNET_free (uris);
231 sptr = kbe;
232 if (NULL != meta)
233 mdsize =
234 GNUNET_CONTAINER_meta_data_serialize (meta, &sptr, mdsize,
235 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
236 if (-1 == mdsize)
237 {
238 GNUNET_break (0);
239 GNUNET_free (ub_plain);
240 cont (cont_cls, _ ("Internal error."));
241 return NULL;
242 }
243 size = sizeof(struct UBlock) + slen + mdsize + ulen;
244
245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
246 "Publishing under identifier `%s'\n",
247 label);
248 /* get public key of the namespace */
249 GNUNET_CRYPTO_ecdsa_key_get_public (ns,
250 &pub);
251 derive_ublock_encryption_key (&skey, &iv,
252 label, &pub);
253
254 /* encrypt ublock */
255 ub_enc = GNUNET_malloc (size);
256 GNUNET_CRYPTO_symmetric_encrypt (&ub_plain[1],
257 ulen + slen + mdsize,
258 &skey, &iv,
259 &ub_enc[1]);
260 GNUNET_free (ub_plain);
261 ub_enc->purpose.size = htonl (ulen + slen + mdsize
262 + sizeof(struct UBlock)
263 - sizeof(struct GNUNET_CRYPTO_EcdsaSignature));
264 ub_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK);
265
266 /* derive signing-key from 'label' and public key of the namespace */
267 nsd = GNUNET_CRYPTO_ecdsa_private_key_derive (ns, label, "fs-ublock");
268 GNUNET_CRYPTO_ecdsa_key_get_public (nsd,
269 &ub_enc->verification_key);
270 GNUNET_assert (GNUNET_OK ==
271 GNUNET_CRYPTO_ecdsa_sign_ (nsd,
272 &ub_enc->purpose,
273 &ub_enc->signature));
274 GNUNET_CRYPTO_hash (&ub_enc->verification_key,
275 sizeof(ub_enc->verification_key),
276 &query);
277 GNUNET_free (nsd);
278
279 uc = GNUNET_new (struct GNUNET_FS_PublishUblockContext);
280 uc->cont = cont;
281 uc->cont_cls = cont_cls;
282 if (NULL != dsh)
283 {
284 uc->qre =
285 GNUNET_DATASTORE_put (dsh,
286 0,
287 &query,
288 ulen + slen + mdsize + sizeof(struct UBlock),
289 ub_enc,
290 GNUNET_BLOCK_TYPE_FS_UBLOCK,
291 bo->content_priority,
292 bo->anonymity_level,
293 bo->replication_level,
294 bo->expiration_time,
295 -2, 1,
296 &ublock_put_cont, uc);
297 }
298 else
299 {
300 uc->task = GNUNET_SCHEDULER_add_now (&run_cont,
301 uc);
302 }
303 GNUNET_free (ub_enc);
304 return uc;
305}
306
307
308/**
309 * Abort UBlock publishing operation.
310 *
311 * @param uc operation to abort.
312 */
313void
314GNUNET_FS_publish_ublock_cancel_ (struct GNUNET_FS_PublishUblockContext *uc)
315{
316 if (NULL != uc->qre)
317 GNUNET_DATASTORE_cancel (uc->qre);
318 if (NULL != uc->task)
319 GNUNET_SCHEDULER_cancel (uc->task);
320 GNUNET_free (uc);
321}
322
323
324/* end of fs_publish_ublock.c */