aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-01-28 20:23:19 +0100
committerChristian Grothoff <christian@grothoff.org>2015-01-28 20:23:19 +0100
commit62d3d352502f5b1d109b18456a87c704a70fcca5 (patch)
tree020ccf88cf701c29faa59a3f22650946e5d0eb2b
parent2debf6c3f0462a4743484c0cde7c951940e5cd2a (diff)
downloadexchange-62d3d352502f5b1d109b18456a87c704a70fcca5.tar.gz
exchange-62d3d352502f5b1d109b18456a87c704a70fcca5.zip
move coin validity test to libtalerutil
-rw-r--r--src/include/taler_util.h41
-rw-r--r--src/mint/mint.h28
-rw-r--r--src/mint/taler-mint-httpd_deposit.c16
-rw-r--r--src/mint/taler-mint-httpd_keys.c35
-rw-r--r--src/mint/taler-mint-httpd_refresh.c38
-rw-r--r--src/util/crypto.c31
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 */
261struct 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 */
291int
292TALER_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 */
42struct 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 */
85int
86TALER_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 */
279int
280TALER_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 */