diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-01-27 16:18:33 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-01-27 16:18:33 +0100 |
commit | 2cda5ea7ee7e0e87b875ce54b483fdde86ed0dac (patch) | |
tree | dd8bfcc5cb1a8c7b77687de8863b2b330abb9309 | |
parent | 610b7b62c09cb19410dc283f0629e4b24c343b57 (diff) | |
download | exchange-2cda5ea7ee7e0e87b875ce54b483fdde86ed0dac.tar.gz exchange-2cda5ea7ee7e0e87b875ce54b483fdde86ed0dac.zip |
rework taler lib, moving some code to GNUnet, cleaner refresh encrypt/decypt API
-rw-r--r-- | src/include/taler_util.h | 142 | ||||
-rw-r--r-- | src/mint/mint.h | 73 | ||||
-rw-r--r-- | src/util/Makefile.am | 2 | ||||
-rw-r--r-- | src/util/amount.c | 329 | ||||
-rw-r--r-- | src/util/crypto.c | 118 | ||||
-rw-r--r-- | src/util/util.c | 406 |
6 files changed, 600 insertions, 470 deletions
diff --git a/src/include/taler_util.h b/src/include/taler_util.h index d37ac356f..f1264d254 100644 --- a/src/include/taler_util.h +++ b/src/include/taler_util.h | |||
@@ -65,22 +65,50 @@ | |||
65 | do {int rc; rc = cmd; if (!rc) break; LOG_ERROR("A Gcrypt call failed at %s:%d with error: %s\n", __FILE__, __LINE__, gcry_strerror(rc)); abort(); } while (0) | 65 | do {int rc; rc = cmd; if (!rc) break; LOG_ERROR("A Gcrypt call failed at %s:%d with error: %s\n", __FILE__, __LINE__, gcry_strerror(rc)); abort(); } while (0) |
66 | 66 | ||
67 | 67 | ||
68 | |||
69 | /** | ||
70 | * Initialize Gcrypt library. | ||
71 | */ | ||
72 | void | ||
73 | TALER_gcrypt_init (void); | ||
74 | |||
75 | |||
76 | /* *********************** Amount management ****************** */ | ||
77 | |||
78 | |||
79 | /** | ||
80 | * Number of characters (plus 1 for 0-termination) we use to | ||
81 | * represent currency names (i.e. EUR, USD, etc.). | ||
82 | */ | ||
68 | #define TALER_CURRENCY_LEN 4 | 83 | #define TALER_CURRENCY_LEN 4 |
69 | 84 | ||
70 | 85 | ||
71 | GNUNET_NETWORK_STRUCT_BEGIN | 86 | GNUNET_NETWORK_STRUCT_BEGIN |
72 | 87 | ||
88 | /** | ||
89 | * Amount, encoded for network transmission. | ||
90 | */ | ||
73 | struct TALER_AmountNBO | 91 | struct TALER_AmountNBO |
74 | { | 92 | { |
93 | /** | ||
94 | * Value in the main currency, in NBO. | ||
95 | */ | ||
75 | uint32_t value; | 96 | uint32_t value; |
97 | |||
98 | /** | ||
99 | * Additinal fractional value, in NBO. | ||
100 | */ | ||
76 | uint32_t fraction; | 101 | uint32_t fraction; |
102 | |||
103 | /** | ||
104 | * Type of the currency being represented. | ||
105 | */ | ||
77 | char currency[TALER_CURRENCY_LEN]; | 106 | char currency[TALER_CURRENCY_LEN]; |
78 | }; | 107 | }; |
79 | 108 | ||
80 | GNUNET_NETWORK_STRUCT_END | 109 | GNUNET_NETWORK_STRUCT_END |
81 | 110 | ||
82 | 111 | ||
83 | |||
84 | /** | 112 | /** |
85 | * Representation of monetary value in a given currency. | 113 | * Representation of monetary value in a given currency. |
86 | */ | 114 | */ |
@@ -90,10 +118,12 @@ struct TALER_Amount | |||
90 | * Value (numerator of fraction) | 118 | * Value (numerator of fraction) |
91 | */ | 119 | */ |
92 | uint32_t value; | 120 | uint32_t value; |
121 | |||
93 | /** | 122 | /** |
94 | * Fraction (denominator of fraction) | 123 | * Fraction (denominator of fraction) |
95 | */ | 124 | */ |
96 | uint32_t fraction; | 125 | uint32_t fraction; |
126 | |||
97 | /** | 127 | /** |
98 | * Currency string, left adjusted and padded with zeros. | 128 | * Currency string, left adjusted and padded with zeros. |
99 | */ | 129 | */ |
@@ -102,37 +132,38 @@ struct TALER_Amount | |||
102 | 132 | ||
103 | 133 | ||
104 | /** | 134 | /** |
105 | * Initialize Gcrypt library. | ||
106 | */ | ||
107 | void | ||
108 | TALER_gcrypt_init (void); | ||
109 | |||
110 | |||
111 | /** | ||
112 | * Parse denomination description, in the format "T : V : F". | 135 | * Parse denomination description, in the format "T : V : F". |
113 | * | 136 | * |
114 | * @param str denomination description | 137 | * @param str denomination description |
115 | * @param denom denomination to write the result to | 138 | * @param denom denomination to write the result to |
116 | * @return GNUNET_OK if the string is a valid denomination specification, | 139 | * @return #GNUNET_OK if the string is a valid denomination specification, |
117 | * GNUNET_SYSERR if it is invalid. | 140 | * #GNUNET_SYSERR if it is invalid. |
118 | */ | 141 | */ |
119 | int | 142 | int |
120 | TALER_string_to_amount (const char *str, struct TALER_Amount *denom); | 143 | TALER_string_to_amount (const char *str, |
144 | struct TALER_Amount *denom); | ||
121 | 145 | ||
122 | 146 | ||
123 | /** | 147 | /** |
124 | * FIXME | 148 | * Convert amount from host to network representation. |
149 | * | ||
150 | * @param d amount in host representation | ||
151 | * @return amount in network representation | ||
125 | */ | 152 | */ |
126 | struct TALER_AmountNBO | 153 | struct TALER_AmountNBO |
127 | TALER_amount_hton (struct TALER_Amount d); | 154 | TALER_amount_hton (struct TALER_Amount d); |
128 | 155 | ||
129 | 156 | ||
130 | /** | 157 | /** |
131 | * FIXME | 158 | * Convert amount from network to host representation. |
159 | * | ||
160 | * @param d amount in network representation | ||
161 | * @return amount in host representation | ||
132 | */ | 162 | */ |
133 | struct TALER_Amount | 163 | struct TALER_Amount |
134 | TALER_amount_ntoh (struct TALER_AmountNBO dn); | 164 | TALER_amount_ntoh (struct TALER_AmountNBO dn); |
135 | 165 | ||
166 | |||
136 | /** | 167 | /** |
137 | * Compare the value/fraction of two amounts. Does not compare the currency, | 168 | * Compare the value/fraction of two amounts. Does not compare the currency, |
138 | * i.e. comparing amounts with the same value and fraction but different | 169 | * i.e. comparing amounts with the same value and fraction but different |
@@ -143,7 +174,8 @@ TALER_amount_ntoh (struct TALER_AmountNBO dn); | |||
143 | * @return result of the comparison | 174 | * @return result of the comparison |
144 | */ | 175 | */ |
145 | int | 176 | int |
146 | TALER_amount_cmp (struct TALER_Amount a1, struct TALER_Amount a2); | 177 | TALER_amount_cmp (struct TALER_Amount a1, |
178 | struct TALER_Amount a2); | ||
147 | 179 | ||
148 | 180 | ||
149 | /** | 181 | /** |
@@ -154,7 +186,8 @@ TALER_amount_cmp (struct TALER_Amount a1, struct TALER_Amount a2); | |||
154 | * @return (a1-a2) or 0 if a2>=a1 | 186 | * @return (a1-a2) or 0 if a2>=a1 |
155 | */ | 187 | */ |
156 | struct TALER_Amount | 188 | struct TALER_Amount |
157 | TALER_amount_subtract (struct TALER_Amount a1, struct TALER_Amount a2); | 189 | TALER_amount_subtract (struct TALER_Amount a1, |
190 | struct TALER_Amount a2); | ||
158 | 191 | ||
159 | 192 | ||
160 | /** | 193 | /** |
@@ -165,7 +198,8 @@ TALER_amount_subtract (struct TALER_Amount a1, struct TALER_Amount a2); | |||
165 | * @return sum of a1 and a2 | 198 | * @return sum of a1 and a2 |
166 | */ | 199 | */ |
167 | struct TALER_Amount | 200 | struct TALER_Amount |
168 | TALER_amount_add (struct TALER_Amount a1, struct TALER_Amount a2); | 201 | TALER_amount_add (struct TALER_Amount a1, |
202 | struct TALER_Amount a2); | ||
169 | 203 | ||
170 | 204 | ||
171 | /** | 205 | /** |
@@ -187,43 +221,89 @@ TALER_amount_normalize (struct TALER_Amount amount); | |||
187 | char * | 221 | char * |
188 | TALER_amount_to_string (struct TALER_Amount amount); | 222 | TALER_amount_to_string (struct TALER_Amount amount); |
189 | 223 | ||
224 | /* ****************** FIXME: move to GNUnet? ************** */ | ||
190 | 225 | ||
191 | /** | 226 | /** |
192 | * Return the base32crockford encoding of the given buffer. | 227 | * Return the base32crockford encoding of the given buffer. |
193 | * | 228 | * |
194 | * The returned string will be freshly allocated, and must be free'd | 229 | * The returned string will be freshly allocated, and must be free'd |
195 | * with GNUNET_free. | 230 | * with #GNUNET_free(). |
196 | * | 231 | * |
197 | * @param buffer with data | 232 | * @param buffer with data |
198 | * @param size size of the buffer | 233 | * @param size size of the buffer |
199 | * @return freshly allocated, null-terminated string | 234 | * @return freshly allocated, null-terminated string |
200 | */ | 235 | */ |
201 | char * | 236 | char * |
202 | TALER_data_to_string_alloc (const void *buf, size_t size); | 237 | TALER_data_to_string_alloc (const void *buf, |
238 | size_t size); | ||
239 | |||
203 | 240 | ||
241 | /* ****************** Refresh crypto primitives ************* */ | ||
204 | 242 | ||
205 | /** | 243 | /** |
206 | * Get encoded binary data from a configuration. | 244 | * Representation of an encrypted refresh link. |
207 | * | ||
208 | * @return GNUNET_OK on success | ||
209 | * GNUNET_NO is the value does not exist | ||
210 | * GNUNET_SYSERR on encoding error | ||
211 | */ | 245 | */ |
212 | int | 246 | struct TALER_RefreshLinkEncrypted |
213 | TALER_configuration_get_data (const struct GNUNET_CONFIGURATION_Handle *cfg, | 247 | { |
214 | const char *section, const char *option, | ||
215 | void *buf, size_t buf_size); | ||
216 | 248 | ||
249 | /** | ||
250 | * Encrypted private key of the coin. | ||
251 | */ | ||
252 | char [sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)] coin_priv_enc; | ||
217 | 253 | ||
254 | /** | ||
255 | * Encrypted blinding key with @e blinding_key_enc_size bytes. | ||
256 | */ | ||
257 | char *blinding_key_enc; | ||
218 | 258 | ||
259 | /** | ||
260 | * Number of bytes in @e blinding_key_enc. | ||
261 | */ | ||
262 | size_t blinding_key_enc_size; | ||
263 | }; | ||
219 | 264 | ||
220 | int | ||
221 | TALER_refresh_decrypt (const void *input, size_t input_size, const struct GNUNET_HashCode *secret, void *result); | ||
222 | 265 | ||
223 | int | 266 | /** |
224 | TALER_refresh_encrypt (const void *input, size_t input_size, const struct GNUNET_HashCode *secret, void *result); | 267 | * Representation of an refresh link in cleartext. |
268 | */ | ||
269 | struct TALER_RefreshLinkDecrypted | ||
270 | { | ||
271 | |||
272 | /** | ||
273 | * Private key of the coin. | ||
274 | */ | ||
275 | struct GNUNET_CRYPTO_EcdsaPrivateKey coin_priv; | ||
276 | |||
277 | /** | ||
278 | * Blinding key with @e blinding_key_enc_size bytes. | ||
279 | */ | ||
280 | struct GNUNET_CRYPTO_rsa_BlindingKey *blinding_key; | ||
281 | |||
282 | }; | ||
225 | 283 | ||
226 | 284 | ||
285 | /** | ||
286 | * Decrypt refresh link information. | ||
287 | * | ||
288 | * @param input encrypted refresh link data | ||
289 | * @param secret shared secret to use for decryption | ||
290 | * @return NULL on error | ||
291 | */ | ||
292 | struct TALER_RefreshLinkDecrypted * | ||
293 | TALER_refresh_decrypt (const struct TALER_RefreshLinkEncrypted *input, | ||
294 | const struct GNUNET_HashCode *secret); | ||
295 | |||
296 | |||
297 | /** | ||
298 | * Encrypt refresh link information. | ||
299 | * | ||
300 | * @param input plaintext refresh link data | ||
301 | * @param secret shared secret to use for encryption | ||
302 | * @return NULL on error (should never happen) | ||
303 | */ | ||
304 | struct TALER_RefreshLinkEncrypted * | ||
305 | TALER_refresh_encrypt (const struct TALER_RefreshLinkDecrypted *input, | ||
306 | const struct GNUNET_HashCode *secret); | ||
227 | 307 | ||
228 | 308 | ||
229 | #endif | 309 | #endif |
diff --git a/src/mint/mint.h b/src/mint/mint.h index 3f98b368d..b194be687 100644 --- a/src/mint/mint.h +++ b/src/mint/mint.h | |||
@@ -117,9 +117,9 @@ struct CollectableBlindcoin | |||
117 | 117 | ||
118 | struct RefreshSession | 118 | struct RefreshSession |
119 | { | 119 | { |
120 | int has_commit_sig; | ||
121 | struct GNUNET_CRYPTO_EddsaSignature commit_sig; | 120 | struct GNUNET_CRYPTO_EddsaSignature commit_sig; |
122 | struct GNUNET_CRYPTO_EddsaPublicKey session_pub; | 121 | struct GNUNET_CRYPTO_EddsaPublicKey session_pub; |
122 | int has_commit_sig; | ||
123 | uint16_t num_oldcoins; | 123 | uint16_t num_oldcoins; |
124 | uint16_t num_newcoins; | 124 | uint16_t num_newcoins; |
125 | uint16_t kappa; | 125 | uint16_t kappa; |
@@ -128,46 +128,33 @@ struct RefreshSession | |||
128 | }; | 128 | }; |
129 | 129 | ||
130 | 130 | ||
131 | #define TALER_REFRESH_SHARED_SECRET_LENGTH (sizeof (struct GNUNET_HashCode)) | 131 | /** |
132 | #define TALER_REFRESH_LINK_LENGTH (sizeof (struct LinkData)) | 132 | * FIXME |
133 | 133 | */ | |
134 | struct RefreshCommitLink | 134 | struct RefreshCommitLink |
135 | { | 135 | { |
136 | struct GNUNET_CRYPTO_EddsaPublicKey session_pub; | 136 | struct GNUNET_CRYPTO_EddsaPublicKey session_pub; |
137 | struct GNUNET_CRYPTO_EcdsaPublicKey transfer_pub; | 137 | struct GNUNET_CRYPTO_EcdsaPublicKey transfer_pub; |
138 | struct GNUNET_HashCode shared_secret; | ||
138 | uint16_t cnc_index; | 139 | uint16_t cnc_index; |
139 | uint16_t oldcoin_index; | 140 | uint16_t oldcoin_index; |
140 | char shared_secret_enc[sizeof (struct GNUNET_HashCode)]; | ||
141 | }; | ||
142 | |||
143 | struct LinkData | ||
144 | { | ||
145 | struct GNUNET_CRYPTO_EcdsaPrivateKey coin_priv; | ||
146 | struct GNUNET_CRYPTO_rsa_BlindingKey *bkey_enc; | ||
147 | }; | 141 | }; |
148 | 142 | ||
149 | 143 | ||
150 | GNUNET_NETWORK_STRUCT_BEGIN | 144 | /** |
151 | 145 | * FIXME | |
152 | struct SharedSecretEnc | 146 | */ |
153 | { | ||
154 | char data[TALER_REFRESH_SHARED_SECRET_LENGTH]; | ||
155 | }; | ||
156 | |||
157 | |||
158 | struct LinkDataEnc | ||
159 | { | ||
160 | char data[sizeof (struct LinkData)]; | ||
161 | }; | ||
162 | |||
163 | GNUNET_NETWORK_STRUCT_END | ||
164 | |||
165 | struct RefreshCommitCoin | 147 | struct RefreshCommitCoin |
166 | { | 148 | { |
149 | /** | ||
150 | * Refresh session's public key. | ||
151 | */ | ||
167 | struct GNUNET_CRYPTO_EddsaPublicKey session_pub; | 152 | struct GNUNET_CRYPTO_EddsaPublicKey session_pub; |
168 | 153 | ||
154 | struct TALER_RefreshLinkEncrypted refresh_link; | ||
155 | |||
169 | /** | 156 | /** |
170 | * Blinded message to be signed (in envelope). | 157 | * Blinded message to be signed (in envelope), with @e coin_env_size bytes. |
171 | */ | 158 | */ |
172 | char *coin_ev; | 159 | char *coin_ev; |
173 | 160 | ||
@@ -176,22 +163,36 @@ struct RefreshCommitCoin | |||
176 | */ | 163 | */ |
177 | size_t coin_ev_size; | 164 | size_t coin_ev_size; |
178 | 165 | ||
166 | /** | ||
167 | * FIXME: needed? | ||
168 | */ | ||
179 | uint16_t cnc_index; | 169 | uint16_t cnc_index; |
170 | |||
171 | /** | ||
172 | * FIXME: needed? | ||
173 | */ | ||
180 | uint16_t newcoin_index; | 174 | uint16_t newcoin_index; |
181 | char link_enc[sizeof (struct LinkData)]; | 175 | |
182 | }; | 176 | }; |
183 | 177 | ||
184 | 178 | ||
179 | /** | ||
180 | * FIXME | ||
181 | */ | ||
185 | struct KnownCoin | 182 | struct KnownCoin |
186 | { | 183 | { |
187 | struct TALER_CoinPublicInfo public_info; | 184 | struct TALER_CoinPublicInfo public_info; |
188 | struct TALER_Amount expended_balance; | 185 | |
189 | int is_refreshed; | ||
190 | /** | 186 | /** |
191 | * Refreshing session, only valid if | 187 | * Refreshing session, only valid if |
192 | * is_refreshed==1. | 188 | * is_refreshed==1. |
193 | */ | 189 | */ |
194 | struct GNUNET_CRYPTO_EddsaPublicKey refresh_session_pub; | 190 | struct GNUNET_CRYPTO_EddsaPublicKey refresh_session_pub; |
191 | |||
192 | struct TALER_Amount expended_balance; | ||
193 | |||
194 | int is_refreshed; | ||
195 | |||
195 | }; | 196 | }; |
196 | 197 | ||
197 | 198 | ||
@@ -356,11 +357,15 @@ TALER_MINT_config_load (const char *mint_base_dir); | |||
356 | 357 | ||
357 | 358 | ||
358 | int | 359 | int |
359 | TALER_TALER_DB_extract_amount (PGresult *result, unsigned int row, | 360 | TALER_TALER_DB_extract_amount (PGresult *result, |
360 | int indices[3], struct TALER_Amount *denom); | 361 | unsigned int row, |
362 | int indices[3], | ||
363 | struct TALER_Amount *denom); | ||
361 | 364 | ||
362 | int | 365 | int |
363 | TALER_TALER_DB_extract_amount_nbo (PGresult *result, unsigned int row, | 366 | TALER_TALER_DB_extract_amount_nbo (PGresult *result, |
364 | int indices[3], struct TALER_AmountNBO *denom_nbo); | 367 | unsigned int row, |
368 | int indices[3], | ||
369 | struct TALER_AmountNBO *denom_nbo); | ||
365 | 370 | ||
366 | #endif /* _MINT_H */ | 371 | #endif /* _MINT_H */ |
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 2fbcb54b4..bb07e2ca3 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am | |||
@@ -4,6 +4,8 @@ lib_LTLIBRARIES = \ | |||
4 | libtalerutil.la | 4 | libtalerutil.la |
5 | 5 | ||
6 | libtalerutil_la_SOURCES = \ | 6 | libtalerutil_la_SOURCES = \ |
7 | amount.c \ | ||
8 | crypto.c \ | ||
7 | util.c \ | 9 | util.c \ |
8 | json.c \ | 10 | json.c \ |
9 | db.c | 11 | db.c |
diff --git a/src/util/amount.c b/src/util/amount.c new file mode 100644 index 000000000..8bd899bf5 --- /dev/null +++ b/src/util/amount.c | |||
@@ -0,0 +1,329 @@ | |||
1 | /* | ||
2 | This file is part of TALER | ||
3 | (C) 2014 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | TALER is free software; you can redistribute it and/or modify it under the | ||
6 | terms of the GNU General Public License as published by the Free Software | ||
7 | Foundation; either version 3, or (at your option) any later version. | ||
8 | |||
9 | TALER is distributed in the hope that it will be useful, but WITHOUT ANY | ||
10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
11 | A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
12 | |||
13 | You should have received a copy of the GNU General Public License along with | ||
14 | TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file amount.c | ||
19 | * @brief Common utility functions to deal with units of currency | ||
20 | * @author Sree Harsha Totakura <sreeharsha@totakura.in> | ||
21 | * @author Florian Dold | ||
22 | * @author Benedikt Mueller | ||
23 | */ | ||
24 | #include "platform.h" | ||
25 | #include "taler_util.h" | ||
26 | #include <gnunet/gnunet_common.h> | ||
27 | #include <gnunet/gnunet_util_lib.h> | ||
28 | #include <gcrypt.h> | ||
29 | |||
30 | #define AMOUNT_FRAC_BASE 1000000 | ||
31 | |||
32 | #define AMOUNT_FRAC_LEN 6 | ||
33 | |||
34 | |||
35 | /** | ||
36 | * Parse money amount description, in the format "A:B.C". | ||
37 | * | ||
38 | * @param str amount description | ||
39 | * @param denom amount to write the result to | ||
40 | * @return #GNUNET_OK if the string is a valid amount specification, | ||
41 | * #GNUNET_SYSERR if it is invalid. | ||
42 | */ | ||
43 | int | ||
44 | TALER_string_to_amount (const char *str, | ||
45 | struct TALER_Amount *denom) | ||
46 | { | ||
47 | unsigned int i; // pos in str | ||
48 | int n; // number tmp | ||
49 | unsigned int c; // currency pos | ||
50 | uint32_t b; // base for suffix | ||
51 | |||
52 | memset (denom, 0, sizeof (struct TALER_Amount)); | ||
53 | |||
54 | i = n = c = 0; | ||
55 | |||
56 | while (isspace(str[i])) | ||
57 | i++; | ||
58 | |||
59 | if (0 == str[i]) | ||
60 | { | ||
61 | printf("null before currency\n"); | ||
62 | return GNUNET_SYSERR; | ||
63 | } | ||
64 | |||
65 | while (str[i] != ':') | ||
66 | { | ||
67 | if (0 == str[i]) | ||
68 | { | ||
69 | printf("null before colon"); | ||
70 | return GNUNET_SYSERR; | ||
71 | } | ||
72 | if (c > 3) | ||
73 | { | ||
74 | printf("currency too long\n"); | ||
75 | return GNUNET_SYSERR; | ||
76 | } | ||
77 | denom->currency[c] = str[i]; | ||
78 | c++; | ||
79 | i++; | ||
80 | } | ||
81 | |||
82 | // skip colon | ||
83 | i++; | ||
84 | |||
85 | if (0 == str[i]) | ||
86 | { | ||
87 | printf("null before value\n"); | ||
88 | return GNUNET_SYSERR; | ||
89 | } | ||
90 | |||
91 | while (str[i] != '.') | ||
92 | { | ||
93 | if (0 == str[i]) | ||
94 | { | ||
95 | return GNUNET_OK; | ||
96 | } | ||
97 | n = str[i] - '0'; | ||
98 | if (n < 0 || n > 9) | ||
99 | { | ||
100 | printf("invalid character '%c' before comma at %u\n", (char) n, i); | ||
101 | return GNUNET_SYSERR; | ||
102 | } | ||
103 | denom->value = (denom->value * 10) + n; | ||
104 | i++; | ||
105 | } | ||
106 | |||
107 | // skip the dot | ||
108 | i++; | ||
109 | |||
110 | if (0 == str[i]) | ||
111 | { | ||
112 | printf("null after dot"); | ||
113 | return GNUNET_SYSERR; | ||
114 | } | ||
115 | |||
116 | b = 100000; | ||
117 | |||
118 | while (0 != str[i]) | ||
119 | { | ||
120 | n = str[i] - '0'; | ||
121 | if (b == 0 || n < 0 || n > 9) | ||
122 | { | ||
123 | printf("error after comma"); | ||
124 | return GNUNET_SYSERR; | ||
125 | } | ||
126 | denom->fraction += n * b; | ||
127 | b /= 10; | ||
128 | i++; | ||
129 | } | ||
130 | |||
131 | return GNUNET_OK; | ||
132 | } | ||
133 | |||
134 | |||
135 | /** | ||
136 | * FIXME | ||
137 | */ | ||
138 | struct TALER_AmountNBO | ||
139 | TALER_amount_hton (struct TALER_Amount d) | ||
140 | { | ||
141 | struct TALER_AmountNBO dn; | ||
142 | dn.value = htonl (d.value); | ||
143 | dn.fraction = htonl (d.fraction); | ||
144 | memcpy (dn.currency, d.currency, TALER_CURRENCY_LEN); | ||
145 | |||
146 | return dn; | ||
147 | } | ||
148 | |||
149 | |||
150 | /** | ||
151 | * FIXME | ||
152 | */ | ||
153 | struct TALER_Amount | ||
154 | TALER_amount_ntoh (struct TALER_AmountNBO dn) | ||
155 | { | ||
156 | struct TALER_Amount d; | ||
157 | d.value = ntohl (dn.value); | ||
158 | d.fraction = ntohl (dn.fraction); | ||
159 | memcpy (d.currency, dn.currency, sizeof(dn.currency)); | ||
160 | |||
161 | return d; | ||
162 | } | ||
163 | |||
164 | |||
165 | /** | ||
166 | * Compare the value/fraction of two amounts. Does not compare the currency, | ||
167 | * i.e. comparing amounts with the same value and fraction but different | ||
168 | * currency would return 0. | ||
169 | * | ||
170 | * @param a1 first amount | ||
171 | * @param a2 second amount | ||
172 | * @return result of the comparison | ||
173 | */ | ||
174 | int | ||
175 | TALER_amount_cmp (struct TALER_Amount a1, struct TALER_Amount a2) | ||
176 | { | ||
177 | a1 = TALER_amount_normalize (a1); | ||
178 | a2 = TALER_amount_normalize (a2); | ||
179 | if (a1.value == a2.value) | ||
180 | { | ||
181 | if (a1.fraction < a2.fraction) | ||
182 | return -1; | ||
183 | if (a1.fraction > a2.fraction) | ||
184 | return 1; | ||
185 | return 0; | ||
186 | } | ||
187 | if (a1.value < a2.value) | ||
188 | return -1; | ||
189 | return 1; | ||
190 | } | ||
191 | |||
192 | |||
193 | /** | ||
194 | * Perform saturating subtraction of amounts. | ||
195 | * | ||
196 | * @param a1 amount to subtract from | ||
197 | * @param a2 amount to subtract | ||
198 | * @return (a1-a2) or 0 if a2>=a1 | ||
199 | */ | ||
200 | struct TALER_Amount | ||
201 | TALER_amount_subtract (struct TALER_Amount a1, struct TALER_Amount a2) | ||
202 | { | ||
203 | a1 = TALER_amount_normalize (a1); | ||
204 | a2 = TALER_amount_normalize (a2); | ||
205 | |||
206 | if (a1.value < a2.value) | ||
207 | { | ||
208 | a1.value = 0; | ||
209 | a1.fraction = 0; | ||
210 | return a1; | ||
211 | } | ||
212 | |||
213 | if (a1.fraction < a2.fraction) | ||
214 | { | ||
215 | if (0 == a1.value) | ||
216 | { | ||
217 | a1.fraction = 0; | ||
218 | return a1; | ||
219 | } | ||
220 | a1.fraction += AMOUNT_FRAC_BASE; | ||
221 | a1.value -= 1; | ||
222 | } | ||
223 | |||
224 | a1.fraction -= a2.fraction; | ||
225 | a1.value -= a2.value; | ||
226 | |||
227 | return a1; | ||
228 | } | ||
229 | |||
230 | |||
231 | /** | ||
232 | * Perform saturating addition of amounts. | ||
233 | * | ||
234 | * @param a1 first amount to add | ||
235 | * @param a2 second amount to add | ||
236 | * @return sum of a1 and a2 | ||
237 | */ | ||
238 | struct TALER_Amount | ||
239 | TALER_amount_add (struct TALER_Amount a1, struct TALER_Amount a2) | ||
240 | { | ||
241 | a1 = TALER_amount_normalize (a1); | ||
242 | a2 = TALER_amount_normalize (a2); | ||
243 | |||
244 | a1.value += a2.value; | ||
245 | a1.fraction += a2.fraction; | ||
246 | |||
247 | if (0 == a1.currency[0]) | ||
248 | { | ||
249 | memcpy (a2.currency, a1.currency, TALER_CURRENCY_LEN); | ||
250 | } | ||
251 | |||
252 | if (0 == a2.currency[0]) | ||
253 | { | ||
254 | memcpy (a1.currency, a2.currency, TALER_CURRENCY_LEN); | ||
255 | } | ||
256 | |||
257 | if (0 != a1.currency[0] && 0 != memcmp (a1.currency, a2.currency, TALER_CURRENCY_LEN)) | ||
258 | { | ||
259 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "adding mismatching currencies\n"); | ||
260 | } | ||
261 | |||
262 | if (a1.value < a2.value) | ||
263 | { | ||
264 | a1.value = UINT32_MAX; | ||
265 | a2.value = UINT32_MAX; | ||
266 | return a1; | ||
267 | } | ||
268 | |||
269 | return TALER_amount_normalize (a1); | ||
270 | } | ||
271 | |||
272 | |||
273 | /** | ||
274 | * Normalize the given amount. | ||
275 | * | ||
276 | * @param amout amount to normalize | ||
277 | * @return normalized amount | ||
278 | */ | ||
279 | struct TALER_Amount | ||
280 | TALER_amount_normalize (struct TALER_Amount amount) | ||
281 | { | ||
282 | while (amount.value != UINT32_MAX && amount.fraction >= AMOUNT_FRAC_BASE) | ||
283 | { | ||
284 | amount.fraction -= AMOUNT_FRAC_BASE; | ||
285 | amount.value += 1; | ||
286 | } | ||
287 | return amount; | ||
288 | } | ||
289 | |||
290 | |||
291 | /** | ||
292 | * Convert amount to string. | ||
293 | * | ||
294 | * @param amount amount to convert to string | ||
295 | * @return freshly allocated string representation | ||
296 | */ | ||
297 | char * | ||
298 | TALER_amount_to_string (struct TALER_Amount amount) | ||
299 | { | ||
300 | char tail[AMOUNT_FRAC_LEN + 1] = { 0 }; | ||
301 | char curr[TALER_CURRENCY_LEN + 1] = { 0 }; | ||
302 | char *result = NULL; | ||
303 | int len; | ||
304 | |||
305 | memcpy (curr, amount.currency, TALER_CURRENCY_LEN); | ||
306 | |||
307 | amount = TALER_amount_normalize (amount); | ||
308 | if (0 != amount.fraction) | ||
309 | { | ||
310 | unsigned int i; | ||
311 | uint32_t n = amount.fraction; | ||
312 | for (i = 0; (i < AMOUNT_FRAC_LEN) && (n != 0); i++) | ||
313 | { | ||
314 | tail[i] = '0' + (n / (AMOUNT_FRAC_BASE / 10)); | ||
315 | n = (n * 10) % (AMOUNT_FRAC_BASE); | ||
316 | } | ||
317 | tail[i] = 0; | ||
318 | len = GNUNET_asprintf (&result, "%s:%lu.%s", curr, (unsigned long) amount.value, tail); | ||
319 | } | ||
320 | else | ||
321 | { | ||
322 | len = GNUNET_asprintf (&result, "%s:%lu", curr, (unsigned long) amount.value); | ||
323 | } | ||
324 | GNUNET_assert (len > 0); | ||
325 | return result; | ||
326 | } | ||
327 | |||
328 | |||
329 | /* end of amount.c */ | ||
diff --git a/src/util/crypto.c b/src/util/crypto.c new file mode 100644 index 000000000..7ff741159 --- /dev/null +++ b/src/util/crypto.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | This file is part of TALER | ||
3 | (C) 2014 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | TALER is free software; you can redistribute it and/or modify it under the | ||
6 | terms of the GNU General Public License as published by the Free Software | ||
7 | Foundation; either version 3, or (at your option) any later version. | ||
8 | |||
9 | TALER is distributed in the hope that it will be useful, but WITHOUT ANY | ||
10 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
11 | A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
12 | |||
13 | You should have received a copy of the GNU General Public License along with | ||
14 | TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file crypto.c | ||
19 | * @brief Cryptographic utility functions | ||
20 | * @author Sree Harsha Totakura <sreeharsha@totakura.in> | ||
21 | * @author Florian Dold | ||
22 | * @author Benedikt Mueller | ||
23 | */ | ||
24 | |||
25 | #include "platform.h" | ||
26 | #include "taler_util.h" | ||
27 | #include <gnunet/gnunet_common.h> | ||
28 | #include <gnunet/gnunet_util_lib.h> | ||
29 | #include <gcrypt.h> | ||
30 | |||
31 | #define CURVE "Ed25519" | ||
32 | |||
33 | |||
34 | static void | ||
35 | fatal_error_handler (void *cls, int wtf, const char *msg) | ||
36 | { | ||
37 | LOG_ERROR("Fatal error in Gcrypt: %s\n", msg); | ||
38 | abort(); | ||
39 | } | ||
40 | |||
41 | |||
42 | /** | ||
43 | * Initialize Gcrypt library. | ||
44 | */ | ||
45 | void | ||
46 | TALER_gcrypt_init() | ||
47 | { | ||
48 | gcry_set_fatalerror_handler (&fatal_error_handler, NULL); | ||
49 | TALER_assert_as(gcry_check_version(NEED_LIBGCRYPT_VERSION), | ||
50 | "libgcrypt version mismatch"); | ||
51 | /* Disable secure memory. */ | ||
52 | gcry_control (GCRYCTL_DISABLE_SECMEM, 0); | ||
53 | gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); | ||
54 | } | ||
55 | |||
56 | |||
57 | /** | ||
58 | * Derive symmetric key material for refresh operations from | ||
59 | * a given shared secret. | ||
60 | * | ||
61 | * @param secret the shared secret | ||
62 | * @param[out] iv set to initialization vector | ||
63 | * @param[out] skey set to session key | ||
64 | */ | ||
65 | static void | ||
66 | derive_refresh_key (const struct GNUNET_HashCode *secret, | ||
67 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | ||
68 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey) | ||
69 | { | ||
70 | static const char ctx_key[] = "taler-key-skey"; | ||
71 | static const char ctx_iv[] = "taler-key-iv"; | ||
72 | |||
73 | GNUNET_assert (GNUNET_YES == | ||
74 | GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), | ||
75 | ctx_key, strlen (ctx_key), | ||
76 | secret, sizeof (struct GNUNET_HashCode), | ||
77 | NULL, 0)); | ||
78 | GNUNET_assert (GNUNET_YES == | ||
79 | GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector), | ||
80 | ctx_iv, strlen (ctx_iv), | ||
81 | secret, sizeof (struct GNUNET_HashCode), | ||
82 | NULL, 0)); | ||
83 | } | ||
84 | |||
85 | |||
86 | int | ||
87 | TALER_refresh_decrypt (const void *input, | ||
88 | size_t input_size, | ||
89 | const struct GNUNET_HashCode *secret, | ||
90 | void *result) | ||
91 | { | ||
92 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
93 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | ||
94 | |||
95 | derive_refresh_key (secret, &iv, &skey); | ||
96 | |||
97 | return GNUNET_CRYPTO_symmetric_decrypt (input, input_size, &skey, &iv, result); | ||
98 | } | ||
99 | |||
100 | |||
101 | int | ||
102 | TALER_refresh_encrypt (const void *input, | ||
103 | size_t input_size, | ||
104 | const struct GNUNET_HashCode *secret, | ||
105 | void *result) | ||
106 | { | ||
107 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
108 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | ||
109 | |||
110 | derive_refresh_key (secret, &iv, &skey); | ||
111 | |||
112 | return GNUNET_CRYPTO_symmetric_encrypt (input, input_size, &skey, &iv, result); | ||
113 | } | ||
114 | |||
115 | |||
116 | |||
117 | |||
118 | /* end of crypto.c */ | ||
diff --git a/src/util/util.c b/src/util/util.c index 80f8fc5f0..440b49fab 100644 --- a/src/util/util.c +++ b/src/util/util.c | |||
@@ -28,335 +28,11 @@ | |||
28 | #include <gnunet/gnunet_util_lib.h> | 28 | #include <gnunet/gnunet_util_lib.h> |
29 | #include <gcrypt.h> | 29 | #include <gcrypt.h> |
30 | 30 | ||
31 | #define CURVE "Ed25519" | ||
32 | |||
33 | #define AMOUNT_FRAC_BASE 1000000 | ||
34 | #define AMOUNT_FRAC_LEN 6 | ||
35 | |||
36 | |||
37 | |||
38 | static void | ||
39 | fatal_error_handler (void *cls, int wtf, const char *msg) | ||
40 | { | ||
41 | LOG_ERROR("Fatal error in Gcrypt: %s\n", msg); | ||
42 | abort(); | ||
43 | } | ||
44 | |||
45 | |||
46 | /** | ||
47 | * Initialize Gcrypt library. | ||
48 | */ | ||
49 | void | ||
50 | TALER_gcrypt_init() | ||
51 | { | ||
52 | gcry_set_fatalerror_handler (&fatal_error_handler, NULL); | ||
53 | TALER_assert_as(gcry_check_version(NEED_LIBGCRYPT_VERSION), | ||
54 | "libgcrypt version mismatch"); | ||
55 | /* Disable secure memory. */ | ||
56 | gcry_control (GCRYCTL_DISABLE_SECMEM, 0); | ||
57 | gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); | ||
58 | } | ||
59 | |||
60 | |||
61 | /** | ||
62 | * Parse money amount description, in the format "A:B.C". | ||
63 | * | ||
64 | * @param str amount description | ||
65 | * @param denom amount to write the result to | ||
66 | * @return GNUNET_OK if the string is a valid amount specification, | ||
67 | * GNUNET_SYSERR if it is invalid. | ||
68 | */ | ||
69 | int | ||
70 | TALER_string_to_amount (const char *str, struct TALER_Amount *denom) | ||
71 | { | ||
72 | unsigned int i; // pos in str | ||
73 | int n; // number tmp | ||
74 | unsigned int c; // currency pos | ||
75 | uint32_t b; // base for suffix | ||
76 | |||
77 | memset (denom, 0, sizeof (struct TALER_Amount)); | ||
78 | |||
79 | i = n = c = 0; | ||
80 | |||
81 | while (isspace(str[i])) | ||
82 | i++; | ||
83 | |||
84 | if (0 == str[i]) | ||
85 | { | ||
86 | printf("null before currency\n"); | ||
87 | return GNUNET_SYSERR; | ||
88 | } | ||
89 | |||
90 | while (str[i] != ':') | ||
91 | { | ||
92 | if (0 == str[i]) | ||
93 | { | ||
94 | printf("null before colon"); | ||
95 | return GNUNET_SYSERR; | ||
96 | } | ||
97 | if (c > 3) | ||
98 | { | ||
99 | printf("currency too long\n"); | ||
100 | return GNUNET_SYSERR; | ||
101 | } | ||
102 | denom->currency[c] = str[i]; | ||
103 | c++; | ||
104 | i++; | ||
105 | } | ||
106 | |||
107 | // skip colon | ||
108 | i++; | ||
109 | |||
110 | if (0 == str[i]) | ||
111 | { | ||
112 | printf("null before value\n"); | ||
113 | return GNUNET_SYSERR; | ||
114 | } | ||
115 | |||
116 | while (str[i] != '.') | ||
117 | { | ||
118 | if (0 == str[i]) | ||
119 | { | ||
120 | return GNUNET_OK; | ||
121 | } | ||
122 | n = str[i] - '0'; | ||
123 | if (n < 0 || n > 9) | ||
124 | { | ||
125 | printf("invalid character '%c' before comma at %u\n", (char) n, i); | ||
126 | return GNUNET_SYSERR; | ||
127 | } | ||
128 | denom->value = (denom->value * 10) + n; | ||
129 | i++; | ||
130 | } | ||
131 | |||
132 | // skip the dot | ||
133 | i++; | ||
134 | |||
135 | if (0 == str[i]) | ||
136 | { | ||
137 | printf("null after dot"); | ||
138 | return GNUNET_SYSERR; | ||
139 | } | ||
140 | |||
141 | b = 100000; | ||
142 | |||
143 | while (0 != str[i]) | ||
144 | { | ||
145 | n = str[i] - '0'; | ||
146 | if (b == 0 || n < 0 || n > 9) | ||
147 | { | ||
148 | printf("error after comma"); | ||
149 | return GNUNET_SYSERR; | ||
150 | } | ||
151 | denom->fraction += n * b; | ||
152 | b /= 10; | ||
153 | i++; | ||
154 | } | ||
155 | |||
156 | return GNUNET_OK; | ||
157 | } | ||
158 | |||
159 | |||
160 | /** | ||
161 | * FIXME | ||
162 | */ | ||
163 | struct TALER_AmountNBO | ||
164 | TALER_amount_hton (struct TALER_Amount d) | ||
165 | { | ||
166 | struct TALER_AmountNBO dn; | ||
167 | dn.value = htonl (d.value); | ||
168 | dn.fraction = htonl (d.fraction); | ||
169 | memcpy (dn.currency, d.currency, TALER_CURRENCY_LEN); | ||
170 | |||
171 | return dn; | ||
172 | } | ||
173 | |||
174 | |||
175 | /** | ||
176 | * FIXME | ||
177 | */ | ||
178 | struct TALER_Amount | ||
179 | TALER_amount_ntoh (struct TALER_AmountNBO dn) | ||
180 | { | ||
181 | struct TALER_Amount d; | ||
182 | d.value = ntohl (dn.value); | ||
183 | d.fraction = ntohl (dn.fraction); | ||
184 | memcpy (d.currency, dn.currency, sizeof(dn.currency)); | ||
185 | |||
186 | return d; | ||
187 | } | ||
188 | |||
189 | |||
190 | /** | ||
191 | * Compare the value/fraction of two amounts. Does not compare the currency, | ||
192 | * i.e. comparing amounts with the same value and fraction but different | ||
193 | * currency would return 0. | ||
194 | * | ||
195 | * @param a1 first amount | ||
196 | * @param a2 second amount | ||
197 | * @return result of the comparison | ||
198 | */ | ||
199 | int | ||
200 | TALER_amount_cmp (struct TALER_Amount a1, struct TALER_Amount a2) | ||
201 | { | ||
202 | a1 = TALER_amount_normalize (a1); | ||
203 | a2 = TALER_amount_normalize (a2); | ||
204 | if (a1.value == a2.value) | ||
205 | { | ||
206 | if (a1.fraction < a2.fraction) | ||
207 | return -1; | ||
208 | if (a1.fraction > a2.fraction) | ||
209 | return 1; | ||
210 | return 0; | ||
211 | } | ||
212 | if (a1.value < a2.value) | ||
213 | return -1; | ||
214 | return 1; | ||
215 | } | ||
216 | |||
217 | |||
218 | /** | ||
219 | * Perform saturating subtraction of amounts. | ||
220 | * | ||
221 | * @param a1 amount to subtract from | ||
222 | * @param a2 amount to subtract | ||
223 | * @return (a1-a2) or 0 if a2>=a1 | ||
224 | */ | ||
225 | struct TALER_Amount | ||
226 | TALER_amount_subtract (struct TALER_Amount a1, struct TALER_Amount a2) | ||
227 | { | ||
228 | a1 = TALER_amount_normalize (a1); | ||
229 | a2 = TALER_amount_normalize (a2); | ||
230 | |||
231 | if (a1.value < a2.value) | ||
232 | { | ||
233 | a1.value = 0; | ||
234 | a1.fraction = 0; | ||
235 | return a1; | ||
236 | } | ||
237 | |||
238 | if (a1.fraction < a2.fraction) | ||
239 | { | ||
240 | if (0 == a1.value) | ||
241 | { | ||
242 | a1.fraction = 0; | ||
243 | return a1; | ||
244 | } | ||
245 | a1.fraction += AMOUNT_FRAC_BASE; | ||
246 | a1.value -= 1; | ||
247 | } | ||
248 | |||
249 | a1.fraction -= a2.fraction; | ||
250 | a1.value -= a2.value; | ||
251 | |||
252 | return a1; | ||
253 | } | ||
254 | |||
255 | |||
256 | /** | ||
257 | * Perform saturating addition of amounts. | ||
258 | * | ||
259 | * @param a1 first amount to add | ||
260 | * @param a2 second amount to add | ||
261 | * @return sum of a1 and a2 | ||
262 | */ | ||
263 | struct TALER_Amount | ||
264 | TALER_amount_add (struct TALER_Amount a1, struct TALER_Amount a2) | ||
265 | { | ||
266 | a1 = TALER_amount_normalize (a1); | ||
267 | a2 = TALER_amount_normalize (a2); | ||
268 | |||
269 | a1.value += a2.value; | ||
270 | a1.fraction += a2.fraction; | ||
271 | |||
272 | if (0 == a1.currency[0]) | ||
273 | { | ||
274 | memcpy (a2.currency, a1.currency, TALER_CURRENCY_LEN); | ||
275 | } | ||
276 | |||
277 | if (0 == a2.currency[0]) | ||
278 | { | ||
279 | memcpy (a1.currency, a2.currency, TALER_CURRENCY_LEN); | ||
280 | } | ||
281 | |||
282 | if (0 != a1.currency[0] && 0 != memcmp (a1.currency, a2.currency, TALER_CURRENCY_LEN)) | ||
283 | { | ||
284 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "adding mismatching currencies\n"); | ||
285 | } | ||
286 | |||
287 | if (a1.value < a2.value) | ||
288 | { | ||
289 | a1.value = UINT32_MAX; | ||
290 | a2.value = UINT32_MAX; | ||
291 | return a1; | ||
292 | } | ||
293 | |||
294 | return TALER_amount_normalize (a1); | ||
295 | } | ||
296 | |||
297 | |||
298 | /** | ||
299 | * Normalize the given amount. | ||
300 | * | ||
301 | * @param amout amount to normalize | ||
302 | * @return normalized amount | ||
303 | */ | ||
304 | struct TALER_Amount | ||
305 | TALER_amount_normalize (struct TALER_Amount amount) | ||
306 | { | ||
307 | while (amount.value != UINT32_MAX && amount.fraction >= AMOUNT_FRAC_BASE) | ||
308 | { | ||
309 | amount.fraction -= AMOUNT_FRAC_BASE; | ||
310 | amount.value += 1; | ||
311 | } | ||
312 | return amount; | ||
313 | } | ||
314 | |||
315 | |||
316 | /** | ||
317 | * Convert amount to string. | ||
318 | * | ||
319 | * @param amount amount to convert to string | ||
320 | * @return freshly allocated string representation | ||
321 | */ | ||
322 | char * | ||
323 | TALER_amount_to_string (struct TALER_Amount amount) | ||
324 | { | ||
325 | char tail[AMOUNT_FRAC_LEN + 1] = { 0 }; | ||
326 | char curr[TALER_CURRENCY_LEN + 1] = { 0 }; | ||
327 | char *result = NULL; | ||
328 | int len; | ||
329 | |||
330 | memcpy (curr, amount.currency, TALER_CURRENCY_LEN); | ||
331 | |||
332 | amount = TALER_amount_normalize (amount); | ||
333 | if (0 != amount.fraction) | ||
334 | { | ||
335 | unsigned int i; | ||
336 | uint32_t n = amount.fraction; | ||
337 | for (i = 0; (i < AMOUNT_FRAC_LEN) && (n != 0); i++) | ||
338 | { | ||
339 | tail[i] = '0' + (n / (AMOUNT_FRAC_BASE / 10)); | ||
340 | n = (n * 10) % (AMOUNT_FRAC_BASE); | ||
341 | } | ||
342 | tail[i] = 0; | ||
343 | len = GNUNET_asprintf (&result, "%s:%lu.%s", curr, (unsigned long) amount.value, tail); | ||
344 | } | ||
345 | else | ||
346 | { | ||
347 | len = GNUNET_asprintf (&result, "%s:%lu", curr, (unsigned long) amount.value); | ||
348 | } | ||
349 | GNUNET_assert (len > 0); | ||
350 | return result; | ||
351 | } | ||
352 | |||
353 | |||
354 | |||
355 | /** | 31 | /** |
356 | * Return the base32crockford encoding of the given buffer. | 32 | * Return the base32crockford encoding of the given buffer. |
357 | * | 33 | * |
358 | * The returned string will be freshly allocated, and must be free'd | 34 | * The returned string will be freshly allocated, and must be free'd |
359 | * with GNUNET_free. | 35 | * with GNUNET_free(). |
360 | * | 36 | * |
361 | * @param buffer with data | 37 | * @param buffer with data |
362 | * @param size size of the buffer | 38 | * @param size size of the buffer |
@@ -384,84 +60,4 @@ TALER_data_to_string_alloc (const void *buf, size_t size) | |||
384 | } | 60 | } |
385 | 61 | ||
386 | 62 | ||
387 | /** | ||
388 | * Get encoded binary data from a configuration. | ||
389 | * | ||
390 | * @return GNUNET_OK on success | ||
391 | * GNUNET_NO is the value does not exist | ||
392 | * GNUNET_SYSERR on encoding error | ||
393 | */ | ||
394 | int | ||
395 | TALER_configuration_get_data (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
396 | const char *section, const char *option, | ||
397 | void *buf, size_t buf_size) | ||
398 | { | ||
399 | char *enc; | ||
400 | int res; | ||
401 | size_t data_size; | ||
402 | if (GNUNET_OK != (res = GNUNET_CONFIGURATION_get_value_string (cfg, section, option, &enc))) | ||
403 | return res; | ||
404 | data_size = (strlen (enc) * 5) / 8; | ||
405 | if (data_size != buf_size) | ||
406 | { | ||
407 | GNUNET_free (enc); | ||
408 | return GNUNET_SYSERR; | ||
409 | } | ||
410 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, strlen (enc), | ||
411 | buf, buf_size)) | ||
412 | { | ||
413 | GNUNET_free (enc); | ||
414 | return GNUNET_SYSERR; | ||
415 | } | ||
416 | return GNUNET_OK; | ||
417 | } | ||
418 | |||
419 | |||
420 | static void | ||
421 | derive_refresh_key (const struct GNUNET_HashCode *secret, | ||
422 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, | ||
423 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey) | ||
424 | { | ||
425 | static const char ctx_key[] = "taler-key-skey"; | ||
426 | static const char ctx_iv[] = "taler-key-iv"; | ||
427 | |||
428 | GNUNET_assert (GNUNET_YES == | ||
429 | GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), | ||
430 | ctx_key, strlen (ctx_key), | ||
431 | secret, sizeof (struct GNUNET_HashCode), | ||
432 | NULL, 0)); | ||
433 | GNUNET_assert (GNUNET_YES == | ||
434 | GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector), | ||
435 | ctx_iv, strlen (ctx_iv), | ||
436 | secret, sizeof (struct GNUNET_HashCode), | ||
437 | NULL, 0)); | ||
438 | } | ||
439 | |||
440 | |||
441 | int | ||
442 | TALER_refresh_decrypt (const void *input, size_t input_size, const struct GNUNET_HashCode *secret, void *result) | ||
443 | { | ||
444 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
445 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | ||
446 | |||
447 | derive_refresh_key (secret, &iv, &skey); | ||
448 | |||
449 | return GNUNET_CRYPTO_symmetric_decrypt (input, input_size, &skey, &iv, result); | ||
450 | } | ||
451 | |||
452 | |||
453 | int | ||
454 | TALER_refresh_encrypt (const void *input, size_t input_size, const struct GNUNET_HashCode *secret, void *result) | ||
455 | { | ||
456 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
457 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | ||
458 | |||
459 | derive_refresh_key (secret, &iv, &skey); | ||
460 | |||
461 | return GNUNET_CRYPTO_symmetric_encrypt (input, input_size, &skey, &iv, result); | ||
462 | } | ||
463 | |||
464 | |||
465 | |||
466 | |||
467 | /* end of util.c */ | 63 | /* end of util.c */ |