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);
|
||||
|
||||
|
||||
/* ****************** 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 ************* */
|
||||
|
||||
/**
|
||||
|
@ -34,31 +34,6 @@
|
||||
#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
|
||||
@ -91,9 +66,6 @@ struct CollectableBlindcoin
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Global information for a refreshing session.
|
||||
*/
|
||||
|
@ -59,6 +59,7 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
|
||||
{
|
||||
struct MintKeyState *key_state;
|
||||
struct TALER_DepositRequest dr;
|
||||
struct TALER_MINT_DenomKeyIssuePriv *dki;
|
||||
|
||||
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_DEPOSIT);
|
||||
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,
|
||||
"csig");
|
||||
}
|
||||
|
||||
/* check denomination exists and is valid */
|
||||
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 !=
|
||||
TALER_MINT_test_coin_valid (key_state,
|
||||
&deposit->coin))
|
||||
TALER_test_coin_valid (&deposit->coin))
|
||||
{
|
||||
LOG_WARNING ("Invalid coin passed for /deposit\n");
|
||||
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;
|
||||
char *buf;
|
||||
size_t buf_size;
|
||||
struct TALER_MINT_DenomKeyIssuePriv *dki;
|
||||
|
||||
res = TALER_MINT_parse_post_json (connection,
|
||||
connection_cls,
|
||||
@ -360,24 +361,39 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
|
||||
{
|
||||
GNUNET_break (GNUNET_SYSERR != res);
|
||||
// FIXME: leaks!
|
||||
TALER_MINT_key_state_release (key_state);
|
||||
return res;
|
||||
}
|
||||
/* check that this coin's private key was used to sign that
|
||||
we should melt it */
|
||||
if (GNUNET_OK != (res = check_confirm_signature (connection,
|
||||
json_array_get (melt_coins, i),
|
||||
&coin_public_infos[i].coin_pub,
|
||||
&refresh_session_pub)))
|
||||
{
|
||||
GNUNET_break (GNUNET_SYSERR != res);
|
||||
// FIXME: leaks!
|
||||
return res;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
(res = check_confirm_signature (connection,
|
||||
json_array_get (melt_coins, i),
|
||||
&coin_public_infos[i].coin_pub,
|
||||
&refresh_session_pub)))
|
||||
{
|
||||
GNUNET_break (GNUNET_SYSERR != 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 */
|
||||
if (GNUNET_OK != TALER_MINT_test_coin_valid (key_state,
|
||||
&coin_public_infos[i]))
|
||||
if (GNUNET_OK !=
|
||||
TALER_test_coin_valid (&coin_public_infos[i]))
|
||||
{
|
||||
// FIXME: leaks!
|
||||
TALER_MINT_key_state_release (key_state);
|
||||
return (MHD_YES ==
|
||||
TALER_MINT_reply_json_pack (connection,
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user