diff options
Diffstat (limited to 'src/mint/taler-mint-httpd_deposit.c')
-rw-r--r-- | src/mint/taler-mint-httpd_deposit.c | 145 |
1 files changed, 83 insertions, 62 deletions
diff --git a/src/mint/taler-mint-httpd_deposit.c b/src/mint/taler-mint-httpd_deposit.c index 4a3713c5b..ed0eca8bb 100644 --- a/src/mint/taler-mint-httpd_deposit.c +++ b/src/mint/taler-mint-httpd_deposit.c | |||
@@ -59,19 +59,26 @@ verify_and_execute_deposit (struct MHD_Connection *connection, | |||
59 | const struct Deposit *deposit) | 59 | const struct Deposit *deposit) |
60 | { | 60 | { |
61 | struct MintKeyState *key_state; | 61 | struct MintKeyState *key_state; |
62 | struct TALER_CoinPublicInfo coin_info; | ||
63 | 62 | ||
64 | memcpy (&coin_info.coin_pub, | 63 | /* FIXME: verify coin signature! */ |
65 | &deposit->coin_pub, | 64 | /* |
66 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | 65 | if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_DEPOSIT, |
67 | coin_info.denom_pub = deposit->denom_pub; | 66 | &deposit->purpose, |
68 | coin_info.denom_sig = deposit->ubsig; | 67 | &deposit->coin_sig, |
68 | &deposit->coin_pub)) | ||
69 | { | ||
70 | resp = json_pack ("{s:s}", "error", "Signature verfication failed"); | ||
71 | return TALER_MINT_reply_arg_invalid (connection, | ||
72 | "csig"); | ||
73 | } | ||
74 | */ | ||
69 | 75 | ||
70 | key_state = TALER_MINT_key_state_acquire (); | 76 | key_state = TALER_MINT_key_state_acquire (); |
71 | if (GNUNET_YES != | 77 | if (GNUNET_YES != |
72 | TALER_MINT_test_coin_valid (key_state, | 78 | TALER_MINT_test_coin_valid (key_state, |
73 | &coin_info)) | 79 | &deposit->coin)) |
74 | { | 80 | { |
81 | LOG_WARNING ("Invalid coin passed for /deposit\n"); | ||
75 | TALER_MINT_key_state_release (key_state); | 82 | TALER_MINT_key_state_release (key_state); |
76 | return TALER_MINT_reply_json_pack (connection, | 83 | return TALER_MINT_reply_json_pack (connection, |
77 | MHD_HTTP_NOT_FOUND, | 84 | MHD_HTTP_NOT_FOUND, |
@@ -80,19 +87,6 @@ verify_and_execute_deposit (struct MHD_Connection *connection, | |||
80 | } | 87 | } |
81 | TALER_MINT_key_state_release (key_state); | 88 | TALER_MINT_key_state_release (key_state); |
82 | 89 | ||
83 | /* FIXME: verify coin signature! */ | ||
84 | /* | ||
85 | if (GNUNET_OK != GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_DEPOSIT, | ||
86 | &deposit->purpose, | ||
87 | &deposit->coin_sig, | ||
88 | &deposit->coin_pub)) | ||
89 | { | ||
90 | resp = json_pack ("{s:s}", "error", "Signature verfication failed"); | ||
91 | resp_code = MHD_HTTP_NOT_FOUND; | ||
92 | goto EXITIF_exit; | ||
93 | } | ||
94 | */ | ||
95 | |||
96 | return TALER_MINT_db_execute_deposit (connection, | 90 | return TALER_MINT_db_execute_deposit (connection, |
97 | deposit); | 91 | deposit); |
98 | } | 92 | } |
@@ -101,12 +95,12 @@ verify_and_execute_deposit (struct MHD_Connection *connection, | |||
101 | /** | 95 | /** |
102 | * Handle a "/deposit" request. This function parses the | 96 | * Handle a "/deposit" request. This function parses the |
103 | * JSON information and then calls #verify_and_execute_deposit() | 97 | * JSON information and then calls #verify_and_execute_deposit() |
104 | * to verify the data and execute the deposit. | 98 | * to verify the signatures and execute the deposit. |
105 | * | 99 | * |
106 | * @param connection the MHD connection to handle | 100 | * @param connection the MHD connection to handle |
107 | * @param root root of the posted JSON | 101 | * @param root root of the posted JSON |
108 | * @param purpose is this a #TALER_SIGNATURE_DEPOSIT or | 102 | * @param purpose is this a #TALER_SIGNATURE_DEPOSIT or |
109 | * #TALER_SIGNATURE_INCREMENTAL_DEPOSIT | 103 | * #TALER_SIGNATURE_INCREMENTAL_DEPOSIT // FIXME: bad type, use enum! |
110 | * @param wire json describing the wire details (?) | 104 | * @param wire json describing the wire details (?) |
111 | * @return MHD result code | 105 | * @return MHD result code |
112 | */ | 106 | */ |
@@ -116,61 +110,88 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection, | |||
116 | uint32_t purpose, | 110 | uint32_t purpose, |
117 | const json_t *wire) | 111 | const json_t *wire) |
118 | { | 112 | { |
119 | struct Deposit *deposit; | 113 | int res; |
114 | struct Deposit deposit; | ||
120 | char *wire_enc; | 115 | char *wire_enc; |
121 | size_t len; | 116 | size_t len; |
122 | int res; | 117 | struct GNUNET_MINT_ParseFieldSpec spec[] = { |
118 | TALER_MINT_PARSE_VARIABLE ("denom_pub"), | ||
119 | TALER_MINT_PARSE_VARIABLE ("ubsig"), | ||
120 | TALER_MINT_PARSE_FIXED ("coin_pub", &deposit.coin.coin_pub), | ||
121 | TALER_MINT_PARSE_FIXED ("merchant_pub", &deposit.merchant_pub), | ||
122 | TALER_MINT_PARSE_FIXED ("H_a", &deposit.h_contract), | ||
123 | TALER_MINT_PARSE_FIXED ("H_wire", &deposit.h_wire), | ||
124 | TALER_MINT_PARSE_FIXED ("csig", &deposit.csig), | ||
125 | TALER_MINT_PARSE_FIXED ("transaction_id", &deposit.transaction_id), | ||
126 | TALER_MINT_PARSE_END | ||
127 | }; | ||
123 | 128 | ||
124 | // FIXME: `struct Deposit` is clearly ill-defined, we should | 129 | memset (&deposit, 0, sizeof (deposit)); |
125 | // not have to do this... | 130 | res = TALER_MINT_parse_json_data (connection, |
131 | root, | ||
132 | spec); | ||
133 | if (GNUNET_SYSERR == res) | ||
134 | return MHD_NO; /* hard failure */ | ||
135 | if (GNUNET_NO == res) | ||
136 | return MHD_YES; /* failure */ | ||
137 | deposit.coin.denom_pub | ||
138 | = GNUNET_CRYPTO_rsa_public_key_decode (spec[0].destination, | ||
139 | spec[0].destination_size_out); | ||
140 | if (NULL == deposit.coin.denom_pub) | ||
141 | { | ||
142 | LOG_WARNING ("Failed to parse denomination key for /deposit request\n"); | ||
143 | TALER_MINT_release_parsed_data (spec); | ||
144 | return TALER_MINT_reply_arg_invalid (connection, | ||
145 | "denom_pub"); | ||
146 | } | ||
147 | deposit.coin.denom_sig | ||
148 | = GNUNET_CRYPTO_rsa_signature_decode (spec[1].destination, | ||
149 | spec[1].destination_size_out); | ||
150 | if (NULL == deposit.coin.denom_sig) | ||
151 | { | ||
152 | LOG_WARNING ("Failed to parse unblinded signature for /deposit request\n"); | ||
153 | GNUNET_CRYPTO_rsa_public_key_free (deposit.coin.denom_pub); | ||
154 | TALER_MINT_release_parsed_data (spec); | ||
155 | return TALER_MINT_reply_arg_invalid (connection, | ||
156 | "denom_pub"); | ||
157 | } | ||
126 | if (NULL == (wire_enc = json_dumps (wire, JSON_COMPACT | JSON_SORT_KEYS))) | 158 | if (NULL == (wire_enc = json_dumps (wire, JSON_COMPACT | JSON_SORT_KEYS))) |
127 | { | 159 | { |
128 | GNUNET_break_op (0); | 160 | GNUNET_CRYPTO_rsa_public_key_free (deposit.coin.denom_pub); |
129 | return TALER_MINT_reply_json_pack (connection, | 161 | GNUNET_CRYPTO_rsa_signature_free (deposit.coin.denom_sig); |
130 | MHD_HTTP_BAD_REQUEST, | 162 | LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n"); |
131 | "{s:s}", | 163 | TALER_MINT_release_parsed_data (spec); |
132 | "error", "Bad format"); | 164 | return TALER_MINT_reply_arg_invalid (connection, |
133 | 165 | "wire"); | |
134 | } | 166 | } |
135 | len = strlen (wire_enc) + 1; | 167 | len = strlen (wire_enc) + 1; |
168 | GNUNET_CRYPTO_hash (wire_enc, | ||
169 | len, | ||
170 | &deposit.h_wire); | ||
136 | GNUNET_free (wire_enc); | 171 | GNUNET_free (wire_enc); |
137 | 172 | ||
138 | deposit = GNUNET_malloc (sizeof (struct Deposit) + len); | 173 | deposit.wire = wire; |
139 | { | 174 | deposit.purpose = purpose; |
140 | struct GNUNET_MINT_ParseFieldSpec spec[] = | 175 | |
141 | { | 176 | // FIXME: deposit.amount not initialized! |
142 | TALER_MINT_PARSE_FIXED ("coin_pub", &deposit->coin_pub), | 177 | |
143 | TALER_MINT_PARSE_FIXED ("denom_pub", &deposit->denom_pub), | 178 | res = verify_and_execute_deposit (connection, |
144 | TALER_MINT_PARSE_FIXED ("ubsig", &deposit->ubsig), | 179 | &deposit); |
145 | TALER_MINT_PARSE_FIXED ("merchant_pub", &deposit->merchant_pub), | 180 | GNUNET_CRYPTO_rsa_public_key_free (deposit.coin.denom_pub); |
146 | TALER_MINT_PARSE_FIXED ("H_a", &deposit->h_contract), | 181 | GNUNET_CRYPTO_rsa_signature_free (deposit.coin.denom_sig); |
147 | TALER_MINT_PARSE_FIXED ("H_wire", &deposit->h_wire), | 182 | TALER_MINT_release_parsed_data (spec); |
148 | TALER_MINT_PARSE_FIXED ("csig", &deposit->coin_sig), | ||
149 | TALER_MINT_PARSE_FIXED ("transaction_id", &deposit->transaction_id), | ||
150 | TALER_MINT_PARSE_END | ||
151 | }; | ||
152 | res = TALER_MINT_parse_json_data (connection, | ||
153 | wire, /* FIXME: wire or root here? */ | ||
154 | spec); | ||
155 | if (GNUNET_SYSERR == res) | ||
156 | return MHD_NO; /* hard failure */ | ||
157 | if (GNUNET_NO == res) | ||
158 | return MHD_YES; /* failure */ | ||
159 | |||
160 | // deposit->purpose = htonl (purpose); // FIXME... | ||
161 | res = verify_and_execute_deposit (connection, | ||
162 | deposit); | ||
163 | TALER_MINT_release_parsed_data (spec); | ||
164 | } | ||
165 | GNUNET_free (deposit); | ||
166 | return res; | 183 | return res; |
167 | } | 184 | } |
168 | 185 | ||
169 | 186 | ||
170 | /** | 187 | /** |
171 | * Handle a "/deposit" request. Parses the JSON in the post and, if | 188 | * Handle a "/deposit" request. Parses the JSON in the post to find |
189 | * the "type" (either DIRECT_DEPOSIT or INCREMENTAL_DEPOSIT), and, if | ||
172 | * successful, passes the JSON data to | 190 | * successful, passes the JSON data to |
173 | * #parse_and_handle_deposit_request(). | 191 | * #parse_and_handle_deposit_request() to further check the details |
192 | * of the operation specified in the "wire" field of the JSON data. | ||
193 | * If everything checks out, this will ultimately lead to the | ||
194 | * "/deposit" being executed, or rejected. | ||
174 | * | 195 | * |
175 | * @param rh context of the handler | 196 | * @param rh context of the handler |
176 | * @param connection the MHD connection to handle | 197 | * @param connection the MHD connection to handle |