move coin validity test to libtalerutil
This commit is contained in:
parent
2debf6c3f0
commit
62d3d35250
@ -251,6 +251,47 @@ TALER_data_to_string_alloc (const void *buf,
|
|||||||
size_t size);
|
size_t size);
|
||||||
|
|
||||||
|
|
||||||
|
/* ****************** Coin crypto primitives ************* */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public information about a coin (including the public key
|
||||||
|
* of the coin, the denomination key and the signature with
|
||||||
|
* the denomination key).
|
||||||
|
*/
|
||||||
|
struct TALER_CoinPublicInfo
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The coin's public key.
|
||||||
|
*/
|
||||||
|
struct GNUNET_CRYPTO_EcdsaPublicKey coin_pub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public key representing the denomination of the coin
|
||||||
|
* that is being deposited.
|
||||||
|
*/
|
||||||
|
struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Unblinded) signature over @e coin_pub with @e denom_pub,
|
||||||
|
* which demonstrates that the coin is valid.
|
||||||
|
*/
|
||||||
|
struct GNUNET_CRYPTO_rsa_Signature *denom_sig;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a coin is valid; that is, whether the denomination key exists,
|
||||||
|
* is not expired, and the signature is correct.
|
||||||
|
*
|
||||||
|
* @param coin_public_info the coin public info to check for validity
|
||||||
|
* @return #GNUNET_YES if the coin is valid,
|
||||||
|
* #GNUNET_NO if it is invalid
|
||||||
|
* #GNUNET_SYSERROR if an internal error occured
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info);
|
||||||
|
|
||||||
|
|
||||||
/* ****************** Refresh crypto primitives ************* */
|
/* ****************** Refresh crypto primitives ************* */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,31 +34,6 @@
|
|||||||
#define MINT_CURRENCY "EUR"
|
#define MINT_CURRENCY "EUR"
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public information about a coin (including the public key
|
|
||||||
* of the coin, the denomination key and the signature with
|
|
||||||
* the denomination key).
|
|
||||||
*/
|
|
||||||
struct TALER_CoinPublicInfo
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The coin's public key.
|
|
||||||
*/
|
|
||||||
struct GNUNET_CRYPTO_EcdsaPublicKey coin_pub;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public key representing the denomination of the coin
|
|
||||||
* that is being deposited.
|
|
||||||
*/
|
|
||||||
struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* (Unblinded) signature over @e coin_pub with @e denom_pub,
|
|
||||||
* which demonstrates that the coin is valid.
|
|
||||||
*/
|
|
||||||
struct GNUNET_CRYPTO_rsa_Signature *denom_sig;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information we keep for a withdrawn coin to reproduce
|
* Information we keep for a withdrawn coin to reproduce
|
||||||
@ -91,9 +66,6 @@ struct CollectableBlindcoin
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global information for a refreshing session.
|
* Global information for a refreshing session.
|
||||||
*/
|
*/
|
||||||
|
@ -59,6 +59,7 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
struct MintKeyState *key_state;
|
struct MintKeyState *key_state;
|
||||||
struct TALER_DepositRequest dr;
|
struct TALER_DepositRequest dr;
|
||||||
|
struct TALER_MINT_DenomKeyIssuePriv *dki;
|
||||||
|
|
||||||
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_DEPOSIT);
|
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_DEPOSIT);
|
||||||
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequest));
|
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequest));
|
||||||
@ -77,11 +78,20 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
|
|||||||
return TALER_MINT_reply_arg_invalid (connection,
|
return TALER_MINT_reply_arg_invalid (connection,
|
||||||
"csig");
|
"csig");
|
||||||
}
|
}
|
||||||
|
/* check denomination exists and is valid */
|
||||||
key_state = TALER_MINT_key_state_acquire ();
|
key_state = TALER_MINT_key_state_acquire ();
|
||||||
|
dki = TALER_MINT_get_denom_key (key_state,
|
||||||
|
deposit->coin.denom_pub);
|
||||||
|
if (NULL == dki)
|
||||||
|
{
|
||||||
|
TALER_MINT_key_state_release (key_state);
|
||||||
|
LOG_WARNING ("Unknown denomination key in /deposit request\n");
|
||||||
|
return TALER_MINT_reply_arg_invalid (connection,
|
||||||
|
"denom_pub");
|
||||||
|
}
|
||||||
|
/* check coin signature */
|
||||||
if (GNUNET_YES !=
|
if (GNUNET_YES !=
|
||||||
TALER_MINT_test_coin_valid (key_state,
|
TALER_test_coin_valid (&deposit->coin))
|
||||||
&deposit->coin))
|
|
||||||
{
|
{
|
||||||
LOG_WARNING ("Invalid coin passed for /deposit\n");
|
LOG_WARNING ("Invalid coin passed for /deposit\n");
|
||||||
TALER_MINT_key_state_release (key_state);
|
TALER_MINT_key_state_release (key_state);
|
||||||
|
@ -72,41 +72,6 @@ TALER_MINT_handler_keys (struct RequestHandler *rh,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a coin is valid; that is, whether the denomination key exists,
|
|
||||||
* is not expired, and the signature is correct.
|
|
||||||
*
|
|
||||||
* @param key_state the key state to use for checking the coin's validity
|
|
||||||
* @param coin_public_info the coin public info to check for validity
|
|
||||||
* @return #GNUNET_YES if the coin is valid,
|
|
||||||
* #GNUNET_NO if it is invalid
|
|
||||||
* #GNUNET_SYSERROR if an internal error occured
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
TALER_MINT_test_coin_valid (const struct MintKeyState *key_state,
|
|
||||||
const struct TALER_CoinPublicInfo *coin_public_info)
|
|
||||||
{
|
|
||||||
struct TALER_MINT_DenomKeyIssuePriv *dki;
|
|
||||||
struct GNUNET_HashCode c_hash;
|
|
||||||
|
|
||||||
dki = TALER_MINT_get_denom_key (key_state, coin_public_info->denom_pub);
|
|
||||||
if (NULL == dki)
|
|
||||||
return GNUNET_NO;
|
|
||||||
/* FIXME: we had envisioned a more complex scheme... */
|
|
||||||
GNUNET_CRYPTO_hash (&coin_public_info->coin_pub,
|
|
||||||
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
|
|
||||||
&c_hash);
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
GNUNET_CRYPTO_rsa_verify (&c_hash,
|
|
||||||
coin_public_info->denom_sig,
|
|
||||||
dki->issue.denom_pub))
|
|
||||||
{
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
|
||||||
"coin signature is invalid\n");
|
|
||||||
return GNUNET_NO;
|
|
||||||
}
|
|
||||||
return GNUNET_YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -262,6 +262,7 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
|
|||||||
json_t *melt_sig_json;
|
json_t *melt_sig_json;
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t buf_size;
|
size_t buf_size;
|
||||||
|
struct TALER_MINT_DenomKeyIssuePriv *dki;
|
||||||
|
|
||||||
res = TALER_MINT_parse_post_json (connection,
|
res = TALER_MINT_parse_post_json (connection,
|
||||||
connection_cls,
|
connection_cls,
|
||||||
@ -360,24 +361,39 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
|
|||||||
{
|
{
|
||||||
GNUNET_break (GNUNET_SYSERR != res);
|
GNUNET_break (GNUNET_SYSERR != res);
|
||||||
// FIXME: leaks!
|
// FIXME: leaks!
|
||||||
|
TALER_MINT_key_state_release (key_state);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
/* check that this coin's private key was used to sign that
|
/* check that this coin's private key was used to sign that
|
||||||
we should melt it */
|
we should melt it */
|
||||||
if (GNUNET_OK != (res = check_confirm_signature (connection,
|
if (GNUNET_OK !=
|
||||||
json_array_get (melt_coins, i),
|
(res = check_confirm_signature (connection,
|
||||||
&coin_public_infos[i].coin_pub,
|
json_array_get (melt_coins, i),
|
||||||
&refresh_session_pub)))
|
&coin_public_infos[i].coin_pub,
|
||||||
{
|
&refresh_session_pub)))
|
||||||
GNUNET_break (GNUNET_SYSERR != res);
|
{
|
||||||
// FIXME: leaks!
|
GNUNET_break (GNUNET_SYSERR != res);
|
||||||
return res;
|
// FIXME: leaks!
|
||||||
}
|
TALER_MINT_key_state_release (key_state);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
/* check coin denomination is valid */
|
||||||
|
dki = TALER_MINT_get_denom_key (key_state,
|
||||||
|
coin_public_infos[i].denom_pub);
|
||||||
|
if (NULL == dki)
|
||||||
|
{
|
||||||
|
TALER_MINT_key_state_release (key_state);
|
||||||
|
LOG_WARNING ("Unknown denomination key in /refresh/melt request\n");
|
||||||
|
TALER_MINT_key_state_release (key_state);
|
||||||
|
return TALER_MINT_reply_arg_invalid (connection,
|
||||||
|
"melt_coins");
|
||||||
|
}
|
||||||
/* check mint signature on the coin */
|
/* check mint signature on the coin */
|
||||||
if (GNUNET_OK != TALER_MINT_test_coin_valid (key_state,
|
if (GNUNET_OK !=
|
||||||
&coin_public_infos[i]))
|
TALER_test_coin_valid (&coin_public_infos[i]))
|
||||||
{
|
{
|
||||||
// FIXME: leaks!
|
// FIXME: leaks!
|
||||||
|
TALER_MINT_key_state_release (key_state);
|
||||||
return (MHD_YES ==
|
return (MHD_YES ==
|
||||||
TALER_MINT_reply_json_pack (connection,
|
TALER_MINT_reply_json_pack (connection,
|
||||||
MHD_HTTP_NOT_FOUND,
|
MHD_HTTP_NOT_FOUND,
|
||||||
|
@ -267,4 +267,35 @@ TALER_refresh_encrypt (const struct TALER_RefreshLinkDecrypted *input,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a coin is valid; that is, whether the denomination key exists,
|
||||||
|
* is not expired, and the signature is correct.
|
||||||
|
*
|
||||||
|
* @param coin_public_info the coin public info to check for validity
|
||||||
|
* @return #GNUNET_YES if the coin is valid,
|
||||||
|
* #GNUNET_NO if it is invalid
|
||||||
|
* #GNUNET_SYSERROR if an internal error occured
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info)
|
||||||
|
{
|
||||||
|
struct GNUNET_HashCode c_hash;
|
||||||
|
|
||||||
|
/* FIXME: we had envisioned a more complex scheme... */
|
||||||
|
GNUNET_CRYPTO_hash (&coin_public_info->coin_pub,
|
||||||
|
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
|
||||||
|
&c_hash);
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CRYPTO_rsa_verify (&c_hash,
|
||||||
|
coin_public_info->denom_sig,
|
||||||
|
coin_public_info->denom_pub))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"coin signature is invalid\n");
|
||||||
|
return GNUNET_NO;
|
||||||
|
}
|
||||||
|
return GNUNET_YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* end of crypto.c */
|
/* end of crypto.c */
|
||||||
|
Loading…
Reference in New Issue
Block a user