diff --git a/brandt.c b/brandt.c index dda81ac..1af19b9 100644 --- a/brandt.c +++ b/brandt.c @@ -62,8 +62,8 @@ struct BRANDT_Auction * BRANDT_new (BRANDT_CbBroadcast broadcast, BRANDT_CbResult result, void *auction_closure, - void **auction_data, - size_t *auction_data_len, + void **auction_desc, + size_t *auction_desc_len, struct GNUNET_TIME_Absolute time_start, struct GNUNET_TIME_Relative time_round, void *description, @@ -113,28 +113,94 @@ BRANDT_new (BRANDT_CbBroadcast broadcast, &start_auction, ret); - *auction_data_len = sizeof (struct BRANDT_DescrP); - *auction_data = desc; + *auction_desc_len = sizeof (struct BRANDT_DescrP); + *auction_desc = desc; return ret; } +int +BRANDT_verify_desc (const void *auction_desc, + size_t auction_desc_len, + const void *description, + uint32_t description_len, + struct GNUNET_TIME_Absolute *time_start, + struct GNUNET_TIME_Relative *time_round, + uint16_t *num_prices, + uint16_t *m, + uint16_t *outcome_public) +{ + const struct BRANDT_DescrP *desc = auction_desc; + const uint32_t zero = 0; + struct GNUNET_HashContext *hc = GNUNET_CRYPTO_hash_context_start (); + struct GNUNET_HashCode computed_hash; + + if (sizeof (struct BRANDT_DescrP) != auction_desc_len) + { + weprintf ("auction desc struct size mismatch"); + return -1; + } + + GNUNET_CRYPTO_hash_context_read (hc, + &desc->time_start, + sizeof (*desc) - sizeof (desc->hash)); + GNUNET_CRYPTO_hash_context_read (hc, + description, + description_len); + GNUNET_CRYPTO_hash_context_finish (hc, &computed_hash); + if (0 != memcmp (&desc->hash, &computed_hash, sizeof (computed_hash))) + { + weprintf ("auction description hash does not match"); + return -1; + } + + if (0 != memcmp (&desc->reserved1, &zero, sizeof (desc->reserved1)) || + 0 != memcmp (&desc->reserved2, &zero, sizeof (desc->reserved2))) + { + weprintf ("unknown auction description format"); + return -1; + } + + if (time_start) + *time_start = GNUNET_TIME_absolute_ntoh (desc->time_start); + if (time_round) + *time_round = GNUNET_TIME_relative_ntoh (desc->time_round); + if (num_prices) + *num_prices = ntohs (desc->k); + if (m) + *m = ntohs (desc->m); + if (outcome_public) + *outcome_public = ntohs (desc->outcome_public); + + return 0; +} + + struct BRANDT_Auction * BRANDT_join (BRANDT_CbBroadcast broadcast, BRANDT_CbUnicast unicast, BRANDT_CbResult result, void *auction_closure, - const void *auction_data, - size_t auction_data_len) + const void *auction_desc, + size_t auction_desc_len, + const void *description, + uint32_t description_len) { struct BRANDT_Auction *ret = GNUNET_new (struct BRANDT_Auction); - struct BRANDT_DescrP *desc = (struct BRANDT_DescrP *)auction_data; - ret->time_start = GNUNET_TIME_absolute_ntoh (desc->time_start); - ret->time_round = GNUNET_TIME_relative_ntoh (desc->time_round); - ret->k = ntohs (desc->k); - ret->m = ntohs (desc->m); - ret->outcome_public = ntohs (desc->outcome_public); + if (0 != BRANDT_verify_desc (auction_desc, + auction_desc_len, + description, + description_len, + &ret->time_start, + &ret->time_round, + &ret->k, + &ret->m, + &ret->outcome_public)) + { + weprintf ("failed to parse auction description blob"); + return NULL; + } ret->cur_round = msg_join; ret->round_progress = gcry_mpi_new (256); diff --git a/brandt.h b/brandt.h index 108e082..ad98663 100644 --- a/brandt.h +++ b/brandt.h @@ -90,18 +90,45 @@ typedef void void BRANDT_init (struct GNUNET_CRYPTO_EccDlogContext *dlogctx); + /** - * Join an auction described by the @a auction_data parameter. + * Verify an auction description blob and parse it's fields. See BRANDT_new() + * for an explanation of the different auction description fields. + * + * @param[in] auction_desc The auction description blob published by the seller. + * @param[in] auction_desc_len Length of @a auction_desc in bytes. + * @param[in] description The description text in application choosen format. + * @param[in] description_len Length of @a description in bytes. + * @param[out] time_start Starting time of the auction. May be NULL. + * @param[out] time_round Maximum round time of the auction. May be NULL. + * @param[out] num_prices Amount of possible prices. May be NULL. + * @param[out] m Auction mode. May be NULL. + * @param[out] outcome_public Outcome setting. May be NULL. + */ +int +BRANDT_verify_desc (const void *auction_desc, + size_t auction_desc_len, + const void *description, + uint32_t description_len, + struct GNUNET_TIME_Absolute *time_start, + struct GNUNET_TIME_Relative *time_round, + uint16_t *num_prices, + uint16_t *m, + uint16_t *outcome_public); + + +/** + * Join an auction described by the @a auction_desc parameter. * * @param[in] broadcast Pointer to the broadcast callback function * @param[in] unicast Pointer to the unicast callback function * @param[in] result Pointer to the result callback function * @param[in] auction_closure Closure pointer representing the auction. This * will not be touched by libbrandt itself. It is only passed to the callbacks. - * @param[in] auction_data The auction information data published by the seller. + * @param[in] auction_desc The auction information data published by the seller. * This is an opaque data structure. It will be parsed and checked by * BRANDT_join(). - * @param[in] auction_data_len The length in bytes of the @a auction_data + * @param[in] auction_desc_len The length in bytes of the @a auction_desc * structure. * @return A pointer, which should only be remembered and passed to * libbrandt functions when the client needs to refer to this auction. This is a @@ -112,8 +139,10 @@ BRANDT_join (BRANDT_CbBroadcast broadcast, BRANDT_CbUnicast unicast, BRANDT_CbResult result, void *auction_closure, - const void *auction_data, - size_t auction_data_len); + const void *auction_desc, + size_t auction_desc_len, + const void *description, + uint32_t description_len); /* \todo: where do I specify my bid? */ @@ -127,16 +156,16 @@ BRANDT_join (BRANDT_CbBroadcast broadcast, /* setup needs more auction proposal details (hash, timeout, */ /* bid structure), later we need to know # participants */ /** - * Create a new auction described by the @a auction_data parameter. + * Create a new auction described by the @a auction_desc parameter. * * @param[in] broadcast Pointer to the broadcast callback function * @param[in] result Pointer to the result callback function * @param[in] auction_closure Closure pointer representing the auction. This * will not be touched by libbrandt. It is only passed to the callbacks. - * @param[out] auction_data The auction information data a an opaque data + * @param[out] auction_desc The auction information data a an opaque data * structure. It will be generated by BRANDT_new() and should be distributed to * all possibly interested bidders. - * @param[out] auction_data_len The length in bytes of the @a auction_data + * @param[out] auction_desc_len The length in bytes of the @a auction_desc * structure. Will be filled by BRANDT_new(). * @param[in] num_prices The amount of possible valuations for the sold item(s). * If 0, a default of 256 will be used. \todo: what about 1, does it work with @@ -156,8 +185,8 @@ struct BRANDT_Auction * BRANDT_new (BRANDT_CbBroadcast broadcast, BRANDT_CbResult result, void *auction_closure, - void **auction_data, - size_t *auction_data_len, + void **auction_desc, + size_t *auction_desc_len, struct GNUNET_TIME_Absolute time_start, struct GNUNET_TIME_Relative time_round, void *description, diff --git a/internals.h b/internals.h index fa2ea87..23dab78 100644 --- a/internals.h +++ b/internals.h @@ -79,7 +79,7 @@ struct BRANDT_DescrP { /** The length of the description in bytes */ uint32_t description_len GNUNET_PACKED; - /** reserved for future use */ + /** reserved for future use. Must be zeroed out. */ uint32_t reserved1 GNUNET_PACKED; /** The amount of possible prices */ @@ -93,7 +93,7 @@ struct BRANDT_DescrP { * outcome. */ uint16_t outcome_public GNUNET_PACKED; - /** reserved for future use */ + /** reserved for future use. Must be zeroed out. */ uint16_t reserved2 GNUNET_PACKED; };