X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ffs%2Ffs_publish_ublock.c;h=7de9ea689df0222abb31fbbb851507da8e759532;hb=3140154d46212e08e0d73ed891a66213a6813075;hp=1e1d1e233cbe34e74d673f1517ccfd72e2beb3f4;hpb=0f8b11c7c8fa59eded68dc57de5410b7a313a031;p=oweals%2Fgnunet.git diff --git a/src/fs/fs_publish_ublock.c b/src/fs/fs_publish_ublock.c index 1e1d1e233..7de9ea689 100644 --- a/src/fs/fs_publish_ublock.c +++ b/src/fs/fs_publish_ublock.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009, 2010, 2012, 2013 Christian Grothoff (and other contributing authors) + Copyright (C) 2009, 2010, 2012, 2013 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -14,14 +14,14 @@ You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /** * @file fs/fs_publish_ublock.c * @brief publish a UBLOCK in GNUnet - * @see https://gnunet.org/encoding and #2564 + * @see https://gnunet.org/encoding and #2564 * @author Krista Bennett * @author Christian Grothoff */ @@ -33,23 +33,58 @@ #include "fs_tree.h" +/** + * Derive the key for symmetric encryption/decryption from + * the public key and the label. + * + * @param skey where to store symmetric key + * @param iv where to store the IV + * @param label label to use for key derivation + * @param pub public key to use for key derivation + */ +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) +{ + struct GNUNET_HashCode key; + + /* derive key from 'label' and public key of the namespace */ + GNUNET_assert (GNUNET_YES == + GNUNET_CRYPTO_kdf (&key, sizeof (key), + "UBLOCK-ENC", strlen ("UBLOCK-ENC"), + label, strlen (label), + pub, sizeof (*pub), + NULL, 0)); + GNUNET_CRYPTO_hash_to_aes_key (&key, skey, iv); +} + + /** * Decrypt the given UBlock, storing the result in output. * * @param input input data - * @param input_len number of bytes in input + * @param input_len number of bytes in @a input * @param ns public key under which the UBlock was stored * @param label label under which the UBlock was stored * @param output where to write the result, has input_len bytes - */ + */ void GNUNET_FS_ublock_decrypt_ (const void *input, size_t input_len, - const struct GNUNET_CRYPTO_EccPublicKey *ns, + const struct GNUNET_CRYPTO_EcdsaPublicKey *ns, const char *label, void *output) { - GNUNET_break (0); + struct GNUNET_CRYPTO_SymmetricInitializationVector iv; + struct GNUNET_CRYPTO_SymmetricSessionKey skey; + + derive_ublock_encryption_key (&skey, &iv, + label, ns); + GNUNET_CRYPTO_symmetric_decrypt (input, input_len, + &skey, &iv, + output); } @@ -73,23 +108,29 @@ struct GNUNET_FS_PublishUblockContext * Handle for active datastore operation. */ struct GNUNET_DATASTORE_QueueEntry *qre; + + /** + * Task to run continuation asynchronously. + */ + struct GNUNET_SCHEDULER_Task * task; + }; /** - * Continuation of "GNUNET_FS_publish_ublock_". + * Continuation of #GNUNET_FS_publish_ublock_(). * * @param cls closure of type "struct GNUNET_FS_PublishUblockContext*" - * @param success GNUNET_SYSERR on failure (including timeout/queue drop) - * GNUNET_NO if content was already there - * GNUNET_YES (or other positive value) on success + * @param success #GNUNET_SYSERR on failure (including timeout/queue drop) + * #GNUNET_NO if content was already there + * #GNUNET_YES (or other positive value) on success * @param min_expiration minimum expiration time required for 0-priority content to be stored * by the datacache at this time, zero for unknown, forever if we have no * space for 0-priority content * @param msg NULL on success, otherwise an error message */ static void -ublock_put_cont (void *cls, +ublock_put_cont (void *cls, int32_t success, struct GNUNET_TIME_Absolute min_expiration, const char *msg) @@ -102,6 +143,22 @@ ublock_put_cont (void *cls, } +/** + * Run the continuation. + * + * @param cls the `struct GNUNET_FS_PublishUblockContext *` + */ +static void +run_cont (void *cls) +{ + struct GNUNET_FS_PublishUblockContext *uc = cls; + + uc->task = NULL; + uc->cont (uc->cont_cls, NULL); + GNUNET_free (uc); +} + + /** * Publish a UBlock. * @@ -115,15 +172,15 @@ ublock_put_cont (void *cls, * @param bo per-block options * @param options publication options * @param cont continuation - * @param cont_cls closure for cont - * @return NULL on error ('cont' will still be called) + * @param cont_cls closure for @a cont + * @return NULL on error (@a cont will still be called) */ 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_EccPrivateKey *ns, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns, const struct GNUNET_CONTAINER_MetaData *meta, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_BlockOptions *bo, @@ -131,14 +188,11 @@ GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h, GNUNET_FS_UBlockContinuation cont, void *cont_cls) { struct GNUNET_FS_PublishUblockContext *uc; - struct GNUNET_HashCode key; - struct GNUNET_HashCode seed; - struct GNUNET_HashCode signing_key; struct GNUNET_HashCode query; - struct GNUNET_CRYPTO_AesSessionKey skey; - struct GNUNET_CRYPTO_AesInitializationVector iv; - struct GNUNET_CRYPTO_EccPrivateKey *nsd; - struct GNUNET_CRYPTO_EccPublicKey pub; + struct GNUNET_CRYPTO_SymmetricInitializationVector iv; + struct GNUNET_CRYPTO_SymmetricSessionKey skey; + struct GNUNET_CRYPTO_EcdsaPrivateKey *nsd; + struct GNUNET_CRYPTO_EcdsaPublicKey pub; char *uris; size_t size; char *kbe; @@ -158,7 +212,7 @@ GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h, uris = GNUNET_FS_uri_to_string (uri); slen = strlen (uris) + 1; if (NULL == ulabel) - ulen = 0; + ulen = 1; else ulen = strlen (ulabel) + 1; size = mdsize + sizeof (struct UBlock) + slen + ulen; @@ -169,7 +223,8 @@ GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h, } ub_plain = GNUNET_malloc (size); kbe = (char *) &ub_plain[1]; - memcpy (kbe, ulabel, ulen); + if (NULL != ulabel) + memcpy (kbe, ulabel, ulen); kbe += ulen; memcpy (kbe, uris, slen); kbe += slen; @@ -188,66 +243,64 @@ GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h, } size = sizeof (struct UBlock) + slen + mdsize + ulen; - /* derive signing seed from plaintext */ - GNUNET_CRYPTO_hash (&ub_plain[1], - ulen + slen + mdsize, - &seed); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing under identifier `%s'\n", label); /* get public key of the namespace */ - GNUNET_CRYPTO_ecc_key_get_public (ns, + GNUNET_CRYPTO_ecdsa_key_get_public (ns, &pub); - /* derive key from 'label' and public key of the namespace */ - GNUNET_assert (GNUNET_YES == - GNUNET_CRYPTO_kdf (&key, sizeof (key), - "UBLOCK-ENC", strlen ("UBLOCK-ENC"), - label, strlen (label), - &pub, sizeof (pub), - NULL, 0)); - GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv); + derive_ublock_encryption_key (&skey, &iv, + label, &pub); /* encrypt ublock */ ub_enc = GNUNET_malloc (size); - GNUNET_CRYPTO_aes_encrypt (&ub_plain[1], + GNUNET_CRYPTO_symmetric_encrypt (&ub_plain[1], ulen + slen + mdsize, &skey, &iv, &ub_enc[1]); - ub_enc->purpose.size = htonl (ulen + slen + mdsize + + GNUNET_free (ub_plain); + ub_enc->purpose.size = htonl (ulen + slen + mdsize + sizeof (struct UBlock) - - sizeof (struct GNUNET_CRYPTO_EccSignature)); + - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); ub_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK); /* derive signing-key from 'label' and public key of the namespace */ - GNUNET_assert (GNUNET_YES == - GNUNET_CRYPTO_kdf (&signing_key, sizeof (signing_key), - "UBLOCK-SIGN", strlen ("UBLOCK-SIGN"), - label, strlen (label), - &pub, sizeof (pub), - NULL, 0)); - nsd = GNUNET_CRYPTO_ecc_key_derive (ns, label); - GNUNET_CRYPTO_ecc_key_get_public (nsd, + nsd = GNUNET_CRYPTO_ecdsa_private_key_derive (ns, label, "fs-ublock"); + GNUNET_CRYPTO_ecdsa_key_get_public (nsd, &ub_enc->verification_key); GNUNET_assert (GNUNET_OK == - GNUNET_CRYPTO_ecc_sign (nsd, + GNUNET_CRYPTO_ecdsa_sign (nsd, &ub_enc->purpose, &ub_enc->signature)); GNUNET_CRYPTO_hash (&ub_enc->verification_key, sizeof (ub_enc->verification_key), &query); - GNUNET_CRYPTO_ecc_key_free (nsd); + GNUNET_free (nsd); uc = GNUNET_new (struct GNUNET_FS_PublishUblockContext); uc->cont = cont; uc->cont_cls = cont_cls; - uc->qre = - GNUNET_DATASTORE_put (dsh, 0, &query, - ulen + slen + mdsize + sizeof (struct UBlock), - ub_enc, GNUNET_BLOCK_TYPE_FS_UBLOCK, - bo->content_priority, bo->anonymity_level, - bo->replication_level, bo->expiration_time, - -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT, - &ublock_put_cont, uc); + if (NULL != dsh) + { + uc->qre = + GNUNET_DATASTORE_put (dsh, + 0, + &query, + ulen + slen + mdsize + sizeof (struct UBlock), + ub_enc, + GNUNET_BLOCK_TYPE_FS_UBLOCK, + bo->content_priority, + bo->anonymity_level, + bo->replication_level, + bo->expiration_time, + -2, 1, + &ublock_put_cont, uc); + } + else + { + uc->task = GNUNET_SCHEDULER_add_now (&run_cont, + uc); + } return uc; } @@ -260,6 +313,11 @@ GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h, void GNUNET_FS_publish_ublock_cancel_ (struct GNUNET_FS_PublishUblockContext *uc) { - GNUNET_DATASTORE_cancel (uc->qre); + if (NULL != uc->qre) + GNUNET_DATASTORE_cancel (uc->qre); + if (NULL != uc->task) + GNUNET_SCHEDULER_cancel (uc->task); GNUNET_free (uc); } + +/* end of fs_publish_ublock.c */