GNUnet  0.11.x
fs_publish_ublock.c
Go to the documentation of this file.
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 
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 
45 static void
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 */
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 
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 {
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 
96 {
101 
105  void *cont_cls;
106 
111 
116 };
117 
118 
131 static void
132 ublock_put_cont (void *cls,
133  int32_t success,
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 
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 
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,
188 {
190  struct GNUNET_HashCode query;
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
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,
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 
246  "Publishing under identifier `%s'\n",
247  label);
248  /* get public key of the namespace */
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));
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");
269  &ub_enc->verification_key);
272  &ub_enc->purpose,
273  &ub_enc->signature));
275  sizeof(ub_enc->verification_key),
276  &query);
277  GNUNET_free (nsd);
278 
280  uc->cont = cont;
281  uc->cont_cls = cont_cls;
282  if (NULL != dsh)
283  {
284  uc->qre =
286  0,
287  &query,
288  ulen + slen + mdsize + sizeof(struct UBlock),
289  ub_enc,
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  {
301  uc);
302  }
303  GNUNET_free (ub_enc);
304  return uc;
305 }
306 
307 
313 void
315 {
316  if (NULL != uc->qre)
318  if (NULL != uc->task)
320  GNUNET_free (uc);
321 }
322 
323 
324 /* end of fs_publish_ublock.c */
struct GNUNET_TIME_Absolute expiration_time
At what time should the block expire? Data blocks (DBLOCKS and IBLOCKS) may still be used even if the...
ssize_t GNUNET_CONTAINER_meta_data_get_serialized_size(const struct GNUNET_CONTAINER_MetaData *md)
Get the size of the full meta-data in serialized form.
static struct GNUNET_TIME_Absolute min_expiration
Minimum time that content should have to not be discarded instantly (time stamp of any content that w...
GNUNET_FS_UBlockContinuation cont
Function to call when done.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
ssize_t GNUNET_CONTAINER_meta_data_serialize(const struct GNUNET_CONTAINER_MetaData *md, char **target, size_t max, enum GNUNET_CONTAINER_MetaDataSerializationOptions opt)
Serialize meta-data to target.
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
If not enough space is available, it is acceptable to only serialize some of the metadata.
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
Master context for most FS operations.
Definition: fs_api.h:1068
struct GNUNET_DATASTORE_QueueEntry * GNUNET_DATASTORE_put(struct GNUNET_DATASTORE_Handle *h, uint32_t rid, const struct GNUNET_HashCode *key, size_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, unsigned int queue_priority, unsigned int max_queue_size, GNUNET_DATASTORE_ContinuationWithStatus cont, void *cont_cls)
Store an item in the datastore.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GNUNET_FS_ublock_decrypt_(const void *input, size_t input_len, const struct GNUNET_CRYPTO_EcdsaPublicKey *ns, const char *label, void *output)
Decrypt the given UBlock, storing the result in output.
static struct GNUNET_FS_UnindexContext * uc
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static void ublock_put_cont(void *cls, int32_t success, struct GNUNET_TIME_Absolute min_expiration, const char *msg)
Continuation of GNUNET_FS_publish_ublock_().
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
struct GNUNET_DATASTORE_QueueEntry * qre
Handle for active datastore operation.
#define GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK
UBlock Signature, done using DSS, not ECC.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
char * GNUNET_FS_uri_to_string(const struct GNUNET_FS_Uri *uri)
Convert a URI to a UTF-8 String.
Definition: fs_uri.c:2028
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
uint32_t anonymity_level
At which anonymity level should the block be shared? (0: no anonymity, 1: normal GAP, >1: with cover traffic).
int GNUNET_CRYPTO_ecdsa_sign(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EcdsaSignature *sig)
ECDSA Sign a given block.
Definition: crypto_ecc.c:928
struct GNUNET_CRYPTO_EcdsaSignature signature
Signature using pseudonym and search keyword / identifier.
Definition: block_fs.h:54
Meta data to associate with a file, directory or namespace.
Entry in our priority queue.
Definition: datastore_api.c:99
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
ssize_t GNUNET_CRYPTO_symmetric_encrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Encrypt a block using a symmetric sessionkey.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1280
static struct GNUNET_NAMESTORE_Handle * ns
Handle to the namestore.
Definition: gnunet-abd.c:41
an ECC signature using ECDSA
GNUNET_FS_PublishOptions
Options for publishing.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
Type of a block representing any type of search result (universal).
A 512-bit hashcode.
void GNUNET_CRYPTO_hash_to_aes_key(const struct GNUNET_HashCode *hc, struct GNUNET_CRYPTO_SymmetricSessionKey *skey, struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
Convert a hashcode into a key.
Definition: crypto_hash.c:222
void GNUNET_FS_publish_ublock_cancel_(struct GNUNET_FS_PublishUblockContext *uc)
Abort UBlock publishing operation.
static unsigned int size
Size of the "table".
Definition: peer.c:67
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:239
struct GNUNET_FS_PublishUblockContext * GNUNET_FS_publish_ublock_(struct GNUNET_FS_Handle *h, struct GNUNET_DATASTORE_Handle *dsh, const char *label, const char *ulabel, const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns, const struct GNUNET_CONTAINER_MetaData *meta, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_BlockOptions *bo, enum GNUNET_FS_PublishOptions options, GNUNET_FS_UBlockContinuation cont, void *cont_cls)
Publish a UBlock.
Settings for publishing a block (which may of course also apply to an entire directory or file)...
struct GNUNET_SCHEDULER_Task * task
Task to run continuation asynchronously.
uint32_t replication_level
How often should we try to migrate the block to other peers? Only used if "CONTENT_PUSHING" is set to...
void GNUNET_DATASTORE_cancel(struct GNUNET_DATASTORE_QueueEntry *qe)
Cancel a datastore operation.
shared definitions for the FS library
Context for &#39;ublock_put_cont&#39;.
A Universal Resource Identifier (URI), opaque.
Definition: fs_api.h:165
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:39
Handle to the datastore service.
static struct GNUNET_CONTAINER_MetaData * meta
Meta-data provided via command-line option.
static struct GNUNET_DATASTORE_Handle * dsh
Datastore handle.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
uint32_t content_priority
How important is it for us to store the block? If we run out of space, the highest-priority, non-expired blocks will be kept.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
static void run_cont(void *cls)
Run the continuation.
#define MAX_UBLOCK_SIZE
Maximum legal size for a ublock.
Definition: block_fs.h:41
struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_CRYPTO_ecdsa_private_key_derive(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const char *label, const char *context)
Derive a private key from a given private key and a label.
Definition: crypto_ecc.c:1293
void(* GNUNET_FS_UBlockContinuation)(void *cls, const char *emsg)
Signature of a function called as the continuation of a UBlock publication.
ssize_t GNUNET_CRYPTO_symmetric_decrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result)
Decrypt a given block using a symmetric sessionkey.
static void derive_ublock_encryption_key(struct GNUNET_CRYPTO_SymmetricSessionKey *skey, struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const char *label, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Derive the key for symmetric encryption/decryption from the public key and the label.
void * cont_cls
Closure of &#39;cont&#39;.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
What is being signed and why?
Definition: block_fs.h:59
int GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:89
struct GNUNET_CRYPTO_EcdsaPublicKey verification_key
Public key used to sign this block.
Definition: block_fs.h:64
universal block for keyword and namespace search results
Definition: block_fs.h:49
#define GNUNET_malloc(size)
Wrapper around malloc.
static struct GNUNET_FS_BlockOptions bo
Options we set for published blocks.
#define GNUNET_free(ptr)
Wrapper around free.
Merkle-tree-ish-CHK file encoding for GNUnet.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
publish a UBLOCK in GNUnet