From 3028910d08226b995fa559b8d25fbd867d0e9652 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 8 Aug 2015 14:29:21 +0200 Subject: implementing serialization logic --- src/mint-lib/mint_api_refresh.c | 186 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 181 insertions(+), 5 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 30d24e02..7b75ca0c 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -130,7 +130,8 @@ struct MeltDataP /* Followed by serializations of: 1) struct MeltedCoinP melted_coins[num_melted_coins]; 2) struct TALER_MINT_DenomPublicKey fresh_pks[num_fresh_coins]; - 3) struct FreshCoinP fresh_coins[num_fresh_coins][k]; + 3) TALER_CNC_KAPPA times: + 3a) struct FreshCoinP fresh_coins[num_fresh_coins]; */ }; @@ -166,7 +167,7 @@ struct MeltedCoin /** * Timestamp indicating when coins of this denomination become invalid. */ - struct GNUNET_TIME_AbsoluteNBO deposit_valid_until; + struct GNUNET_TIME_Absolute deposit_valid_until; /** * Denomination key of the original coin. @@ -316,6 +317,138 @@ free_melt_data (struct MeltData *md) } +/** + * Serialize information about a coin we are melting. + * + * @param mc information to serialize + * @param buf buffer to write data in, NULL to just compute + * required size + * @param off offeset at @a buf to use + * @return number of bytes written to @a buf at @a off, or if + * @a buf is NULL, number of bytes required + */ +static size_t +serialize_melted_coin (const struct MeltedCoin *mc, + char *buf, + size_t off) +{ + struct MeltedCoinP mcp; + unsigned int i; + char *pbuf; + size_t pbuf_size; + char *sbuf; + size_t sbuf_size; + + sbuf_size = GNUNET_CRYPTO_rsa_signature_encode (mc->sig.rsa_signature, + &sbuf); + pbuf_size = GNUNET_CRYPTO_rsa_public_key_encode (mc->pub_key.rsa_public_key, + &pbuf); + if (NULL == buf) + { + GNUNET_free (sbuf); + GNUNET_free (pbuf); + return sizeof (struct MeltedCoinP) + sbuf_size + pbuf_size; + } + + mcp.coin_priv = mc->coin_priv; + TALER_amount_hton (&mcp.melt_amount_with_fee, + &mc->melt_amount_with_fee); + + TALER_amount_hton (&mcp.fee_withdraw, + &mc->fee_withdraw); + for (i=0;itransfer_priv[i]; + mcp.deposit_valid_until = GNUNET_TIME_absolute_hton (mc->deposit_valid_until); + + memcpy (&buf[off], + &mcp, + sizeof (struct MeltedCoinP)); + memcpy (&buf[off + sizeof (struct MeltedCoinP)], + pbuf, + pbuf_size); + memcpy (&buf[off + sizeof (struct MeltedCoinP) + pbuf_size], + sbuf, + sbuf_size); + GNUNET_free (sbuf); + GNUNET_free (pbuf); + return sizeof (struct MeltedCoinP) + sbuf_size + pbuf_size; +} + + +/** + * Serialize information about a denomination key. + * + * @param dk information to serialize + * @param buf buffer to write data in, NULL to just compute + * required size + * @param off offeset at @a buf to use + * @return number of bytes written to @a buf at @a off, or if + * @a buf is NULL, number of bytes required + */ +static size_t +serialize_denomination_key (const struct TALER_DenominationPublicKey *dk, + char *buf, + size_t off) +{ + char *pbuf; + size_t pbuf_size; + + pbuf_size = GNUNET_CRYPTO_rsa_public_key_encode (dk->rsa_public_key, + &pbuf); + if (NULL == buf) + { + GNUNET_free (pbuf); + return pbuf_size; + } + + memcpy (&buf[off], + pbuf, + pbuf_size); + GNUNET_free (pbuf); + return pbuf_size; +} + + +/** + * Serialize information about a fresh coin we are generating. + * + * @param fc information to serialize + * @param buf buffer to write data in, NULL to just compute + * required size + * @param off offeset at @a buf to use + * @return number of bytes written to @a buf at @a off, or if + * @a buf is NULL, number of bytes required + */ +static size_t +serialize_fresh_coin (const struct FreshCoin *fc, + char *buf, + size_t off) +{ + struct FreshCoinP fcp; + char *bbuf; + size_t bbuf_size; + + bbuf_size = GNUNET_CRYPTO_rsa_blinding_key_encode (fc->blinding_key.rsa_blinding_key, + &bbuf); + if (NULL == buf) + { + GNUNET_free (bbuf); + return sizeof (struct FreshCoinP) + bbuf_size; + } + + fcp.coin_priv = fc->coin_priv; + fcp.link_secret = fc->link_secret; + memcpy (&buf[off], + &fcp, + sizeof (struct FreshCoinP)); + memcpy (&buf[off + sizeof (struct FreshCoinP)], + bbuf, + bbuf_size); + GNUNET_free (bbuf); + return sizeof (struct FreshCoinP) + bbuf_size; +} + + /** * Serialize melt data. * @@ -327,9 +460,52 @@ static char * serialize_melt_data (const struct MeltData *md, size_t *res_size) { - GNUNET_break (0); // FIXME: not implemented - *res_size = 0; - return NULL; + size_t size; + size_t asize; + char *buf; + unsigned int i; + unsigned int j; + + size = 0; + buf = NULL; + /* we do 2 iterations, #1 to determine total size, #2 to + actually construct the buffer */ + do { + if (0 == size) + { + size = sizeof (struct MeltDataP); + } + else + { + struct MeltDataP *mdp; + + buf = GNUNET_malloc (size); + asize = size; /* just for invariant check later */ + size = sizeof (struct MeltDataP); + mdp = (struct MeltDataP *) buf; + mdp->melt_session_hash = md->melt_session_hash; + for (i=0;itransfer_secrets[i] = md->transfer_secrets[i]; + mdp->num_melted_coins = htons (md->num_melted_coins); + mdp->num_fresh_coins = htons (md->num_fresh_coins); + } + for (i=0;inum_melted_coins;i++) + size += serialize_melted_coin (&md->melted_coins[i], + buf, + size); + for (i=0;inum_fresh_coins;i++) + size += serialize_denomination_key (&md->fresh_pks[i], + buf, + size); + for (i=0;inum_fresh_coins;j++) + size += serialize_fresh_coin (&md->fresh_coins[i][j], + buf, + size); + } while (NULL == buf); + GNUNET_assert (size == asize); + *res_size = size; + return buf; } -- cgit v1.2.3 From 0ad7967328edec8ea97666765e362c6da7eebe81 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 8 Aug 2015 15:00:55 +0200 Subject: implementing deserialization logic --- src/mint-lib/mint_api_refresh.c | 306 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 284 insertions(+), 22 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 7b75ca0c..5451ef4f 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -68,6 +68,16 @@ struct MeltedCoinP */ struct GNUNET_TIME_AbsoluteNBO deposit_valid_until; + /** + * Size of the encoded public key that follows. + */ + uint16_t pbuf_size; + + /** + * Size of the encoded signature that follows. + */ + uint16_t sbuf_size; + /* Followed by serializations of: 1) struct TALER_DenominationPublicKey pub_key; 2) struct TALER_DenominationSignature sig; @@ -93,6 +103,11 @@ struct FreshCoinP */ struct TALER_LinkSecretP link_secret; + /** + * Size of the encoded blinding key that follows. + */ + uint32_t bbuf_size; + /* Followed by serialization of: - struct TALER_DenominationBlindingKey blinding_key; */ @@ -263,8 +278,12 @@ struct MeltData static void free_melted_coin (struct MeltedCoin *mc) { - GNUNET_CRYPTO_rsa_public_key_free (mc->pub_key.rsa_public_key); - GNUNET_CRYPTO_rsa_signature_free (mc->sig.rsa_signature); + if (NULL == mc) + return; + if (NULL != mc->pub_key.rsa_public_key) + GNUNET_CRYPTO_rsa_public_key_free (mc->pub_key.rsa_public_key); + if (NULL != mc->sig.rsa_signature) + GNUNET_CRYPTO_rsa_signature_free (mc->sig.rsa_signature); } @@ -277,12 +296,18 @@ free_melted_coin (struct MeltedCoin *mc) static void free_fresh_coin (struct FreshCoin *fc) { - GNUNET_CRYPTO_rsa_blinding_key_free (fc->blinding_key.rsa_blinding_key); + if (NULL == fc) + return; + if (NULL != fc->blinding_key.rsa_blinding_key) + GNUNET_CRYPTO_rsa_blinding_key_free (fc->blinding_key.rsa_blinding_key); } /** - * Free all information associated with a melting session. + * Free all information associated with a melting session. Note + * that we allow the melting session to be only partially initialized, + * as we use this function also when freeing melt data that was not + * fully initialized (i.e. due to failures in #deserialize_melt_data()). * * @param md melting data to release, the pointer itself is NOT * freed (as it is typically not allocated by itself) @@ -293,19 +318,28 @@ free_melt_data (struct MeltData *md) unsigned int i; unsigned int j; - for (i=0;inum_melted_coins;i++) - free_melted_coin (&md->melted_coins[i]); - GNUNET_free (md->melted_coins); - - for (i=0;inum_fresh_coins;i++) - GNUNET_CRYPTO_rsa_public_key_free (md->fresh_pks[i].rsa_public_key); - GNUNET_free (md->fresh_pks); + if (NULL != md->melted_coins) + { + for (i=0;inum_melted_coins;i++) + free_melted_coin (&md->melted_coins[i]); + GNUNET_free (md->melted_coins); + } + if (NULL != md->fresh_pks) + { + for (i=0;inum_fresh_coins;i++) + if (NULL != md->fresh_pks[i].rsa_public_key) + GNUNET_CRYPTO_rsa_public_key_free (md->fresh_pks[i].rsa_public_key); + GNUNET_free (md->fresh_pks); + } for (i=0;inum_fresh_coins;j++) - free_fresh_coin (&md->fresh_coins[i][j]); - GNUNET_free (md->fresh_coins[i]); + if (NULL != md->fresh_coins) + { + for (j=0;jnum_fresh_coins;j++) + free_fresh_coin (&md->fresh_coins[i][j]); + GNUNET_free (md->fresh_coins[i]); + } } /* Finally, clean up a bit... (NOTE: compilers might optimize this away, so this is @@ -325,7 +359,7 @@ free_melt_data (struct MeltData *md) * required size * @param off offeset at @a buf to use * @return number of bytes written to @a buf at @a off, or if - * @a buf is NULL, number of bytes required + * @a buf is NULL, number of bytes required; 0 on error */ static size_t serialize_melted_coin (const struct MeltedCoin *mc, @@ -349,7 +383,12 @@ serialize_melted_coin (const struct MeltedCoin *mc, GNUNET_free (pbuf); return sizeof (struct MeltedCoinP) + sbuf_size + pbuf_size; } - + if ( (sbuf_size > UINT16_MAX) || + (pbuf_size > UINT16_MAX) ) + { + GNUNET_break (0); + return 0; + } mcp.coin_priv = mc->coin_priv; TALER_amount_hton (&mcp.melt_amount_with_fee, &mc->melt_amount_with_fee); @@ -359,7 +398,8 @@ serialize_melted_coin (const struct MeltedCoin *mc, for (i=0;itransfer_priv[i]; mcp.deposit_valid_until = GNUNET_TIME_absolute_hton (mc->deposit_valid_until); - + mcp.pbuf_size = htons ((uint16_t) pbuf_size); + mcp.sbuf_size = htons ((uint16_t) sbuf_size); memcpy (&buf[off], &mcp, sizeof (struct MeltedCoinP)); @@ -375,6 +415,73 @@ serialize_melted_coin (const struct MeltedCoin *mc, } +/** + * Deserialize information about a coin we are melting. + * + * @param[out] mc information to deserialize + * @param buf buffer to read data from + * @param size number of bytes available at @a buf to use + * @param[out] ok set to #GNUNET_NO to report errors + * @return number of bytes read from @a buf, 0 on error + */ +static size_t +deserialize_melted_coin (struct MeltedCoin *mc, + const char *buf, + size_t size, + int *ok) +{ + struct MeltedCoinP mcp; + unsigned int i; + size_t pbuf_size; + size_t sbuf_size; + size_t off; + + if (size < sizeof (struct MeltedCoinP)) + { + GNUNET_break (0); + *ok = GNUNET_NO; + return 0; + } + memcpy (&mcp, + buf, + sizeof (struct MeltedCoinP)); + pbuf_size = ntohs (mcp.pbuf_size); + sbuf_size = ntohs (mcp.sbuf_size); + if (size < sizeof (struct MeltedCoinP) + pbuf_size + sbuf_size) + { + GNUNET_break (0); + *ok = GNUNET_NO; + return 0; + } + off = sizeof (struct MeltedCoinP); + mc->pub_key.rsa_public_key + = GNUNET_CRYPTO_rsa_public_key_decode (&buf[off], + pbuf_size); + off += pbuf_size; + mc->sig.rsa_signature + = GNUNET_CRYPTO_rsa_signature_decode (&buf[off], + sbuf_size); + off += sbuf_size; + if ( (NULL == mc->pub_key.rsa_public_key) || + (NULL == mc->sig.rsa_signature) ) + { + GNUNET_break (0); + *ok = GNUNET_NO; + return 0; + } + + mc->coin_priv = mcp.coin_priv; + TALER_amount_ntoh (&mc->melt_amount_with_fee, + &mcp.melt_amount_with_fee); + TALER_amount_ntoh (&mc->fee_withdraw, + &mcp.fee_withdraw); + for (i=0;itransfer_priv[i] = mcp.transfer_priv[i]; + mc->deposit_valid_until = GNUNET_TIME_absolute_ntoh (mcp.deposit_valid_until); + return off; +} + + /** * Serialize information about a denomination key. * @@ -392,16 +499,20 @@ serialize_denomination_key (const struct TALER_DenominationPublicKey *dk, { char *pbuf; size_t pbuf_size; + uint32_t be; pbuf_size = GNUNET_CRYPTO_rsa_public_key_encode (dk->rsa_public_key, &pbuf); if (NULL == buf) { GNUNET_free (pbuf); - return pbuf_size; + return pbuf_size + sizeof (uint32_t); } - + be = htonl ((uint32_t) pbuf_size); memcpy (&buf[off], + &be, + sizeof (uint32_t)); + memcpy (&buf[off + sizeof (uint32_t)], pbuf, pbuf_size); GNUNET_free (pbuf); @@ -409,6 +520,54 @@ serialize_denomination_key (const struct TALER_DenominationPublicKey *dk, } +/** + * Deserialize information about a denomination key. + * + * @param[out] dk information to deserialize + * @param buf buffer to read data from + * @param size number of bytes available at @a buf to use + * @param[out] ok set to #GNUNET_NO to report errors + * @return number of bytes read from @a buf, 0 on error + */ +static size_t +deserialize_denomination_key (struct TALER_DenominationPublicKey *dk, + const char *buf, + size_t size, + int *ok) +{ + size_t pbuf_size; + uint32_t be; + + if (size < sizeof (uint32_t)) + { + GNUNET_break (0); + *ok = GNUNET_NO; + return 0; + } + memcpy (&be, + buf, + sizeof (uint32_t)); + pbuf_size = ntohl (be); + if (size < sizeof (uint32_t) + pbuf_size) + { + GNUNET_break (0); + *ok = GNUNET_NO; + return 0; + } + dk->rsa_public_key + = GNUNET_CRYPTO_rsa_public_key_decode (&buf[sizeof (uint32_t)], + pbuf_size); + + if (NULL == dk->rsa_public_key) + { + GNUNET_break (0); + *ok = GNUNET_NO; + return 0; + } + return sizeof (uint32_t) + pbuf_size; +} + + /** * Serialize information about a fresh coin we are generating. * @@ -435,9 +594,9 @@ serialize_fresh_coin (const struct FreshCoin *fc, GNUNET_free (bbuf); return sizeof (struct FreshCoinP) + bbuf_size; } - fcp.coin_priv = fc->coin_priv; fcp.link_secret = fc->link_secret; + fcp.bbuf_size = htonl ((uint32_t) bbuf_size); memcpy (&buf[off], &fcp, sizeof (struct FreshCoinP)); @@ -449,6 +608,55 @@ serialize_fresh_coin (const struct FreshCoin *fc, } +/** + * Deserialize information about a fresh coin we are generating. + * + * @param[out] fc information to deserialize + * @param buf buffer to read data from + * @param size number of bytes available at @a buf to use + * @param[out] ok set to #GNUNET_NO to report errors + * @return number of bytes read from @a buf, 0 on error + */ +static size_t +deserialize_fresh_coin (struct FreshCoin *fc, + const char *buf, + size_t size, + int *ok) +{ + struct FreshCoinP fcp; + size_t bbuf_size; + + if (size < sizeof (struct FreshCoinP)) + { + GNUNET_break (0); + *ok = GNUNET_NO; + return 0; + } + memcpy (&fcp, + buf, + sizeof (struct FreshCoinP)); + bbuf_size = ntohl (fcp.bbuf_size); + if (size < sizeof (struct FreshCoinP) + bbuf_size) + { + GNUNET_break (0); + *ok = GNUNET_NO; + return 0; + } + fc->blinding_key.rsa_blinding_key + = GNUNET_CRYPTO_rsa_blinding_key_decode (&buf[sizeof (struct FreshCoinP)], + bbuf_size); + if (NULL == fc->blinding_key.rsa_blinding_key) + { + GNUNET_break (0); + *ok = GNUNET_NO; + return 0; + } + fc->coin_priv = fcp.coin_priv; + fc->link_secret = fcp.link_secret; + return sizeof (struct FreshCoinP) + bbuf_size; +} + + /** * Serialize melt data. * @@ -520,8 +728,62 @@ static struct MeltData * deserialize_melt_data (const char *buf, size_t buf_size) { - GNUNET_break (0); // FIXME: not implemented - return NULL; + struct MeltData *md; + struct MeltDataP mdp; + unsigned int i; + unsigned int j; + size_t off; + int ok; + + if (buf_size < sizeof (struct MeltDataP)) + return NULL; + memcpy (&mdp, + buf, + buf_size); + md = GNUNET_new (struct MeltData); + md->melt_session_hash = mdp.melt_session_hash; + for (i=0;itransfer_secrets[i] = mdp.transfer_secrets[i]; + md->num_melted_coins = ntohs (mdp.num_melted_coins); + md->num_fresh_coins = ntohs (mdp.num_fresh_coins); + md->melted_coins = GNUNET_new_array (md->num_melted_coins, + struct MeltedCoin); + md->fresh_pks = GNUNET_new_array (md->num_fresh_coins, + struct TALER_DenominationPublicKey); + for (i=0;ifresh_coins[i] = GNUNET_new_array (md->num_fresh_coins, + struct FreshCoin); + off = sizeof (struct MeltDataP); + ok = GNUNET_YES; + for (i=0;(inum_melted_coins)&&(GNUNET_YES == ok);i++) + off += deserialize_melted_coin (&md->melted_coins[i], + &buf[off], + buf_size - off, + &ok); + for (i=0;(inum_fresh_coins)&&(GNUNET_YES == ok);i++) + off += deserialize_denomination_key (&md->fresh_pks[i], + &buf[off], + buf_size - off, + &ok); + + for (i=0;inum_fresh_coins)&&(GNUNET_YES == ok);j++) + off += deserialize_fresh_coin (&md->fresh_coins[i][j], + &buf[off], + buf_size - off, + &ok); + if (off != buf_size) + { + GNUNET_break (0); + ok = GNUNET_NO; + } + if (GNUNET_YES != ok) + { + free_melt_data (md); + GNUNET_free (md); + return NULL; + } + return md; } -- cgit v1.2.3 From 669e3fcdf2bc20e0ae2e9d915cf509ec10c89f77 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 8 Aug 2015 15:35:34 +0200 Subject: towards implemnting TALER_MINT_refresh_prepare --- src/mint-lib/mint_api_refresh.c | 71 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 5451ef4f..d9591a51 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -787,6 +787,31 @@ deserialize_melt_data (const char *buf, } +/** + * Setup information for a fresh coin. + * + * @param[out] fc value to initialize + * @param pk denomination information for the fresh coin + */ +static void +setup_fresh_coin (struct FreshCoin *fc, + const struct TALER_MINT_DenomPublicKey *pk) +{ + struct GNUNET_CRYPTO_EddsaPrivateKey *epk; + unsigned int len; + + epk = GNUNET_CRYPTO_eddsa_key_create (); + fc->coin_priv.eddsa_priv = *epk; + GNUNET_free (epk); + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, + &fc->link_secret, + sizeof (struct TALER_LinkSecretP)); + len = GNUNET_CRYPTO_rsa_public_key_len (pk->key.rsa_public_key); + fc->blinding_key.rsa_blinding_key + = GNUNET_CRYPTO_rsa_blinding_key_create (len); +} + + /** * Melt (partially spent) coins to obtain fresh coins that are * unlinkable to the original coin(s). Note that melting more @@ -842,9 +867,53 @@ TALER_MINT_refresh_prepare (unsigned int num_melts, { struct MeltData md; char *buf; + unsigned int i; + unsigned int j; + + for (i=0;i Date: Sat, 8 Aug 2015 16:09:25 +0200 Subject: complete implementation of TALER_MINT_refresh_prepare --- src/mint-lib/mint_api_refresh.c | 109 ++++++++++++++++++++++++++++++---------- 1 file changed, 82 insertions(+), 27 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index d9591a51..5c58679e 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -97,12 +97,6 @@ struct FreshCoinP */ struct TALER_CoinSpendPrivateKeyP coin_priv; - /** - * Link secret used to encrypt the @a coin_priv and the blinding - * key in the linkage data. - */ - struct TALER_LinkSecretP link_secret; - /** * Size of the encoded blinding key that follows. */ @@ -128,9 +122,10 @@ struct MeltDataP struct GNUNET_HashCode melt_session_hash; /** - * Transfer secrets for each cut-and-choose dimension. + * Link secret used to encrypt the @a coin_priv and the blinding + * key in the linkage data for the respective cut-and-choose dimension. */ - struct TALER_TransferSecretP transfer_secrets[TALER_CNC_KAPPA]; + struct TALER_LinkSecretP link_secrets[TALER_CNC_KAPPA]; /** * Number of coins we are melting, in NBO @@ -209,12 +204,6 @@ struct FreshCoin */ struct TALER_CoinSpendPrivateKeyP coin_priv; - /** - * Link secret used to encrypt the @a coin_priv and the blinding - * key in the linkage data. - */ - struct TALER_LinkSecretP link_secret; - /** * Blinding key used for blinding during blind signing. */ @@ -235,9 +224,9 @@ struct MeltData struct GNUNET_HashCode melt_session_hash; /** - * Transfer secrets for each cut-and-choose dimension. + * Link secrets for each cut-and-choose dimension. */ - struct TALER_TransferSecretP transfer_secrets[TALER_CNC_KAPPA]; + struct TALER_LinkSecretP link_secrets[TALER_CNC_KAPPA]; /** * Number of coins we are melting @@ -595,7 +584,6 @@ serialize_fresh_coin (const struct FreshCoin *fc, return sizeof (struct FreshCoinP) + bbuf_size; } fcp.coin_priv = fc->coin_priv; - fcp.link_secret = fc->link_secret; fcp.bbuf_size = htonl ((uint32_t) bbuf_size); memcpy (&buf[off], &fcp, @@ -652,7 +640,6 @@ deserialize_fresh_coin (struct FreshCoin *fc, return 0; } fc->coin_priv = fcp.coin_priv; - fc->link_secret = fcp.link_secret; return sizeof (struct FreshCoinP) + bbuf_size; } @@ -693,7 +680,7 @@ serialize_melt_data (const struct MeltData *md, mdp = (struct MeltDataP *) buf; mdp->melt_session_hash = md->melt_session_hash; for (i=0;itransfer_secrets[i] = md->transfer_secrets[i]; + mdp->link_secrets[i] = md->link_secrets[i]; mdp->num_melted_coins = htons (md->num_melted_coins); mdp->num_fresh_coins = htons (md->num_fresh_coins); } @@ -743,7 +730,7 @@ deserialize_melt_data (const char *buf, md = GNUNET_new (struct MeltData); md->melt_session_hash = mdp.melt_session_hash; for (i=0;itransfer_secrets[i] = mdp.transfer_secrets[i]; + md->link_secrets[i] = mdp.link_secrets[i]; md->num_melted_coins = ntohs (mdp.num_melted_coins); md->num_fresh_coins = ntohs (mdp.num_fresh_coins); md->melted_coins = GNUNET_new_array (md->num_melted_coins, @@ -803,9 +790,6 @@ setup_fresh_coin (struct FreshCoin *fc, epk = GNUNET_CRYPTO_eddsa_key_create (); fc->coin_priv.eddsa_priv = *epk; GNUNET_free (epk); - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, - &fc->link_secret, - sizeof (struct TALER_LinkSecretP)); len = GNUNET_CRYPTO_rsa_public_key_len (pk->key.rsa_public_key); fc->blinding_key.rsa_blinding_key = GNUNET_CRYPTO_rsa_blinding_key_create (len); @@ -869,11 +853,12 @@ TALER_MINT_refresh_prepare (unsigned int num_melts, char *buf; unsigned int i; unsigned int j; + struct GNUNET_HashContext *hash_context; for (i=0;icoin_priv.eddsa_priv, + &coin_pub.eddsa_pub); + GNUNET_CRYPTO_hash (&coin_pub.eddsa_pub, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), + &coin_hash); + coin_ev_size = GNUNET_CRYPTO_rsa_blind (&coin_hash, + fc->blinding_key.rsa_blinding_key, + md.fresh_pks[j].rsa_public_key, + &coin_ev); + GNUNET_CRYPTO_hash_context_read (hash_context, + coin_ev, + coin_ev_size); + GNUNET_free (coin_ev); + + rld.coin_priv = fc->coin_priv; + rld.blinding_key = fc->blinding_key; + rle = TALER_refresh_encrypt (&rld, + &md.link_secrets[i]); + link_enc = TALER_refresh_link_encrypted_encode (rle, + &link_enc_size); + + GNUNET_CRYPTO_hash_context_read (hash_context, + link_enc, + link_enc_size); + GNUNET_free (link_enc); + } + } buf = serialize_melt_data (&md, res_size); free_melt_data (&md); -- cgit v1.2.3 From ce4f6e2106ffe5b92fecef502c7ca3f7fd211a43 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 8 Aug 2015 16:15:18 +0200 Subject: -more boilerplate --- src/mint-lib/mint_api_refresh.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 5c58679e..566ab109 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -1123,10 +1123,18 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint, void *melt_cb_cls) { json_t *melt_obj; + json_t *new_denoms; + json_t *melt_coins; + json_t *coin_evs; + json_t *transfer_pubs; + json_t *secret_encs; + json_t *link_encs; struct TALER_MINT_RefreshMeltHandle *rmh; CURL *eh; struct TALER_MINT_Context *ctx; struct MeltData *md; + unsigned int i; + unsigned int j; if (GNUNET_YES != MAH_handle_is_ready (mint)) @@ -1142,10 +1150,32 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint, return NULL; } - /* FIXME: totally bogus request building here: */ - melt_obj = json_pack ("{s:o, s:O}", /* f/wire */ - "4", 42, - "6", 62); + /* FIXME: inomplete request building here: */ + new_denoms = json_array (); + melt_coins = json_array (); + coin_evs = json_array (); + transfer_pubs = json_array (); + secret_encs = json_array (); + link_encs = json_array (); + for (i=0;inum_melted_coins;i++) + { + for (j=0;jnum_fresh_coins;i++) + { + for (j=0;j Date: Sat, 8 Aug 2015 19:52:05 +0200 Subject: completing TALER_MINT_refresh_melt implementation --- src/include/taler_crypto_lib.h | 17 +++++ src/include/taler_mint_service.h | 2 +- src/mint-lib/mint_api_refresh.c | 158 ++++++++++++++++++++++++++++++++++++--- src/util/crypto.c | 28 +++++++ 4 files changed, 194 insertions(+), 11 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 4126894a..5f142507 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -468,6 +468,23 @@ TALER_link_decrypt_secret2 (const struct TALER_EncryptedLinkSecretP *secret_enc, struct TALER_LinkSecretP *secret); +/** + * Given the coin and the transfer private keys, compute the + * transfer secret. (Technically, we only need one of the two + * private keys, but the caller currently trivially only has + * the two private keys, so we derive one of the public keys + * internally to this function.) + * + * @param coin_priv coin key + * @param trans_priv transfer private key + * @param[out] computed transfer secret + */ +void +TALER_link_derive_transfer_secret (const struct TALER_CoinSpendPrivateKeyP *coin_priv, + const struct TALER_TransferPrivateKeyP *trans_priv, + struct TALER_TransferSecretP *ts); + + /** * Encrypt the shared @a secret to generate the encrypted link secret. * Also creates the transfer key. diff --git a/src/include/taler_mint_service.h b/src/include/taler_mint_service.h index b228acc5..fa1f7a50 100644 --- a/src/include/taler_mint_service.h +++ b/src/include/taler_mint_service.h @@ -181,7 +181,7 @@ struct TALER_MINT_DenomPublicKey struct TALER_Amount fee_deposit; /** - *The applicable fee to refresh a coin of this denomination + *The applicable fee to melt/refresh a coin of this denomination */ struct TALER_Amount fee_refresh; }; diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 566ab109..0de367ce 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -56,7 +56,7 @@ struct MeltedCoinP /** * The applicable fee for withdrawing a coin of this denomination */ - struct TALER_AmountNBO fee_withdraw; + struct TALER_AmountNBO fee_melt; /** * Transfer private keys for each cut-and-choose dimension. @@ -165,9 +165,9 @@ struct MeltedCoin struct TALER_Amount melt_amount_with_fee; /** - * The applicable fee for withdrawing a coin of this denomination + * The applicable fee for melting a coin of this denomination */ - struct TALER_Amount fee_withdraw; + struct TALER_Amount fee_melt; /** * Transfer private keys for each cut-and-choose dimension. @@ -382,8 +382,8 @@ serialize_melted_coin (const struct MeltedCoin *mc, TALER_amount_hton (&mcp.melt_amount_with_fee, &mc->melt_amount_with_fee); - TALER_amount_hton (&mcp.fee_withdraw, - &mc->fee_withdraw); + TALER_amount_hton (&mcp.fee_melt, + &mc->fee_melt); for (i=0;itransfer_priv[i]; mcp.deposit_valid_until = GNUNET_TIME_absolute_hton (mc->deposit_valid_until); @@ -462,8 +462,8 @@ deserialize_melted_coin (struct MeltedCoin *mc, mc->coin_priv = mcp.coin_priv; TALER_amount_ntoh (&mc->melt_amount_with_fee, &mcp.melt_amount_with_fee); - TALER_amount_ntoh (&mc->fee_withdraw, - &mcp.fee_withdraw); + TALER_amount_ntoh (&mc->fee_melt, + &mcp.fee_melt); for (i=0;itransfer_priv[i] = mcp.transfer_priv[i]; mc->deposit_valid_until = GNUNET_TIME_absolute_ntoh (mcp.deposit_valid_until); @@ -867,7 +867,7 @@ TALER_MINT_refresh_prepare (unsigned int num_melts, { md.melted_coins[i].coin_priv = melt_privs[i]; md.melted_coins[i].melt_amount_with_fee = melt_amounts[i]; - md.melted_coins[i].fee_withdraw = melt_pks[i].fee_withdraw; + md.melted_coins[i].fee_melt = melt_pks[i].fee_refresh; for (j=0;jmelt_amount_with_fee); + TALER_amount_hton (&melt.melt_fee, + &mc->fee_melt); + GNUNET_CRYPTO_eddsa_key_get_public (&mc->coin_priv.eddsa_priv, + &melt.coin_pub.eddsa_pub); + GNUNET_CRYPTO_eddsa_sign (&mc->coin_priv.eddsa_priv, + &melt.purpose, + &confirm_sig.eddsa_signature); + return json_pack ("{s:o, s:o, s:o, s:o, s:o}", + "coin_pub", + TALER_json_from_data (&melt.coin_pub, + sizeof (melt.coin_pub)), + "denom_pub", + TALER_json_from_rsa_public_key (mc->pub_key.rsa_public_key), + "denom_sig", 42, + TALER_json_from_rsa_signature (mc->sig.rsa_signature), + "confirm_sig", + TALER_json_from_data (&confirm_sig, + sizeof (confirm_sig)), + "value_with_fee", + TALER_json_from_amount (&mc->melt_amount_with_fee)); +} + + /** * Submit a melt request to the mint and get the mint's * response. @@ -1129,6 +1171,7 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint, json_t *transfer_pubs; json_t *secret_encs; json_t *link_encs; + json_t *tmp; struct TALER_MINT_RefreshMeltHandle *rmh; CURL *eh; struct TALER_MINT_Context *ctx; @@ -1150,7 +1193,7 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint, return NULL; } - /* FIXME: inomplete request building here: */ + /* build JSON request, each of the 6 arrays first */ new_denoms = json_array (); melt_coins = json_array (); coin_evs = json_array (); @@ -1159,16 +1202,111 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint, link_encs = json_array (); for (i=0;inum_melted_coins;i++) { + const struct MeltedCoin *mc = &md->melted_coins[i]; + + /* now melt_coins */ + json_array_append (melt_coins, + melted_coin_to_json (&md->melt_session_hash, + mc)); + + /* now transfer_pubs */ + tmp = json_array (); + for (j=0;jtransfer_priv[j].ecdhe_priv, + &transfer_pub.ecdhe_pub); + json_array_append (tmp, + TALER_json_from_data (&transfer_pub, + sizeof (transfer_pub))); + } + json_array_append (transfer_pubs, + tmp); + + /* now secret_encs */ + tmp = json_array (); for (j=0;jcoin_priv, + &mc->transfer_priv[j], + &trans_sec); + GNUNET_assert (GNUNET_OK == + TALER_transfer_encrypt (&md->link_secrets[j], + &trans_sec, + &els)); + json_array_append (tmp, + TALER_json_from_data (&els, + sizeof (els))); } + json_array_append (secret_encs, + tmp); } for (i=0;inum_fresh_coins;i++) { + /* now new_denoms */ + json_array_append (new_denoms, + TALER_json_from_rsa_public_key + (md->fresh_pks[i].rsa_public_key)); + + /* now link_encs */ + tmp = json_array (); for (j=0;jfresh_coins[j][i]; + struct TALER_RefreshLinkDecrypted rld; + struct TALER_RefreshLinkEncrypted *rle; + char *buf; + size_t buf_len; + + rld.coin_priv = fc->coin_priv; + rld.blinding_key = fc->blinding_key; + rle = TALER_refresh_encrypt (&rld, + &md->link_secrets[j]); + GNUNET_assert (NULL != rle); + buf = TALER_refresh_link_encrypted_encode (rle, + &buf_len); + GNUNET_assert (NULL != buf); + json_array_append (tmp, + TALER_json_from_data (buf, + buf_len)); + GNUNET_free (buf); + GNUNET_free (rle); } + json_array_append (link_encs, + tmp); + + /* now coin_evs */ + tmp = json_array (); + for (j=0;jfresh_coins[j][i]; + struct TALER_CoinSpendPublicKeyP coin_pub; + struct GNUNET_HashCode coin_hash; + char *coin_ev; /* blinded message to be signed (in envelope) for each coin */ + size_t coin_ev_size; + + GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv, + &coin_pub.eddsa_pub); + GNUNET_CRYPTO_hash (&coin_pub.eddsa_pub, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), + &coin_hash); + coin_ev_size = GNUNET_CRYPTO_rsa_blind (&coin_hash, + fc->blinding_key.rsa_blinding_key, + md->fresh_pks[j].rsa_public_key, + &coin_ev); + json_array_append (tmp, + TALER_json_from_data (coin_ev, + coin_ev_size)); + GNUNET_free (coin_ev); + } + json_array_append (coin_evs, + tmp); } + /* finally, assemble main JSON request from constitutent arrays */ melt_obj = json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}", "new_denoms", new_denoms, "melt_coins", melt_coins, @@ -1177,7 +1315,7 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint, "secret_encs", secret_encs, "link_encs", link_encs); - + /* and now we can at last begin the actual request handling */ rmh = GNUNET_new (struct TALER_MINT_RefreshMeltHandle); rmh->mint = mint; rmh->melt_cb = melt_cb; diff --git a/src/util/crypto.c b/src/util/crypto.c index b803b960..edc30087 100644 --- a/src/util/crypto.c +++ b/src/util/crypto.c @@ -162,6 +162,34 @@ TALER_transfer_decrypt (const struct TALER_EncryptedLinkSecretP *secret_enc, } +/** + * Given the coin and the transfer private keys, compute the + * transfer secret. (Technically, we only need one of the two + * private keys, but the caller currently trivially only has + * the two private keys, so we derive one of the public keys + * internally to this function.) + * + * @param coin_priv coin key + * @param trans_priv transfer private key + * @param[out] computed transfer secret + */ +void +TALER_link_derive_transfer_secret (const struct TALER_CoinSpendPrivateKeyP *coin_priv, + const struct TALER_TransferPrivateKeyP *trans_priv, + struct TALER_TransferSecretP *ts) +{ + struct TALER_CoinSpendPublicKeyP coin_pub; + + GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, + &coin_pub.eddsa_pub); + GNUNET_assert (GNUNET_OK == + GNUNET_CRYPTO_ecdh_eddsa (&trans_priv->ecdhe_priv, + &coin_pub.eddsa_pub, + &ts->key)); + +} + + /** * Use the @a trans_sec (from ECDHE) to encrypt the @a secret * to obtain the @a secret_enc. -- cgit v1.2.3 From 0a5e962108580c6dca14ebcf42a8962bd80c7957 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 8 Aug 2015 20:01:45 +0200 Subject: implement TALER_MINT_refresh_reveal logic --- src/mint-lib/mint_api_refresh.c | 48 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 0de367ce..a8953463 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -1525,10 +1525,14 @@ TALER_MINT_refresh_reveal (struct TALER_MINT_Handle *mint, void *reveal_cb_cls) { struct TALER_MINT_RefreshRevealHandle *rrh; + json_t *transfer_privs; json_t *reveal_obj; + json_t *tmp; CURL *eh; struct TALER_MINT_Context *ctx; struct MeltData *md; + unsigned int i; + unsigned int j; if (GNUNET_YES != MAH_handle_is_ready (mint)) @@ -1543,12 +1547,48 @@ TALER_MINT_refresh_reveal (struct TALER_MINT_Handle *mint, GNUNET_break (0); return NULL; } + if (noreveal_index >= TALER_CNC_KAPPA) + { + /* We check this here, as it would be really bad to below just + disclose all the transfer keys. Note that this error should + have been caught way earlier when the mint replied, but maybe + we had some internal corruption that changed the value... */ + GNUNET_break (0); + return NULL; + } + + /* build array of transfer private keys */ + transfer_privs = json_array (); + for (i=0;inum_melted_coins;i++) + { + const struct MeltedCoin *mc = &md->melted_coins[i]; + + tmp = json_array (); + for (j=0;jtransfer_priv[j], + sizeof (struct TALER_TransferPrivateKeyP))); + } + json_array_append (transfer_privs, + tmp); + } - /* FIXME: totally bogus request building here: */ - reveal_obj = json_pack ("{s:o, s:O}", /* f/wire */ - "4", 42, - "6", 62); + /* build main JSON request */ + reveal_obj = json_pack ("{s:o, s:o}", + "session_hash", + TALER_json_from_data (&md->melt_session_hash, + sizeof (struct GNUNET_HashCode)), + "transfer_privs", + transfer_privs); + /* finally, we can actually issue the request */ rrh = GNUNET_new (struct TALER_MINT_RefreshRevealHandle); rrh->mint = mint; rrh->reveal_cb = reveal_cb; -- cgit v1.2.3 From 0be947809df3a138d11768403851f0171ad405d1 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 8 Aug 2015 20:10:16 +0200 Subject: handle HTTP OK status code for /refresh/melt --- src/mint-lib/mint_api_refresh.c | 81 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index a8953463..dad0ec16 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -1028,6 +1028,68 @@ struct TALER_MINT_RefreshMeltHandle }; +/** + * Verify that the signature on the "200 OK" response + * from the mint is valid. + * + * @param rmh melt handle + * @param json json reply with the signature + * @param[out] noreveal_index set to the noreveal index selected by the mint + * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not + */ +static int +verify_refresh_melt_signature_ok (struct TALER_MINT_RefreshMeltHandle *rmh, + json_t *json, + uint16_t *noreveal_index) +{ + struct TALER_MintSignatureP mint_sig; + struct TALER_MintPublicKeyP mint_pub; + const struct TALER_MINT_Keys *key_state; + struct MAJ_Specification spec[] = { + MAJ_spec_fixed_auto ("mint_sig", &mint_sig), + MAJ_spec_fixed_auto ("mint_pub", &mint_sig), + // MAJ_spec_uint16 ("noreveal_index", noreveal_index), // FIXME! + MAJ_spec_end + }; + struct TALER_RefreshMeltConfirmationPS confirm; + + if (GNUNET_OK != + MAJ_parse_json (json, + spec)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + key_state = TALER_MINT_get_keys (rmh->mint); + if (GNUNET_OK != + TALER_MINT_test_signing_key (key_state, + &mint_pub)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + if (TALER_CNC_KAPPA >= *noreveal_index) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + confirm.purpose.purpose = htonl (TALER_SIGNATURE_MINT_CONFIRM_MELT); + confirm.purpose.size = htonl (sizeof (confirm)); + confirm.session_hash = rmh->md->melt_session_hash; + confirm.noreveal_index = htons (*noreveal_index); + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MINT_CONFIRM_MELT, + &confirm.purpose, + &mint_sig.eddsa_signature, + &mint_pub.eddsa_pub)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + /** * Function called when we're done processing the * HTTP /refresh/melt request. @@ -1042,6 +1104,7 @@ handle_refresh_melt_finished (void *cls, struct TALER_MINT_RefreshMeltHandle *rmh = cls; long response_code; json_t *json; + uint16_t noreveal_index = TALER_CNC_KAPPA; /* invalid value */ rmh->job = NULL; json = MAC_download_get_result (&rmh->db, @@ -1052,8 +1115,22 @@ handle_refresh_melt_finished (void *cls, case 0: break; case MHD_HTTP_OK: - GNUNET_break (0); // FIXME: NOT implemented! (parse, check sig!) - + if (GNUNET_OK != + verify_refresh_melt_signature_ok (rmh, + json, + &noreveal_index)) + { + GNUNET_break_op (0); + response_code = 0; + } + if (NULL != rmh->melt_cb) + { + rmh->melt_cb (rmh->melt_cb_cls, + response_code, + noreveal_index, + json); + rmh->melt_cb = NULL; + } break; case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the mint is buggy -- cgit v1.2.3 From 6ea5858d3276378dd3636ecc36ed312a0ccaee61 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 8 Aug 2015 21:32:09 +0200 Subject: implementing verify_refresh_melt_signature_forbidden --- src/mint-lib/mint_api_refresh.c | 141 +++++++++++++++++++++++++++++++++- src/mint/taler-mint-httpd_responses.c | 2 +- 2 files changed, 140 insertions(+), 3 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index dad0ec16..ede95af5 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -25,6 +25,7 @@ #include /* just for HTTP status codes */ #include #include "taler_mint_service.h" +#include "mint_api_common.h" #include "mint_api_json.h" #include "mint_api_context.h" #include "mint_api_handle.h" @@ -58,6 +59,11 @@ struct MeltedCoinP */ struct TALER_AmountNBO fee_melt; + /** + * The original value of the coin. + */ + struct TALER_AmountNBO original_value; + /** * Transfer private keys for each cut-and-choose dimension. */ @@ -169,6 +175,11 @@ struct MeltedCoin */ struct TALER_Amount fee_melt; + /** + * The original value of the coin. + */ + struct TALER_Amount original_value; + /** * Transfer private keys for each cut-and-choose dimension. */ @@ -381,9 +392,10 @@ serialize_melted_coin (const struct MeltedCoin *mc, mcp.coin_priv = mc->coin_priv; TALER_amount_hton (&mcp.melt_amount_with_fee, &mc->melt_amount_with_fee); - TALER_amount_hton (&mcp.fee_melt, &mc->fee_melt); + TALER_amount_hton (&mcp.original_value, + &mc->original_value); for (i=0;itransfer_priv[i]; mcp.deposit_valid_until = GNUNET_TIME_absolute_hton (mc->deposit_valid_until); @@ -464,6 +476,8 @@ deserialize_melted_coin (struct MeltedCoin *mc, &mcp.melt_amount_with_fee); TALER_amount_ntoh (&mc->fee_melt, &mcp.fee_melt); + TALER_amount_ntoh (&mc->original_value, + &mcp.original_value); for (i=0;itransfer_priv[i] = mcp.transfer_priv[i]; mc->deposit_valid_until = GNUNET_TIME_absolute_ntoh (mcp.deposit_valid_until); @@ -868,6 +882,7 @@ TALER_MINT_refresh_prepare (unsigned int num_melts, md.melted_coins[i].coin_priv = melt_privs[i]; md.melted_coins[i].melt_amount_with_fee = melt_amounts[i]; md.melted_coins[i].fee_melt = melt_pks[i].fee_refresh; + md.melted_coins[i].original_value = melt_pks[i].value; for (j=0;jmd->num_melted_coins;i++) + { + if (0 == TALER_amount_cmp (&melt_value_with_fee, + &rmh->md->melted_coins[i].melt_amount_with_fee)) + { + struct TALER_CoinSpendPublicKeyP mc_pub; + + GNUNET_CRYPTO_eddsa_key_get_public (&rmh->md->melted_coins[i].coin_priv.eddsa_priv, + &mc_pub.eddsa_pub); + if (0 == memcmp (&mc_pub, + &coin_pub, + sizeof (struct TALER_CoinSpendPublicKeyP))) + { + mc = &rmh->md->melted_coins[i]; + break; + } + } + } + if (NULL == mc) + { + /* coin not found in our original request */ + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + + /* check basic coin properties */ + if (0 != TALER_amount_cmp (&original_value, + &mc->original_value)) + { + /* We disagree on the value of the coin */ + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + if (0 != TALER_amount_cmp (&melt_value_with_fee, + &mc->melt_amount_with_fee)) + { + /* We disagree on the value of the coin */ + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + + /* verify coin history */ + history = json_object_get (json, + "history"); + if (GNUNET_OK != + TALER_MINT_verify_coin_history_ (original_value.currency, + &coin_pub, + history, + &total)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + + /* check if melt operation was really too expensive given history */ + if (GNUNET_OK != + TALER_amount_add (&total, + &total, + &melt_value_with_fee)) + { + /* clearly not OK if our transaction would have caused + the overflow... */ + return GNUNET_OK; + } + + if (0 >= TALER_amount_cmp (&total, + &original_value)) + { + /* transaction should have still fit */ + GNUNET_break (0); + return GNUNET_SYSERR; + } + + /* everything OK, valid proof of double-spending was provided */ + return GNUNET_OK; +} + + /** * Function called when we're done processing the * HTTP /refresh/melt request. @@ -1138,7 +1269,13 @@ handle_refresh_melt_finished (void *cls, break; case MHD_HTTP_FORBIDDEN: /* Double spending; check signatures on transaction history */ - GNUNET_break (0); // FIXME: NOT implemented! + if (GNUNET_OK != + verify_refresh_melt_signature_forbidden (rmh, + json)) + { + GNUNET_break_op (0); + response_code = 0; + } break; case MHD_HTTP_UNAUTHORIZED: /* Nothing really to verify, mint says one of the signatures is diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c index 48c0a748..0e2f9070 100644 --- a/src/mint/taler-mint-httpd_responses.c +++ b/src/mint/taler-mint-httpd_responses.c @@ -695,7 +695,7 @@ TMH_RESPONSE_reply_withdraw_sign_success (struct MHD_Connection *connection, * @param coin_pub public key of the coin * @param coin_value original value of the coin * @param tl transaction history for the coin - * @param requested how much this coin was supposed to contribute + * @param requested how much this coin was supposed to contribute, including fee * @param residual remaining value of the coin (after subtracting @a tl) * @return a MHD result code */ -- cgit v1.2.3 From 189adf52eb96de135d531f53389ecce2d791268d Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 8 Aug 2015 21:46:26 +0200 Subject: finshing json parsing support for /refresh/melt handling --- src/mint-lib/mint_api_json.c | 75 +++++++++++++++++++++++++++++++++++++++++ src/mint-lib/mint_api_json.h | 46 +++++++++++++++++++++++-- src/mint-lib/mint_api_refresh.c | 9 +++-- 3 files changed, 126 insertions(+), 4 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_json.c b/src/mint-lib/mint_api_json.c index 8b0b5437..b1517394 100644 --- a/src/mint-lib/mint_api_json.c +++ b/src/mint-lib/mint_api_json.c @@ -253,6 +253,37 @@ parse_json (json_t *root, } break; + case MAJ_CMD_UINT16: + { + json_int_t val; + + if (! json_is_integer (pos)) + { + GNUNET_break_op (0); + return i; + } + val = json_integer_value (pos); + if ( (0 > val) || (val > UINT16_MAX) ) + { + GNUNET_break_op (0); + return i; + } + *spec[i].details.u16 = (uint16_t) val; + } + break; + + case MAJ_CMD_JSON_OBJECT: + { + if (! (json_is_object (pos) || json_is_array (pos)) ) + { + GNUNET_break_op (0); + return i; + } + json_incref (pos); + *spec[i].details.obj = pos; + } + break; + default: GNUNET_break (0); return i; @@ -307,6 +338,10 @@ parse_free (struct MAJ_Specification *spec, GNUNET_free (*spec[i].details.eddsa_signature.purpose_p); *spec[i].details.eddsa_signature.purpose_p = NULL; break; + case MAJ_CMD_JSON_OBJECT: + json_decref (*spec[i].details.obj); + *spec[i].details.obj = NULL; + break; default: GNUNET_break (0); break; @@ -417,6 +452,46 @@ MAJ_spec_amount (const char *name, } +/** + * 16-bit integer. + * + * @param name name of the JSON field + * @param[out] u16 where to store the integer found under @a name + */ +struct MAJ_Specification +MAJ_spec_uint16 (const char *name, + uint16_t *u16) +{ + struct MAJ_Specification ret = + { + .cmd = MAJ_CMD_UINT16, + .field = name, + .details.u16 = u16 + }; + return ret; +} + + +/** + * JSON object. + * + * @param name name of the JSON field + * @param[out] jsonp where to store the JSON found under @a name + */ +struct MAJ_Specification +MAJ_spec_json (const char *name, + json_t **jsonp) +{ + struct MAJ_Specification ret = + { + .cmd = MAJ_CMD_JSON_OBJECT, + .field = name, + .details.obj = jsonp + }; + return ret; +} + + /** * Specification for parsing an RSA public key. * diff --git a/src/mint-lib/mint_api_json.h b/src/mint-lib/mint_api_json.h index 46ccef3a..bca3b47c 100644 --- a/src/mint-lib/mint_api_json.h +++ b/src/mint-lib/mint_api_json.h @@ -79,7 +79,17 @@ enum MAJ_Command MAJ_CMD_STRING, /** - * Parse at current position. + * Parse `uint16_t` integer at the current position. + */ + MAJ_CMD_UINT16, + + /** + * Parse JSON object at the current position. + */ + MAJ_CMD_JSON_OBJECT, + + /** + * Parse ??? at current position. */ MAJ_CMD_C @@ -181,6 +191,16 @@ struct MAJ_Specification */ const char **strptr; + /** + * Where to store 16-bit integer. + */ + uint16_t *u16; + + /** + * Where to store a JSON object. + */ + json_t **obj; + } details; }; @@ -249,13 +269,35 @@ MAJ_spec_string (const char *name, * Absolute time. * * @param name name of the JSON field - * @param at where to store the absolute time found under @a name + * @param[out] at where to store the absolute time found under @a name */ struct MAJ_Specification MAJ_spec_absolute_time (const char *name, struct GNUNET_TIME_Absolute *at); +/** + * 16-bit integer. + * + * @param name name of the JSON field + * @param[out] u16 where to store the integer found under @a name + */ +struct MAJ_Specification +MAJ_spec_uint16 (const char *name, + uint16_t *u16); + + +/** + * JSON object. + * + * @param name name of the JSON field + * @param[out] jsonp where to store the JSON found under @a name + */ +struct MAJ_Specification +MAJ_spec_json (const char *name, + json_t **jsonp); + + /** * Specification for parsing an amount value. * diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index ede95af5..3012957d 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -1063,7 +1063,7 @@ verify_refresh_melt_signature_ok (struct TALER_MINT_RefreshMeltHandle *rmh, struct MAJ_Specification spec[] = { MAJ_spec_fixed_auto ("mint_sig", &mint_sig), MAJ_spec_fixed_auto ("mint_pub", &mint_sig), - // MAJ_spec_uint16 ("noreveal_index", noreveal_index), // FIXME! + MAJ_spec_uint16 ("noreveal_index", noreveal_index), MAJ_spec_end }; struct TALER_RefreshMeltConfirmationPS confirm; @@ -1124,7 +1124,7 @@ verify_refresh_melt_signature_forbidden (struct TALER_MINT_RefreshMeltHandle *rm struct TALER_CoinSpendPublicKeyP coin_pub; unsigned int i; struct MAJ_Specification spec[] = { - // MAJ_spec_json ("history", &history), // FIXME! + MAJ_spec_json ("history", &history), MAJ_spec_fixed_auto ("coin_pub", &coin_pub), MAJ_spec_amount ("original_value", &original_value), MAJ_spec_amount ("requested_value", &melt_value_with_fee), @@ -1165,6 +1165,7 @@ verify_refresh_melt_signature_forbidden (struct TALER_MINT_RefreshMeltHandle *rm { /* coin not found in our original request */ GNUNET_break_op (0); + json_decref (history); return GNUNET_SYSERR; } @@ -1174,6 +1175,7 @@ verify_refresh_melt_signature_forbidden (struct TALER_MINT_RefreshMeltHandle *rm { /* We disagree on the value of the coin */ GNUNET_break_op (0); + json_decref (history); return GNUNET_SYSERR; } if (0 != TALER_amount_cmp (&melt_value_with_fee, @@ -1181,6 +1183,7 @@ verify_refresh_melt_signature_forbidden (struct TALER_MINT_RefreshMeltHandle *rm { /* We disagree on the value of the coin */ GNUNET_break_op (0); + json_decref (history); return GNUNET_SYSERR; } @@ -1194,8 +1197,10 @@ verify_refresh_melt_signature_forbidden (struct TALER_MINT_RefreshMeltHandle *rm &total)) { GNUNET_break_op (0); + json_decref (history); return GNUNET_SYSERR; } + json_decref (history); /* check if melt operation was really too expensive given history */ if (GNUNET_OK != -- cgit v1.2.3 From 1e8529a19ed41d4ea8c92ab855d6b24a9f7b9899 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 8 Aug 2015 21:48:13 +0200 Subject: add missing conclusion over melt session hash computation --- src/mint-lib/mint_api_refresh.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 3012957d..51571009 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -985,6 +985,10 @@ TALER_MINT_refresh_prepare (unsigned int num_melts, GNUNET_free (link_enc); } } + GNUNET_CRYPTO_hash_context_finish (hash_context, + &md.melt_session_hash); + + /* finally, serialize everything */ buf = serialize_melt_data (&md, res_size); free_melt_data (&md); @@ -1075,6 +1079,8 @@ verify_refresh_melt_signature_ok (struct TALER_MINT_RefreshMeltHandle *rmh, GNUNET_break_op (0); return GNUNET_SYSERR; } + + /* check that mint signing key is permitted */ key_state = TALER_MINT_get_keys (rmh->mint); if (GNUNET_OK != TALER_MINT_test_signing_key (key_state, @@ -1083,11 +1089,15 @@ verify_refresh_melt_signature_ok (struct TALER_MINT_RefreshMeltHandle *rmh, GNUNET_break_op (0); return GNUNET_SYSERR; } + + /* check that noreveal index is in permitted range */ if (TALER_CNC_KAPPA >= *noreveal_index) { GNUNET_break_op (0); return GNUNET_SYSERR; } + + /* verify signature by mint */ confirm.purpose.purpose = htonl (TALER_SIGNATURE_MINT_CONFIRM_MELT); confirm.purpose.size = htonl (sizeof (confirm)); confirm.session_hash = rmh->md->melt_session_hash; -- cgit v1.2.3 From 6b048a0dc60f3c50f3fd3d6bed09dcf0d1f5a547 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 8 Aug 2015 22:11:58 +0200 Subject: implement handle_refresh_reveal_finished (200 OK handler) --- src/mint-lib/mint_api_refresh.c | 131 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 2 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 51571009..00f2a825 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -869,6 +869,7 @@ TALER_MINT_refresh_prepare (unsigned int num_melts, unsigned int j; struct GNUNET_HashContext *hash_context; + /* build up melt data structure */ for (i=0;imd->num_fresh_coins != json_array_size (jsona)) + { + /* Number of coins generated does not match our expectation */ + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + for (i=0;imd->num_fresh_coins;i++) + { + const struct FreshCoin *fc; + struct TALER_DenominationPublicKey *pk; + json_t *json; + struct GNUNET_CRYPTO_rsa_Signature *blind_sig; + struct GNUNET_CRYPTO_rsa_Signature *sig; + struct TALER_CoinSpendPublicKeyP coin_pub; + struct GNUNET_HashCode coin_hash; + + struct MAJ_Specification spec[] = { + MAJ_spec_rsa_signature ("ev_sig", &blind_sig), + MAJ_spec_end + }; + + fc = &rrh->md->fresh_coins[rrh->noreveal_index][i]; + pk = &rrh->md->fresh_pks[i]; + json = json_array_get (jsona, i); + GNUNET_assert (NULL != json); + + if (GNUNET_OK != + MAJ_parse_json (json, + spec)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + + /* unblind the signature */ + sig = GNUNET_CRYPTO_rsa_unblind (blind_sig, + fc->blinding_key.rsa_blinding_key, + pk->rsa_public_key); + GNUNET_CRYPTO_rsa_signature_free (blind_sig); + + /* verify the signature */ + GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv, + &coin_pub.eddsa_pub); + GNUNET_CRYPTO_hash (&coin_pub.eddsa_pub, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), + &coin_hash); + + if (GNUNET_OK != + GNUNET_CRYPTO_rsa_verify (&coin_hash, + sig, + pk->rsa_public_key)) + { + GNUNET_break_op (0); + GNUNET_CRYPTO_rsa_signature_free (sig); + return GNUNET_SYSERR; + } + coin_privs[i] = fc->coin_priv; + sigs[i].rsa_signature = sig; + } + return GNUNET_OK; +} + + /** * Function called when we're done processing the * HTTP /refresh/reveal request. @@ -1687,8 +1786,35 @@ handle_refresh_reveal_finished (void *cls, case 0: break; case MHD_HTTP_OK: - GNUNET_break (0); // FIXME: NOT implemented! - // rrh->reveal_cb = NULL; (call with real result, do not call again below) + { + struct TALER_CoinSpendPrivateKeyP coin_privs[rrh->md->num_fresh_coins]; + struct TALER_DenominationSignature sigs[rrh->md->num_fresh_coins]; + unsigned int i; + int ret; + + memset (sigs, 0, sizeof (sigs)); + ret = refresh_reveal_ok (rrh, + json, + coin_privs, + sigs); + if (GNUNET_OK != ret) + { + response_code = 0; + } + else + { + rrh->reveal_cb (rrh->reveal_cb_cls, + MHD_HTTP_OK, + rrh->md->num_fresh_coins, + coin_privs, + sigs, + json); + rrh->reveal_cb = NULL; + } + for (i=0;imd->num_fresh_coins;i++) + if (NULL != sigs[i].rsa_signature) + GNUNET_CRYPTO_rsa_signature_free (sigs[i].rsa_signature); + } break; case MHD_HTTP_BAD_REQUEST: /* This should never happen, either us or the mint is buggy @@ -1820,6 +1946,7 @@ TALER_MINT_refresh_reveal (struct TALER_MINT_Handle *mint, /* finally, we can actually issue the request */ rrh = GNUNET_new (struct TALER_MINT_RefreshRevealHandle); rrh->mint = mint; + rrh->noreveal_index = noreveal_index; rrh->reveal_cb = reveal_cb; rrh->reveal_cb_cls = reveal_cb_cls; rrh->md = md; -- cgit v1.2.3 From cb47e13322e3fefac95a80b4a32d2551f62202d1 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 8 Aug 2015 22:12:45 +0200 Subject: -newline --- src/mint-lib/mint_api_refresh.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 00f2a825..53526265 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -1848,7 +1848,6 @@ handle_refresh_reveal_finished (void *cls, } - /** * Submit a /refresh/reval request to the mint and get the mint's * response. -- cgit v1.2.3 From c6f88ebd61ba69cddf71b1b70a1952c61f1112b4 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 15:40:16 +0200 Subject: doxygen-fixes --- src/include/taler_crypto_lib.h | 2 +- src/include/taler_mint_service.h | 10 +++++----- src/mint-lib/mint_api_deposit.c | 2 +- src/mint-lib/mint_api_refresh.c | 10 +++++----- src/util/crypto.c | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 5f142507..0f25ea3c 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -477,7 +477,7 @@ TALER_link_decrypt_secret2 (const struct TALER_EncryptedLinkSecretP *secret_enc, * * @param coin_priv coin key * @param trans_priv transfer private key - * @param[out] computed transfer secret + * @param[out] ts computed transfer secret */ void TALER_link_derive_transfer_secret (const struct TALER_CoinSpendPrivateKeyP *coin_priv, diff --git a/src/include/taler_mint_service.h b/src/include/taler_mint_service.h index 8c5f520d..68813306 100644 --- a/src/include/taler_mint_service.h +++ b/src/include/taler_mint_service.h @@ -396,11 +396,11 @@ typedef void * * @param mint the mint handle; the mint must be ready to operate * @param amount the amount to be deposited - * @param wire the merchant’s account details, in a format supported by the mint + * @param wire_details the merchant’s account details, in a format supported by the mint * @param h_contract hash of the contact of the merchant with the customer (further details are never disclosed to the mint) * @param coin_pub coin’s public key * @param denom_pub denomination key with which the coin is signed - * @param ub_sig mint’s unblinded signature of the coin + * @param denom_sig mint’s unblinded signature of the coin * @param timestamp timestamp when the contract was finalized, must match approximately the current time of the mint * @param transaction_id transaction id for the transaction between merchant and customer * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests) @@ -635,7 +635,7 @@ TALER_MINT_withdraw_sign_cancel (struct TALER_MINT_WithdrawSignHandle *sign); * no money is lost in case of hardware failures, is operation does * not actually initiate the request. Instead, it generates a buffer * which the caller must store before proceeding with the actual call - * to #TALER_MINT_refresh_execute() that will generate the request. + * to #TALER_MINT_refresh_melt() that will generate the request. * * This function does verify that the given request data is internally * consistent. However, the @a melts_sigs are only verified if @a @@ -660,11 +660,11 @@ TALER_MINT_withdraw_sign_cancel (struct TALER_MINT_WithdrawSignHandle *sign); * @param check_sigs verify the validity of the signatures of @a melt_sigs * @param fresh_pks_len length of the @a pks array * @param fresh_pks array of @a pks_len denominations of fresh coins to create - * @param[OUT] res_size set to the size of the return value, or 0 on error + * @param[out] res_size set to the size of the return value, or 0 on error * @return NULL * if the inputs are invalid (i.e. denomination key not with this mint). * Otherwise, pointer to a buffer of @a res_size to store persistently - * before proceeding to #TALER_MINT_refresh_execute(). + * before proceeding to #TALER_MINT_refresh_melt(). * Non-null results should be freed using #GNUNET_free(). */ char * diff --git a/src/mint-lib/mint_api_deposit.c b/src/mint-lib/mint_api_deposit.c index 4484f1cd..3da9d0ae 100644 --- a/src/mint-lib/mint_api_deposit.c +++ b/src/mint-lib/mint_api_deposit.c @@ -358,7 +358,7 @@ verify_signatures (const struct TALER_MINT_DenomPublicKey *dki, * * @param mint the mint handle; the mint must be ready to operate * @param amount the amount to be deposited - * @param wire the merchant’s account details, in a format supported by the mint + * @param wire_details the merchant’s account details, in a format supported by the mint * @param h_contract hash of the contact of the merchant with the customer (further details are never disclosed to the mint) * @param coin_pub coin’s public key * @param denom_pub denomination key with which the coin is signed diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 53526265..d8391ac4 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -820,11 +820,11 @@ setup_fresh_coin (struct FreshCoin *fc, * no money is lost in case of hardware failures, is operation does * not actually initiate the request. Instead, it generates a buffer * which the caller must store before proceeding with the actual call - * to #TALER_MINT_refresh_execute() that will generate the request. + * to #TALER_MINT_refresh_melt() that will generate the request. * * This function does verify that the given request data is internally - * consistent. However, the @a melts_sigs are only verified if @a - * check_sigs is set to #GNUNET_YES, as this may be relatively + * consistent. However, the @a melts_sigs are only verified if + * @a check_sigs is set to #GNUNET_YES, as this may be relatively * expensive and should be redundant. * * Aside from some non-trivial cryptographic operations that might @@ -845,11 +845,11 @@ setup_fresh_coin (struct FreshCoin *fc, * @param check_sigs verify the validity of the signatures of @a melt_sigs * @param fresh_pks_len length of the @a pks array * @param fresh_pks array of @a pks_len denominations of fresh coins to create - * @param[OUT] res_size set to the size of the return value, or 0 on error + * @param[out] res_size set to the size of the return value, or 0 on error * @return NULL * if the inputs are invalid (i.e. denomination key not with this mint). * Otherwise, pointer to a buffer of @a res_size to store persistently - * before proceeding to #TALER_MINT_refresh_execute(). + * before proceeding to #TALER_MINT_refresh_melt(). * Non-null results should be freed using #GNUNET_free(). */ char * diff --git a/src/util/crypto.c b/src/util/crypto.c index edc30087..ebf6413d 100644 --- a/src/util/crypto.c +++ b/src/util/crypto.c @@ -171,7 +171,7 @@ TALER_transfer_decrypt (const struct TALER_EncryptedLinkSecretP *secret_enc, * * @param coin_priv coin key * @param trans_priv transfer private key - * @param[out] computed transfer secret + * @param[out] ts computed transfer secret */ void TALER_link_derive_transfer_secret (const struct TALER_CoinSpendPrivateKeyP *coin_priv, -- cgit v1.2.3 From f0d073410e3e618802cec44df05c822602741340 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 17:17:44 +0200 Subject: bugfix in return value calculation --- src/mint-lib/mint_api_refresh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index d8391ac4..442a73e1 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -519,7 +519,7 @@ serialize_denomination_key (const struct TALER_DenominationPublicKey *dk, pbuf, pbuf_size); GNUNET_free (pbuf); - return pbuf_size; + return pbuf_size + sizeof (uint32_t); } -- cgit v1.2.3 From d0fb01185085d6f4423d5fc2ea726113676749a8 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 18:31:26 +0200 Subject: fixing silly bug --- src/mint-lib/mint_api_refresh.c | 4 ++-- src/mint-lib/test_mint_api.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 442a73e1..58fe1126 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -647,7 +647,7 @@ deserialize_fresh_coin (struct FreshCoin *fc, fc->blinding_key.rsa_blinding_key = GNUNET_CRYPTO_rsa_blinding_key_decode (&buf[sizeof (struct FreshCoinP)], bbuf_size); - if (NULL == fc->blinding_key.rsa_blinding_key) + if (NULL == fc->blinding_key.rsa_blinding_key) { GNUNET_break (0); *ok = GNUNET_NO; @@ -740,7 +740,7 @@ deserialize_melt_data (const char *buf, return NULL; memcpy (&mdp, buf, - buf_size); + sizeof (struct MeltDataP)); md = GNUNET_new (struct MeltData); md->melt_session_hash = mdp.melt_session_hash; for (i=0;i Date: Sun, 9 Aug 2015 18:33:15 +0200 Subject: fixing very silly bug --- src/mint-lib/mint_api_refresh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 58fe1126..e5e9b291 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -1357,7 +1357,7 @@ melted_coin_to_json (const struct GNUNET_HashCode *melt_session_hash, sizeof (melt.coin_pub)), "denom_pub", TALER_json_from_rsa_public_key (mc->pub_key.rsa_public_key), - "denom_sig", 42, + "denom_sig", TALER_json_from_rsa_signature (mc->sig.rsa_signature), "confirm_sig", TALER_json_from_data (&confirm_sig, -- cgit v1.2.3 From 30959d1380ed79d71baee10ec547027b4911c760 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 18:42:38 +0200 Subject: fix array dimensions to match server expecations, fix server to report location of parse errors more precisely --- src/mint-lib/mint_api_refresh.c | 34 +++++++++++++++++++++++++--------- src/mint/taler-mint-httpd_refresh.c | 2 ++ 2 files changed, 27 insertions(+), 9 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index e5e9b291..294ca06e 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -1438,11 +1438,15 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint, json_array_append (melt_coins, melted_coin_to_json (&md->melt_session_hash, mc)); + } - /* now transfer_pubs */ + /* now transfer_pubs */ + for (j=0;jnum_melted_coins;i++) { + const struct MeltedCoin *mc = &md->melted_coins[i]; struct TALER_TransferPublicKeyP transfer_pub; GNUNET_CRYPTO_ecdhe_key_get_public (&mc->transfer_priv[j].ecdhe_priv, @@ -1453,11 +1457,15 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint, } json_array_append (transfer_pubs, tmp); + } - /* now secret_encs */ + /* now secret_encs */ + for (j=0;jnum_melted_coins;i++) { + const struct MeltedCoin *mc = &md->melted_coins[i]; struct TALER_EncryptedLinkSecretP els; struct TALER_TransferSecretP trans_sec; @@ -1475,16 +1483,20 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint, json_array_append (secret_encs, tmp); } + + /* now new_denoms */ for (i=0;inum_fresh_coins;i++) { - /* now new_denoms */ json_array_append (new_denoms, TALER_json_from_rsa_public_key (md->fresh_pks[i].rsa_public_key)); + } - /* now link_encs */ + /* now link_encs */ + for (j=0;jnum_fresh_coins;i++) { const struct FreshCoin *fc = &md->fresh_coins[j][i]; struct TALER_RefreshLinkDecrypted rld; @@ -1508,10 +1520,13 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint, } json_array_append (link_encs, tmp); + } - /* now coin_evs */ + /* now coin_evs */ + for (j=0;jnum_fresh_coins;i++) { const struct FreshCoin *fc = &md->fresh_coins[j][i]; struct TALER_CoinSpendPublicKeyP coin_pub; @@ -1536,6 +1551,7 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint, json_array_append (coin_evs, tmp); } + /* finally, assemble main JSON request from constitutent arrays */ melt_obj = json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o}", "new_denoms", new_denoms, diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c index 687fb998..d870f3a3 100644 --- a/src/mint/taler-mint-httpd_refresh.c +++ b/src/mint/taler-mint-httpd_refresh.c @@ -700,6 +700,7 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh, JSON_ARRAY, &coin_detail); if (GNUNET_OK != res) { + GNUNET_break_op (0); TMH_PARSE_release_data (spec); return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; } @@ -711,6 +712,7 @@ TMH_REFRESH_handler_refresh_melt (struct TMH_RequestHandler *rh, JSON_ARRAY, &coin_detail); if (GNUNET_OK != res) { + GNUNET_break_op (0); TMH_PARSE_release_data (spec); return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; } -- cgit v1.2.3 From cd4018e61a7e6abea2ba2620376a8e5590a77c22 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 19:31:59 +0200 Subject: fix signature purpose used, log session hash for diagnostics --- src/mint-lib/mint_api_refresh.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 294ca06e..36c19a16 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -1339,8 +1339,8 @@ melted_coin_to_json (const struct GNUNET_HashCode *melt_session_hash, struct TALER_CoinSpendSignatureP confirm_sig; struct TALER_RefreshMeltCoinAffirmationPS melt; - melt.purpose.purpose = htonl (TALER_SIGNATURE_MINT_CONFIRM_MELT); - melt.purpose.size = htonl (sizeof (melt)); + melt.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT); + melt.purpose.size = htonl (sizeof (struct TALER_RefreshMeltCoinAffirmationPS)); melt.session_hash = *melt_session_hash; TALER_amount_hton (&melt.amount_with_fee, &mc->melt_amount_with_fee); @@ -1351,6 +1351,9 @@ melted_coin_to_json (const struct GNUNET_HashCode *melt_session_hash, GNUNET_CRYPTO_eddsa_sign (&mc->coin_priv.eddsa_priv, &melt.purpose, &confirm_sig.eddsa_signature); + fprintf (stderr, + "Signing hash %s\n", + GNUNET_h2s (melt_session_hash)); return json_pack ("{s:o, s:o, s:o, s:o, s:o}", "coin_pub", TALER_json_from_data (&melt.coin_pub, -- cgit v1.2.3 From 0140dd818b226f13d5cc126bed62442922561c2a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 21:24:36 +0200 Subject: fix missing bits from session hash calculation --- src/mint-lib/mint_api_refresh.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 36c19a16..796eb23f 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -986,6 +986,27 @@ TALER_MINT_refresh_prepare (unsigned int num_melts, GNUNET_free (link_enc); } } + for (i = 0; i < TALER_CNC_KAPPA; i++) + { + for (j = 0; j < num_melts; j++) + { + struct TALER_MINTDB_RefreshCommitLinkP rcl; + struct TALER_TransferSecretP trans_sec; + + GNUNET_CRYPTO_ecdhe_key_get_public (&md.melted_coins[j].transfer_priv[i].ecdhe_priv, + &rcl.transfer_pub.ecdhe_pub); + TALER_link_derive_transfer_secret (&melt_privs[j], + &md.melted_coins[j].transfer_priv[i], + &trans_sec); + TALER_transfer_encrypt (&md.link_secrets[i], + &trans_sec, + &rcl.shared_secret_enc); + GNUNET_CRYPTO_hash_context_read (hash_context, + &rcl, + sizeof (struct TALER_MINTDB_RefreshCommitLinkP)); + } + } + GNUNET_CRYPTO_hash_context_finish (hash_context, &md.melt_session_hash); @@ -1351,9 +1372,6 @@ melted_coin_to_json (const struct GNUNET_HashCode *melt_session_hash, GNUNET_CRYPTO_eddsa_sign (&mc->coin_priv.eddsa_priv, &melt.purpose, &confirm_sig.eddsa_signature); - fprintf (stderr, - "Signing hash %s\n", - GNUNET_h2s (melt_session_hash)); return json_pack ("{s:o, s:o, s:o, s:o, s:o}", "coin_pub", TALER_json_from_data (&melt.coin_pub, @@ -1544,7 +1562,7 @@ TALER_MINT_refresh_melt (struct TALER_MINT_Handle *mint, &coin_hash); coin_ev_size = GNUNET_CRYPTO_rsa_blind (&coin_hash, fc->blinding_key.rsa_blinding_key, - md->fresh_pks[j].rsa_public_key, + md->fresh_pks[i].rsa_public_key, &coin_ev); json_array_append (tmp, TALER_json_from_data (coin_ev, -- cgit v1.2.3 From 6237981d9652889bbcc042e8b374c0addc65932f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 9 Aug 2015 21:25:49 +0200 Subject: rename struct TALER_MINTDB_RefreshCommitLinkP to struct TALER_RefreshCommitLinkP --- src/include/taler_mintdb_plugin.h | 6 +++--- src/include/taler_signatures.h | 2 +- src/mint-lib/mint_api_refresh.c | 4 ++-- src/mint/taler-mint-httpd_db.c | 6 +++--- src/mint/taler-mint-httpd_db.h | 2 +- src/mint/taler-mint-httpd_refresh.c | 12 ++++++------ src/mint/taler-mint-httpd_responses.c | 2 +- src/mintdb/plugin_mintdb_postgres.c | 6 +++--- 8 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src/mint-lib/mint_api_refresh.c') diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h index ba83c814..c5b9828d 100644 --- a/src/include/taler_mintdb_plugin.h +++ b/src/include/taler_mintdb_plugin.h @@ -539,7 +539,7 @@ struct TALER_MINTDB_MeltCommitment /** * 2D-Array of #TALER_CNC_KAPPA and @e new_oldcoins links. */ - struct TALER_MINTDB_RefreshCommitLinkP *commit_links[TALER_CNC_KAPPA]; + struct TALER_RefreshCommitLinkP *commit_links[TALER_CNC_KAPPA]; }; @@ -1002,7 +1002,7 @@ struct TALER_MINTDB_Plugin const struct GNUNET_HashCode *session_hash, uint16_t cnc_index, uint16_t num_links, - const struct TALER_MINTDB_RefreshCommitLinkP *commit_links); + const struct TALER_RefreshCommitLinkP *commit_links); /** * Obtain the commited (encrypted) refresh link data @@ -1024,7 +1024,7 @@ struct TALER_MINTDB_Plugin const struct GNUNET_HashCode *session_hash, uint16_t cnc_index, uint16_t num_links, - struct TALER_MINTDB_RefreshCommitLinkP *links); + struct TALER_RefreshCommitLinkP *links); /** diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index 0b05bace..c5348eb5 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -657,7 +657,7 @@ struct TALER_MintKeyValidityPS * Part of the construction of the refresh session's hash and * thus of what is signed there. */ -struct TALER_MINTDB_RefreshCommitLinkP +struct TALER_RefreshCommitLinkP { /** * Transfer public key, used to decrypt the @e shared_secret_enc diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 796eb23f..66e8ea83 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -990,7 +990,7 @@ TALER_MINT_refresh_prepare (unsigned int num_melts, { for (j = 0; j < num_melts; j++) { - struct TALER_MINTDB_RefreshCommitLinkP rcl; + struct TALER_RefreshCommitLinkP rcl; struct TALER_TransferSecretP trans_sec; GNUNET_CRYPTO_ecdhe_key_get_public (&md.melted_coins[j].transfer_priv[i].ecdhe_priv, @@ -1003,7 +1003,7 @@ TALER_MINT_refresh_prepare (unsigned int num_melts, &rcl.shared_secret_enc); GNUNET_CRYPTO_hash_context_read (hash_context, &rcl, - sizeof (struct TALER_MINTDB_RefreshCommitLinkP)); + sizeof (struct TALER_RefreshCommitLinkP)); } } diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index 4e91e7e7..e24102ea 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -623,7 +623,7 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection, unsigned int coin_count, const struct TMH_DB_MeltDetails *coin_melt_details, struct TALER_MINTDB_RefreshCommitCoin *const* commit_coin, - struct TALER_MINTDB_RefreshCommitLinkP *const* commit_link) + struct TALER_RefreshCommitLinkP *const* commit_link) { struct TMH_KS_StateHandle *key_state; struct TALER_MINTDB_RefreshSession refresh_session; @@ -839,11 +839,11 @@ check_commitment (struct MHD_Connection *connection, unsigned int j; struct TALER_LinkSecretP last_shared_secret; int secret_initialized = GNUNET_NO; - struct TALER_MINTDB_RefreshCommitLinkP *commit_links; + struct TALER_RefreshCommitLinkP *commit_links; struct TALER_MINTDB_RefreshCommitCoin *commit_coins; commit_links = GNUNET_malloc (num_oldcoins * - sizeof (struct TALER_MINTDB_RefreshCommitLinkP)); + sizeof (struct TALER_RefreshCommitLinkP)); if (GNUNET_OK != TMH_plugin->get_refresh_commit_links (TMH_plugin->cls, session, diff --git a/src/mint/taler-mint-httpd_db.h b/src/mint/taler-mint-httpd_db.h index 8a171153..c2f9a310 100644 --- a/src/mint/taler-mint-httpd_db.h +++ b/src/mint/taler-mint-httpd_db.h @@ -130,7 +130,7 @@ TMH_DB_execute_refresh_melt (struct MHD_Connection *connection, unsigned int coin_count, const struct TMH_DB_MeltDetails *coin_melt_details, struct TALER_MINTDB_RefreshCommitCoin *const* commit_coin, - struct TALER_MINTDB_RefreshCommitLinkP *const* commit_link); + struct TALER_RefreshCommitLinkP *const* commit_link); /** diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c index 7bcaa799..954d8daf 100644 --- a/src/mint/taler-mint-httpd_refresh.c +++ b/src/mint/taler-mint-httpd_refresh.c @@ -57,7 +57,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection, const struct TMH_DB_MeltDetails *coin_melt_details, const struct GNUNET_HashCode *session_hash, struct TALER_MINTDB_RefreshCommitCoin *const* commit_coin, - struct TALER_MINTDB_RefreshCommitLinkP *const* commit_link) + struct TALER_RefreshCommitLinkP *const* commit_link) { unsigned int i; struct TMH_KS_StateHandle *key_state; @@ -324,7 +324,7 @@ free_commit_coins (struct TALER_MINTDB_RefreshCommitCoin **commit_coin, * @param num_old_coins size of 2nd dimension */ static void -free_commit_links (struct TALER_MINTDB_RefreshCommitLinkP **commit_link, +free_commit_links (struct TALER_RefreshCommitLinkP **commit_link, unsigned int kappa, unsigned int num_old_coins) { @@ -378,7 +378,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection, struct GNUNET_HashCode session_hash; struct GNUNET_HashContext *hash_context; struct TALER_MINTDB_RefreshCommitCoin *commit_coin[TALER_CNC_KAPPA]; - struct TALER_MINTDB_RefreshCommitLinkP *commit_link[TALER_CNC_KAPPA]; + struct TALER_RefreshCommitLinkP *commit_link[TALER_CNC_KAPPA]; /* For the signature check, we hash most of the inputs together (except for the signatures on the coins). */ @@ -532,10 +532,10 @@ handle_refresh_melt_json (struct MHD_Connection *connection, for (i = 0; i < TALER_CNC_KAPPA; i++) { commit_link[i] = GNUNET_malloc (num_oldcoins * - sizeof (struct TALER_MINTDB_RefreshCommitLinkP)); + sizeof (struct TALER_RefreshCommitLinkP)); for (j = 0; j < num_oldcoins; j++) { - struct TALER_MINTDB_RefreshCommitLinkP *rcl = &commit_link[i][j]; + struct TALER_RefreshCommitLinkP *rcl = &commit_link[i][j]; res = TMH_PARSE_navigate_json (connection, transfer_pubs, @@ -582,7 +582,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection, GNUNET_CRYPTO_hash_context_read (hash_context, rcl, - sizeof (struct TALER_MINTDB_RefreshCommitLinkP)); + sizeof (struct TALER_RefreshCommitLinkP)); } } diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c index 0e2f9070..9a6813f1 100644 --- a/src/mint/taler-mint-httpd_responses.c +++ b/src/mint/taler-mint-httpd_responses.c @@ -900,7 +900,7 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection, info_link_k = json_array (); for (i=0;inum_newcoins;i++) { - const struct TALER_MINTDB_RefreshCommitLinkP *cl; + const struct TALER_RefreshCommitLinkP *cl; json_t *cl_json; cl = &mc->commit_links[k][i]; diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c index 57455fcc..658d8dd9 100644 --- a/src/mintdb/plugin_mintdb_postgres.c +++ b/src/mintdb/plugin_mintdb_postgres.c @@ -2640,7 +2640,7 @@ postgres_insert_refresh_commit_links (void *cls, const struct GNUNET_HashCode *session_hash, uint16_t cnc_index, uint16_t num_links, - const struct TALER_MINTDB_RefreshCommitLinkP *links) + const struct TALER_RefreshCommitLinkP *links) { // FIXME: check logic! links is array! struct TALER_PQ_QueryParam params[] = { @@ -2693,7 +2693,7 @@ postgres_get_refresh_commit_links (void *cls, const struct GNUNET_HashCode *session_hash, uint16_t cnc_index, uint16_t num_links, - struct TALER_MINTDB_RefreshCommitLinkP *links) + struct TALER_RefreshCommitLinkP *links) { // FIXME: check logic: was written for a single link! struct TALER_PQ_QueryParam params[] = { @@ -2801,7 +2801,7 @@ postgres_get_melt_commitment (void *cls, goto cleanup; mc->commit_links[cnc_index] = GNUNET_malloc (mc->num_oldcoins * - sizeof (struct TALER_MINTDB_RefreshCommitLinkP)); + sizeof (struct TALER_RefreshCommitLinkP)); if (GNUNET_OK != postgres_get_refresh_commit_links (cls, session, -- cgit v1.2.3