diff options
Diffstat (limited to 'src/fs/fs_publish_ublock.c')
-rw-r--r-- | src/fs/fs_publish_ublock.c | 324 |
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 | */ | ||
45 | static void | ||
46 | derive_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 | */ | ||
74 | void | ||
75 | GNUNET_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 | */ | ||
95 | struct 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 | */ | ||
131 | static void | ||
132 | ublock_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 | */ | ||
150 | static void | ||
151 | run_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 | */ | ||
177 | struct GNUNET_FS_PublishUblockContext * | ||
178 | GNUNET_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 | */ | ||
313 | void | ||
314 | GNUNET_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 */ | ||