diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-01-28 20:23:19 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-01-28 20:23:19 +0100 |
commit | 62d3d352502f5b1d109b18456a87c704a70fcca5 (patch) | |
tree | 020ccf88cf701c29faa59a3f22650946e5d0eb2b | |
parent | 2debf6c3f0462a4743484c0cde7c951940e5cd2a (diff) | |
download | exchange-62d3d352502f5b1d109b18456a87c704a70fcca5.tar.gz exchange-62d3d352502f5b1d109b18456a87c704a70fcca5.zip |
move coin validity test to libtalerutil
-rw-r--r-- | src/include/taler_util.h | 41 | ||||
-rw-r--r-- | src/mint/mint.h | 28 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_deposit.c | 16 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_keys.c | 35 | ||||
-rw-r--r-- | src/mint/taler-mint-httpd_refresh.c | 38 | ||||
-rw-r--r-- | src/util/crypto.c | 31 |
6 files changed, 112 insertions, 77 deletions
diff --git a/src/include/taler_util.h b/src/include/taler_util.h index ab5ee11df..5ee90a6cc 100644 --- a/src/include/taler_util.h +++ b/src/include/taler_util.h | |||
@@ -251,6 +251,47 @@ TALER_data_to_string_alloc (const void *buf, | |||
251 | size_t size); | 251 | size_t size); |
252 | 252 | ||
253 | 253 | ||
254 | /* ****************** Coin crypto primitives ************* */ | ||
255 | |||
256 | /** | ||
257 | * Public information about a coin (including the public key | ||
258 | * of the coin, the denomination key and the signature with | ||
259 | * the denomination key). | ||
260 | */ | ||
261 | struct TALER_CoinPublicInfo | ||
262 | { | ||
263 | /** | ||
264 | * The coin's public key. | ||
265 | */ | ||
266 | struct GNUNET_CRYPTO_EcdsaPublicKey coin_pub; | ||
267 | |||
268 | /** | ||
269 | * Public key representing the denomination of the coin | ||
270 | * that is being deposited. | ||
271 | */ | ||
272 | struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub; | ||
273 | |||
274 | /** | ||
275 | * (Unblinded) signature over @e coin_pub with @e denom_pub, | ||
276 | * which demonstrates that the coin is valid. | ||
277 | */ | ||
278 | struct GNUNET_CRYPTO_rsa_Signature *denom_sig; | ||
279 | }; | ||
280 | |||
281 | |||
282 | /** | ||
283 | * Check if a coin is valid; that is, whether the denomination key exists, | ||
284 | * is not expired, and the signature is correct. | ||
285 | * | ||
286 | * @param coin_public_info the coin public info to check for validity | ||
287 | * @return #GNUNET_YES if the coin is valid, | ||
288 | * #GNUNET_NO if it is invalid | ||
289 | * #GNUNET_SYSERROR if an internal error occured | ||
290 | */ | ||
291 | int | ||
292 | TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info); | ||
293 | |||
294 | |||
254 | /* ****************** Refresh crypto primitives ************* */ | 295 | /* ****************** Refresh crypto primitives ************* */ |
255 | 296 | ||
256 | /** | 297 | /** |
diff --git a/src/mint/mint.h b/src/mint/mint.h index 13719e625..b29162b20 100644 --- a/src/mint/mint.h +++ b/src/mint/mint.h | |||
@@ -34,31 +34,6 @@ | |||
34 | #define MINT_CURRENCY "EUR" | 34 | #define MINT_CURRENCY "EUR" |
35 | 35 | ||
36 | 36 | ||
37 | /** | ||
38 | * Public information about a coin (including the public key | ||
39 | * of the coin, the denomination key and the signature with | ||
40 | * the denomination key). | ||
41 | */ | ||
42 | struct TALER_CoinPublicInfo | ||
43 | { | ||
44 | /** | ||
45 | * The coin's public key. | ||
46 | */ | ||
47 | struct GNUNET_CRYPTO_EcdsaPublicKey coin_pub; | ||
48 | |||
49 | /** | ||
50 | * Public key representing the denomination of the coin | ||
51 | * that is being deposited. | ||
52 | */ | ||
53 | struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub; | ||
54 | |||
55 | /** | ||
56 | * (Unblinded) signature over @e coin_pub with @e denom_pub, | ||
57 | * which demonstrates that the coin is valid. | ||
58 | */ | ||
59 | struct GNUNET_CRYPTO_rsa_Signature *denom_sig; | ||
60 | }; | ||
61 | |||
62 | 37 | ||
63 | /** | 38 | /** |
64 | * Information we keep for a withdrawn coin to reproduce | 39 | * Information we keep for a withdrawn coin to reproduce |
@@ -91,9 +66,6 @@ struct CollectableBlindcoin | |||
91 | }; | 66 | }; |
92 | 67 | ||
93 | 68 | ||
94 | |||
95 | |||
96 | |||
97 | /** | 69 | /** |
98 | * Global information for a refreshing session. | 70 | * Global information for a refreshing session. |
99 | */ | 71 | */ |
diff --git a/src/mint/taler-mint-httpd_deposit.c b/src/mint/taler-mint-httpd_deposit.c index 0bd1134a6..63ce03579 100644 --- a/src/mint/taler-mint-httpd_deposit.c +++ b/src/mint/taler-mint-httpd_deposit.c | |||
@@ -59,6 +59,7 @@ verify_and_execute_deposit (struct MHD_Connection *connection, | |||
59 | { | 59 | { |
60 | struct MintKeyState *key_state; | 60 | struct MintKeyState *key_state; |
61 | struct TALER_DepositRequest dr; | 61 | struct TALER_DepositRequest dr; |
62 | struct TALER_MINT_DenomKeyIssuePriv *dki; | ||
62 | 63 | ||
63 | dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_DEPOSIT); | 64 | dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_DEPOSIT); |
64 | dr.purpose.size = htonl (sizeof (struct TALER_DepositRequest)); | 65 | dr.purpose.size = htonl (sizeof (struct TALER_DepositRequest)); |
@@ -77,11 +78,20 @@ verify_and_execute_deposit (struct MHD_Connection *connection, | |||
77 | return TALER_MINT_reply_arg_invalid (connection, | 78 | return TALER_MINT_reply_arg_invalid (connection, |
78 | "csig"); | 79 | "csig"); |
79 | } | 80 | } |
80 | 81 | /* check denomination exists and is valid */ | |
81 | key_state = TALER_MINT_key_state_acquire (); | 82 | key_state = TALER_MINT_key_state_acquire (); |
83 | dki = TALER_MINT_get_denom_key (key_state, | ||
84 | deposit->coin.denom_pub); | ||
85 | if (NULL == dki) | ||
86 | { | ||
87 | TALER_MINT_key_state_release (key_state); | ||
88 | LOG_WARNING ("Unknown denomination key in /deposit request\n"); | ||
89 | return TALER_MINT_reply_arg_invalid (connection, | ||
90 | "denom_pub"); | ||
91 | } | ||
92 | /* check coin signature */ | ||
82 | if (GNUNET_YES != | 93 | if (GNUNET_YES != |
83 | TALER_MINT_test_coin_valid (key_state, | 94 | TALER_test_coin_valid (&deposit->coin)) |
84 | &deposit->coin)) | ||
85 | { | 95 | { |
86 | LOG_WARNING ("Invalid coin passed for /deposit\n"); | 96 | LOG_WARNING ("Invalid coin passed for /deposit\n"); |
87 | TALER_MINT_key_state_release (key_state); | 97 | TALER_MINT_key_state_release (key_state); |
diff --git a/src/mint/taler-mint-httpd_keys.c b/src/mint/taler-mint-httpd_keys.c index fc425876f..71d7f077e 100644 --- a/src/mint/taler-mint-httpd_keys.c +++ b/src/mint/taler-mint-httpd_keys.c | |||
@@ -72,41 +72,6 @@ TALER_MINT_handler_keys (struct RequestHandler *rh, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | 74 | ||
75 | /** | ||
76 | * Check if a coin is valid; that is, whether the denomination key exists, | ||
77 | * is not expired, and the signature is correct. | ||
78 | * | ||
79 | * @param key_state the key state to use for checking the coin's validity | ||
80 | * @param coin_public_info the coin public info to check for validity | ||
81 | * @return #GNUNET_YES if the coin is valid, | ||
82 | * #GNUNET_NO if it is invalid | ||
83 | * #GNUNET_SYSERROR if an internal error occured | ||
84 | */ | ||
85 | int | ||
86 | TALER_MINT_test_coin_valid (const struct MintKeyState *key_state, | ||
87 | const struct TALER_CoinPublicInfo *coin_public_info) | ||
88 | { | ||
89 | struct TALER_MINT_DenomKeyIssuePriv *dki; | ||
90 | struct GNUNET_HashCode c_hash; | ||
91 | |||
92 | dki = TALER_MINT_get_denom_key (key_state, coin_public_info->denom_pub); | ||
93 | if (NULL == dki) | ||
94 | return GNUNET_NO; | ||
95 | /* FIXME: we had envisioned a more complex scheme... */ | ||
96 | GNUNET_CRYPTO_hash (&coin_public_info->coin_pub, | ||
97 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), | ||
98 | &c_hash); | ||
99 | if (GNUNET_OK != | ||
100 | GNUNET_CRYPTO_rsa_verify (&c_hash, | ||
101 | coin_public_info->denom_sig, | ||
102 | dki->issue.denom_pub)) | ||
103 | { | ||
104 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
105 | "coin signature is invalid\n"); | ||
106 | return GNUNET_NO; | ||
107 | } | ||
108 | return GNUNET_YES; | ||
109 | } | ||
110 | 75 | ||
111 | 76 | ||
112 | /** | 77 | /** |
diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c index 057414a8f..5983962f8 100644 --- a/src/mint/taler-mint-httpd_refresh.c +++ b/src/mint/taler-mint-httpd_refresh.c | |||
@@ -262,6 +262,7 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh, | |||
262 | json_t *melt_sig_json; | 262 | json_t *melt_sig_json; |
263 | char *buf; | 263 | char *buf; |
264 | size_t buf_size; | 264 | size_t buf_size; |
265 | struct TALER_MINT_DenomKeyIssuePriv *dki; | ||
265 | 266 | ||
266 | res = TALER_MINT_parse_post_json (connection, | 267 | res = TALER_MINT_parse_post_json (connection, |
267 | connection_cls, | 268 | connection_cls, |
@@ -360,24 +361,39 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh, | |||
360 | { | 361 | { |
361 | GNUNET_break (GNUNET_SYSERR != res); | 362 | GNUNET_break (GNUNET_SYSERR != res); |
362 | // FIXME: leaks! | 363 | // FIXME: leaks! |
364 | TALER_MINT_key_state_release (key_state); | ||
363 | return res; | 365 | return res; |
364 | } | 366 | } |
365 | /* check that this coin's private key was used to sign that | 367 | /* check that this coin's private key was used to sign that |
366 | we should melt it */ | 368 | we should melt it */ |
367 | if (GNUNET_OK != (res = check_confirm_signature (connection, | 369 | if (GNUNET_OK != |
368 | json_array_get (melt_coins, i), | 370 | (res = check_confirm_signature (connection, |
369 | &coin_public_infos[i].coin_pub, | 371 | json_array_get (melt_coins, i), |
370 | &refresh_session_pub))) | 372 | &coin_public_infos[i].coin_pub, |
371 | { | 373 | &refresh_session_pub))) |
372 | GNUNET_break (GNUNET_SYSERR != res); | 374 | { |
373 | // FIXME: leaks! | 375 | GNUNET_break (GNUNET_SYSERR != res); |
374 | return res; | 376 | // FIXME: leaks! |
375 | } | 377 | TALER_MINT_key_state_release (key_state); |
378 | return res; | ||
379 | } | ||
380 | /* check coin denomination is valid */ | ||
381 | dki = TALER_MINT_get_denom_key (key_state, | ||
382 | coin_public_infos[i].denom_pub); | ||
383 | if (NULL == dki) | ||
384 | { | ||
385 | TALER_MINT_key_state_release (key_state); | ||
386 | LOG_WARNING ("Unknown denomination key in /refresh/melt request\n"); | ||
387 | TALER_MINT_key_state_release (key_state); | ||
388 | return TALER_MINT_reply_arg_invalid (connection, | ||
389 | "melt_coins"); | ||
390 | } | ||
376 | /* check mint signature on the coin */ | 391 | /* check mint signature on the coin */ |
377 | if (GNUNET_OK != TALER_MINT_test_coin_valid (key_state, | 392 | if (GNUNET_OK != |
378 | &coin_public_infos[i])) | 393 | TALER_test_coin_valid (&coin_public_infos[i])) |
379 | { | 394 | { |
380 | // FIXME: leaks! | 395 | // FIXME: leaks! |
396 | TALER_MINT_key_state_release (key_state); | ||
381 | return (MHD_YES == | 397 | return (MHD_YES == |
382 | TALER_MINT_reply_json_pack (connection, | 398 | TALER_MINT_reply_json_pack (connection, |
383 | MHD_HTTP_NOT_FOUND, | 399 | MHD_HTTP_NOT_FOUND, |
diff --git a/src/util/crypto.c b/src/util/crypto.c index 4e60d138a..8ce3ade2c 100644 --- a/src/util/crypto.c +++ b/src/util/crypto.c | |||
@@ -267,4 +267,35 @@ TALER_refresh_encrypt (const struct TALER_RefreshLinkDecrypted *input, | |||
267 | } | 267 | } |
268 | 268 | ||
269 | 269 | ||
270 | /** | ||
271 | * Check if a coin is valid; that is, whether the denomination key exists, | ||
272 | * is not expired, and the signature is correct. | ||
273 | * | ||
274 | * @param coin_public_info the coin public info to check for validity | ||
275 | * @return #GNUNET_YES if the coin is valid, | ||
276 | * #GNUNET_NO if it is invalid | ||
277 | * #GNUNET_SYSERROR if an internal error occured | ||
278 | */ | ||
279 | int | ||
280 | TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info) | ||
281 | { | ||
282 | struct GNUNET_HashCode c_hash; | ||
283 | |||
284 | /* FIXME: we had envisioned a more complex scheme... */ | ||
285 | GNUNET_CRYPTO_hash (&coin_public_info->coin_pub, | ||
286 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), | ||
287 | &c_hash); | ||
288 | if (GNUNET_OK != | ||
289 | GNUNET_CRYPTO_rsa_verify (&c_hash, | ||
290 | coin_public_info->denom_sig, | ||
291 | coin_public_info->denom_pub)) | ||
292 | { | ||
293 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
294 | "coin signature is invalid\n"); | ||
295 | return GNUNET_NO; | ||
296 | } | ||
297 | return GNUNET_YES; | ||
298 | } | ||
299 | |||
300 | |||
270 | /* end of crypto.c */ | 301 | /* end of crypto.c */ |