aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-01-26 12:22:26 +0100
committerChristian Grothoff <christian@grothoff.org>2015-01-26 12:22:26 +0100
commitae917eeee0a3100538cf71972a0cadcc80098d80 (patch)
treeb974e974b53cc258aa24adc448c1df4cbc0d9e49
parentd4506f8a041385f7695b04b1ddfacb894d05da5c (diff)
downloadexchange-ae917eeee0a3100538cf71972a0cadcc80098d80.tar.gz
exchange-ae917eeee0a3100538cf71972a0cadcc80098d80.zip
intermediary commit, breaking the build by starting to move towards variable-size GNUnet signatures instead of fixed-size signatures; much broken now
-rw-r--r--src/include/Makefile.am1
-rw-r--r--src/include/taler_rsa.h360
-rw-r--r--src/include/taler_signatures.h31
-rw-r--r--src/mint/mint.h58
-rw-r--r--src/mint/mint_common.c18
-rw-r--r--src/mint/mint_db.c114
-rw-r--r--src/mint/mint_db.h56
-rw-r--r--src/mint/taler-mint-httpd.c1
-rw-r--r--src/mint/taler-mint-httpd_db.c191
-rw-r--r--src/mint/taler-mint-httpd_db.h15
-rw-r--r--src/mint/taler-mint-httpd_deposit.c1
-rw-r--r--src/mint/taler-mint-httpd_keys.c31
-rw-r--r--src/mint/taler-mint-httpd_keys.h10
-rw-r--r--src/mint/taler-mint-httpd_parsing.c68
-rw-r--r--src/mint/taler-mint-httpd_parsing.h27
-rw-r--r--src/mint/taler-mint-httpd_refresh.c99
-rw-r--r--src/mint/taler-mint-httpd_responses.c22
-rw-r--r--src/mint/taler-mint-httpd_responses.h2
-rw-r--r--src/mint/taler-mint-httpd_withdraw.c62
-rw-r--r--src/mint/taler-mint-keyup.c27
-rw-r--r--src/mint/test_mint_common.c26
-rw-r--r--src/util/Makefile.am3
-rw-r--r--src/util/rsa.c928
23 files changed, 568 insertions, 1583 deletions
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index ebdf8561d..70dee2186 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -5,6 +5,5 @@ talerinclude_HEADERS = \
5 taler_db_lib.h \ 5 taler_db_lib.h \
6 taler_json_lib.h \ 6 taler_json_lib.h \
7 taler_mint_service.h \ 7 taler_mint_service.h \
8 taler_rsa.h \
9 taler_signatures.h \ 8 taler_signatures.h \
10 taler_util.h 9 taler_util.h
diff --git a/src/include/taler_rsa.h b/src/include/taler_rsa.h
deleted file mode 100644
index 1d263ae09..000000000
--- a/src/include/taler_rsa.h
+++ /dev/null
@@ -1,360 +0,0 @@
1/* NOTE: this is obsolete logic, we should migrate to the
2 GNUNET_CRYPTO_rsa-API as soon as possible */
3
4/*
5 This file is part of TALER
6 (C) 2014 Christian Grothoff (and other contributing authors)
7
8 TALER is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 3, or (at your option) any later version.
11
12 TALER is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along with
17 TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
18*/
19
20/**
21 * @file include/taler_rsa.h
22 * @brief RSA key management utilities. Some code is taken from gnunet-0.9.5a
23 * @author Sree Harsha Totakura <sreeharsha@totakura.in>
24 *
25 * Authors of the gnunet code:
26 * Christian Grothoff
27 * Krista Bennett
28 * Gerd Knorr <kraxel@bytesex.org>
29 * Ioana Patrascu
30 * Tzvetan Horozov
31 */
32
33#ifndef TALER_RSA_H
34#define TALER_RSA_H
35
36#include <gnunet/gnunet_common.h>
37#include <gnunet/gnunet_crypto_lib.h>
38
39/**
40 * Length of an RSA KEY (n,e,len), 2048 bit (=256 octests) key n, 2 byte e
41 */
42#define TALER_RSA_KEY_LENGTH 258
43
44/**
45 * @brief Length of RSA encrypted data (2048 bit)
46 *
47 * We currently do not handle encryption of data
48 * that can not be done in a single call to the
49 * RSA methods (read: large chunks of data).
50 * We should never need that, as we can use
51 * the GNUNET_CRYPTO_hash for larger pieces of data for signing,
52 * and for encryption, we only need to encode sessionkeys!
53 */
54#define TALER_RSA_DATA_ENCODING_LENGTH 256
55
56/**
57 * The private information of an RSA key pair.
58 */
59struct TALER_RSA_PrivateKey;
60
61
62GNUNET_NETWORK_STRUCT_BEGIN
63
64/**
65 * GNUnet mandates a certain format for the encoding
66 * of private RSA key information that is provided
67 * by the RSA implementations. This format is used
68 * to serialize a private RSA key (typically when
69 * writing it to disk).
70 */
71struct TALER_RSA_PrivateKeyBinaryEncoded
72{
73 /**
74 * Total size of the structure, in bytes, in big-endian!
75 */
76 uint16_t len GNUNET_PACKED;
77 uint16_t sizen GNUNET_PACKED; /* in big-endian! */
78 uint16_t sizee GNUNET_PACKED; /* in big-endian! */
79 uint16_t sized GNUNET_PACKED; /* in big-endian! */
80 uint16_t sizep GNUNET_PACKED; /* in big-endian! */
81 uint16_t sizeq GNUNET_PACKED; /* in big-endian! */
82 uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */
83 uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */
84 /* followed by the actual values */
85};
86GNUNET_NETWORK_STRUCT_END
87
88
89/**
90 * @brief an RSA signature
91 */
92struct TALER_RSA_Signature
93{
94 unsigned char sig[TALER_RSA_DATA_ENCODING_LENGTH];
95};
96
97GNUNET_NETWORK_STRUCT_BEGIN
98/**
99 * @brief header of what an RSA signature signs
100 * this must be followed by "size - 8" bytes of
101 * the actual signed data
102 */
103struct TALER_RSA_SignaturePurpose
104{
105 /**
106 * How many bytes does this signature sign?
107 * (including this purpose header); in network
108 * byte order (!).
109 */
110 uint32_t size GNUNET_PACKED;
111
112 /**
113 * What does this signature vouch for? This
114 * must contain a GNUNET_SIGNATURE_PURPOSE_XXX
115 * constant (from gnunet_signatures.h). In
116 * network byte order!
117 */
118 uint32_t purpose GNUNET_PACKED;
119
120};
121
122
123struct TALER_RSA_BlindedSignaturePurpose
124{
125 unsigned char data[TALER_RSA_DATA_ENCODING_LENGTH];
126};
127
128
129/**
130 * @brief A public key.
131 */
132struct TALER_RSA_PublicKeyBinaryEncoded
133{
134 /**
135 * In big-endian, must be GNUNET_CRYPTO_RSA_KEY_LENGTH+4
136 */
137 uint16_t len GNUNET_PACKED;
138
139 /**
140 * Size of n in key; in big-endian!
141 */
142 uint16_t sizen GNUNET_PACKED;
143
144 /**
145 * The key itself, contains n followed by e.
146 */
147 unsigned char key[TALER_RSA_KEY_LENGTH];
148
149 /**
150 * Padding (must be 0)
151 */
152 uint16_t padding GNUNET_PACKED;
153};
154
155GNUNET_NETWORK_STRUCT_END
156
157/**
158 * Create a new private key. Caller must free return value.
159 *
160 * @return fresh private key
161 */
162struct TALER_RSA_PrivateKey *
163TALER_RSA_key_create ();
164
165
166/**
167 * Free memory occupied by the private key.
168 *
169 * @param key pointer to the memory to free
170 */
171void
172TALER_RSA_key_free (struct TALER_RSA_PrivateKey *key);
173
174
175/**
176 * Encode the private key in a format suitable for
177 * storing it into a file.
178 * @return encoding of the private key
179 */
180struct TALER_RSA_PrivateKeyBinaryEncoded *
181TALER_RSA_encode_key (const struct TALER_RSA_PrivateKey *hostkey);
182
183
184/**
185 * Extract the public key of the given private key.
186 *
187 * @param priv the private key
188 * @param pub where to write the public key
189 */
190void
191TALER_RSA_key_get_public (const struct TALER_RSA_PrivateKey *priv,
192 struct TALER_RSA_PublicKeyBinaryEncoded *pub);
193
194
195/**
196 * Decode the private key from the data-format back
197 * to the "normal", internal format.
198 *
199 * @param buf the buffer where the private key data is stored
200 * @param len the length of the data in 'buffer'
201 * @return NULL on error
202 */
203struct TALER_RSA_PrivateKey *
204TALER_RSA_decode_key (const char *buf, uint16_t len);
205
206
207/**
208 * Convert a public key to a string.
209 *
210 * @param pub key to convert
211 * @return string representing 'pub'
212 */
213char *
214TALER_RSA_public_key_to_string (const struct TALER_RSA_PublicKeyBinaryEncoded *pub);
215
216
217/**
218 * Convert a string representing a public key to a public key.
219 *
220 * @param enc encoded public key
221 * @param enclen number of bytes in enc (without 0-terminator)
222 * @param pub where to store the public key
223 * @return GNUNET_OK on success
224 */
225int
226TALER_RSA_public_key_from_string (const char *enc,
227 size_t enclen,
228 struct TALER_RSA_PublicKeyBinaryEncoded *pub);
229
230
231/**
232 * Sign a given block.h
233 *
234 * @param key private key to use for the signing
235 * @param msg the message
236 * @param size the size of the message
237 * @param sig where to write the signature
238 * @return GNUNET_SYSERR on error, GNUNET_OK on success
239 */
240int
241TALER_RSA_sign (const struct TALER_RSA_PrivateKey *key,
242 const void *msg,
243 size_t size,
244 struct TALER_RSA_Signature *sig);
245
246
247/**
248 * Verify signature with the given hash.
249 *
250 * @param hash the hash code to verify against the signature
251 * @param sig signature that is being validated
252 * @param publicKey public key of the signer
253 * @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid
254 */
255int
256TALER_RSA_hash_verify (const struct GNUNET_HashCode *hash,
257 const struct TALER_RSA_Signature *sig,
258 const struct TALER_RSA_PublicKeyBinaryEncoded *publicKey);
259
260
261/**
262 * Verify signature on the given message
263 *
264 * @param msg the message
265 * @param size the size of the message
266 * @param sig signature that is being validated
267 * @param publicKey public key of the signer
268 * @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid
269 */
270int
271TALER_RSA_verify (const void *msg, size_t size,
272 const struct TALER_RSA_Signature *sig,
273 const struct TALER_RSA_PublicKeyBinaryEncoded *publicKey);
274
275/**
276 * Key used to blind a message
277 */
278struct TALER_RSA_BlindingKey;
279
280/**
281 * Create a blinding key
282 *
283 * @return the newly created blinding key
284 */
285struct TALER_RSA_BlindingKey *
286TALER_RSA_blinding_key_create ();
287
288
289/**
290 * Destroy a blinding key
291 *
292 * @param bkey the blinding key to destroy
293 */
294void
295TALER_RSA_blinding_key_destroy (struct TALER_RSA_BlindingKey *bkey);
296
297
298/**
299 * Binary encoding for TALER_RSA_BlindingKey
300 */
301struct TALER_RSA_BlindingKeyBinaryEncoded
302{
303 unsigned char data[TALER_RSA_DATA_ENCODING_LENGTH];
304};
305
306
307/**
308 * Encode a blinding key
309 *
310 * @param bkey the blinding key to encode
311 * @param bkey_enc where to store the encoded binary key
312 * @return #GNUNET_OK upon successful encoding; #GNUNET_SYSERR upon failure
313 */
314int
315TALER_RSA_blinding_key_encode (struct TALER_RSA_BlindingKey *bkey,
316 struct TALER_RSA_BlindingKeyBinaryEncoded *bkey_enc);
317
318
319/**
320 * Decode a blinding key from its encoded form
321 *
322 * @param bkey_enc the encoded blinding key
323 * @return the decoded blinding key; NULL upon error
324 */
325struct TALER_RSA_BlindingKey *
326TALER_RSA_blinding_key_decode (struct TALER_RSA_BlindingKeyBinaryEncoded *bkey_enc);
327
328
329/**
330 * Blinds the given message with the given blinding key
331 *
332 * @param msg the message
333 * @param size the size of the message
334 * @param bkey the blinding key
335 * @param pkey the public key of the signer
336 * @return the blinding signature purpose; NULL upon any error
337 */
338struct TALER_RSA_BlindedSignaturePurpose *
339TALER_RSA_message_blind (const void *msg, size_t size,
340 struct TALER_RSA_BlindingKey *bkey,
341 struct TALER_RSA_PublicKeyBinaryEncoded *pkey);
342
343
344/**
345 * Unblind a signature made on blinding signature purpose. The signature
346 * purpose should have been generated with TALER_RSA_message_blind() function.
347 *
348 * @param sig the signature made on the blinded signature purpose
349 * @param bkey the blinding key used to blind the signature purpose
350 * @param pkey the public key of the signer
351 * @return GNUNET_SYSERR upon error; GNUNET_OK upon success.
352 */
353int
354TALER_RSA_unblind (struct TALER_RSA_Signature *sig,
355 struct TALER_RSA_BlindingKey *bkey,
356 struct TALER_RSA_PublicKeyBinaryEncoded *pkey);
357
358#endif /* TALER_RSA_H */
359
360/* end of include/taler_rsa.h */
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index 238a915c1..90fa421c3 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -29,8 +29,6 @@
29#define TALER_SIGNATURES_H 29#define TALER_SIGNATURES_H
30 30
31#include <gnunet/gnunet_util_lib.h> 31#include <gnunet/gnunet_util_lib.h>
32#include "taler_rsa.h"
33
34 32
35/** 33/**
36 * Purpose for signing public keys signed 34 * Purpose for signing public keys signed
@@ -113,17 +111,12 @@
113 111
114GNUNET_NETWORK_STRUCT_BEGIN 112GNUNET_NETWORK_STRUCT_BEGIN
115 113
116
117/** 114/**
118 * Request to withdraw coins from a reserve. 115 * Format used for to generate the signature on a request to withdraw
116 * coins from a reserve.
119 */ 117 */
120struct TALER_WithdrawRequest 118struct TALER_WithdrawRequest
121{ 119{
122 /**
123 * Signature over the rest of the message
124 * by the withdraw public key.
125 */
126 struct GNUNET_CRYPTO_EddsaSignature sig;
127 120
128 /** 121 /**
129 * Purpose must be #TALER_SIGNATURE_WITHDRAW. 122 * Purpose must be #TALER_SIGNATURE_WITHDRAW.
@@ -131,24 +124,20 @@ struct TALER_WithdrawRequest
131 struct GNUNET_CRYPTO_EccSignaturePurpose purpose; 124 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
132 125
133 /** 126 /**
134 * Reserve public key. 127 * Reserve public key (which reserve to withdraw from). This is
128 * the public key which must match the signature.
135 */ 129 */
136 struct GNUNET_CRYPTO_EddsaPublicKey reserve_pub; 130 struct GNUNET_CRYPTO_EddsaPublicKey reserve_pub;
137 131
138 /** 132 /**
139 * Denomination public key for the coin that is withdrawn. 133 * Hash of the denomination public key for the coin that is withdrawn.
140 * FIXME: change to the hash of the public key (so this
141 * is fixed-size).
142 */ 134 */
143 struct TALER_RSA_PublicKeyBinaryEncoded denomination_pub; 135 struct GNUNET_HashCode h_denomination_pub;
144 136
145 /** 137 /**
146 * Purpose containing coin's blinded public key. 138 * Hash of the (blinded) message to be signed by the Mint.
147 *
148 * FIXME: this should be explicitly a variable-size field with the
149 * (blinded) message to be signed by the Mint.
150 */ 139 */
151 struct TALER_RSA_BlindedSignaturePurpose coin_envelope; 140 struct GNUNET_HashCode h_coin_envelope;
152}; 141};
153 142
154 143
@@ -178,7 +167,8 @@ struct TALER_MINT_DenomKeyIssue
178 struct GNUNET_TIME_AbsoluteNBO start; 167 struct GNUNET_TIME_AbsoluteNBO start;
179 struct GNUNET_TIME_AbsoluteNBO expire_withdraw; 168 struct GNUNET_TIME_AbsoluteNBO expire_withdraw;
180 struct GNUNET_TIME_AbsoluteNBO expire_spend; 169 struct GNUNET_TIME_AbsoluteNBO expire_spend;
181 struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; 170 // FIXME: does not work like this:
171 struct GNUNET_CRYPTO_rsa_PublicKey * denom_pub;
182 struct TALER_AmountNBO value; 172 struct TALER_AmountNBO value;
183 struct TALER_AmountNBO fee_withdraw; 173 struct TALER_AmountNBO fee_withdraw;
184 struct TALER_AmountNBO fee_deposit; 174 struct TALER_AmountNBO fee_deposit;
@@ -238,4 +228,3 @@ struct RefreshMeltConfirmSignRequestBody
238GNUNET_NETWORK_STRUCT_END 228GNUNET_NETWORK_STRUCT_END
239 229
240#endif 230#endif
241
diff --git a/src/mint/mint.h b/src/mint/mint.h
index 39dda7d5f..1dc179340 100644
--- a/src/mint/mint.h
+++ b/src/mint/mint.h
@@ -29,7 +29,6 @@
29#include <gnunet/gnunet_common.h> 29#include <gnunet/gnunet_common.h>
30#include <libpq-fe.h> 30#include <libpq-fe.h>
31#include "taler_util.h" 31#include "taler_util.h"
32#include "taler_rsa.h"
33#include "taler_signatures.h" 32#include "taler_signatures.h"
34 33
35#define DIR_SIGNKEYS "signkeys" 34#define DIR_SIGNKEYS "signkeys"
@@ -55,7 +54,7 @@ struct TALER_MINT_DenomKeyIssuePriv
55 * The private key of the denomination. Will be NULL if the private key is 54 * The private key of the denomination. Will be NULL if the private key is
56 * not available. 55 * not available.
57 */ 56 */
58 struct TALER_RSA_PrivateKey *denom_priv; 57 struct GNUNET_CRYPTO_rsa_PrivateKey *denom_priv;
59 58
60 struct TALER_MINT_DenomKeyIssue issue; 59 struct TALER_MINT_DenomKeyIssue issue;
61}; 60};
@@ -75,26 +74,43 @@ struct TALER_CoinPublicInfo
75 /* 74 /*
76 * The public key signifying the coin's denomination. 75 * The public key signifying the coin's denomination.
77 */ 76 */
78 struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; 77 struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
79 78
80 /** 79 /**
81 * Signature over coin_pub by denom_pub. 80 * Signature over coin_pub by denom_pub.
82 */ 81 */
83 struct TALER_RSA_Signature denom_sig; 82 struct GNUNET_CRYPTO_rsa_Signature *denom_sig;
84}; 83};
85 84
86 85
87 86
87/**
88 * Information we keep for a withdrawn coin to reproduce
89 * the /withdraw operation if needed, and to have proof
90 * that a reserve was drained by this amount.
91 */
92struct CollectableBlindcoin
93{
88 94
95 /**
96 * Our signature over the (blinded) coin.
97 */
98 struct GNUNET_CRYPTO_rsa_Signature *sig;
89 99
100 /**
101 * Denomination key (which coin was generated).
102 */
103 struct GNUNET_CRYPOT_rsa_PublicKey *denom_pub;
90 104
91 105 /**
92struct CollectableBlindcoin 106 * Public key of the reserve that was drained.
93{ 107 */
94 struct TALER_RSA_BlindedSignaturePurpose ev;
95 struct TALER_RSA_Signature ev_sig;
96 struct TALER_RSA_PublicKeyBinaryEncoded denom_pub;
97 struct GNUNET_CRYPTO_EddsaPublicKey reserve_pub; 108 struct GNUNET_CRYPTO_EddsaPublicKey reserve_pub;
109
110 /**
111 * Signature confirming the withdrawl, matching @e reserve_pub,
112 * @e denom_pub and @e h_blind.
113 */
98 struct GNUNET_CRYPTO_EddsaSignature reserve_sig; 114 struct GNUNET_CRYPTO_EddsaSignature reserve_sig;
99}; 115};
100 116
@@ -127,7 +143,7 @@ struct RefreshCommitLink
127struct LinkData 143struct LinkData
128{ 144{
129 struct GNUNET_CRYPTO_EcdsaPrivateKey coin_priv; 145 struct GNUNET_CRYPTO_EcdsaPrivateKey coin_priv;
130 struct TALER_RSA_BlindingKeyBinaryEncoded bkey_enc; 146 struct GNUNET_CRYPTO_rsa_BlindingKey *bkey_enc;
131}; 147};
132 148
133 149
@@ -149,7 +165,17 @@ GNUNET_NETWORK_STRUCT_END
149struct RefreshCommitCoin 165struct RefreshCommitCoin
150{ 166{
151 struct GNUNET_CRYPTO_EddsaPublicKey session_pub; 167 struct GNUNET_CRYPTO_EddsaPublicKey session_pub;
152 struct TALER_RSA_BlindedSignaturePurpose coin_ev; 168
169 /**
170 * Blinded message to be signed (in envelope).
171 */
172 char *coin_ev;
173
174 /**
175 * Number of bytes in @e coin_ev.
176 */
177 size_t coin_ev_size;
178
153 uint16_t cnc_index; 179 uint16_t cnc_index;
154 uint16_t newcoin_index; 180 uint16_t newcoin_index;
155 char link_enc[sizeof (struct LinkData)]; 181 char link_enc[sizeof (struct LinkData)];
@@ -177,17 +203,17 @@ struct Deposit
177 /* FIXME: should be TALER_CoinPublicInfo */ 203 /* FIXME: should be TALER_CoinPublicInfo */
178 struct GNUNET_CRYPTO_EddsaPublicKey coin_pub; 204 struct GNUNET_CRYPTO_EddsaPublicKey coin_pub;
179 205
180 struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; 206 struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
181 207
182 struct TALER_RSA_Signature coin_sig; 208 struct GNUNET_CRYPTO_rsa_Signature *coin_sig;
183 209
184 struct TALER_RSA_Signature ubsig; 210 struct GNUNET_CRYPTO_rsa_Signature *ubsig; // ???
185 211
186 /** 212 /**
187 * Type of the deposit (also purpose of the signature). Either 213 * Type of the deposit (also purpose of the signature). Either
188 * #TALER_SIGNATURE_DEPOSIT or #TALER_SIGNATURE_INCREMENTAL_DEPOSIT. 214 * #TALER_SIGNATURE_DEPOSIT or #TALER_SIGNATURE_INCREMENTAL_DEPOSIT.
189 */ 215 */
190 struct TALER_RSA_SignaturePurpose purpose; 216 // struct TALER_RSA_SignaturePurpose purpose; // FIXME: bad type!
191 217
192 uint64_t transaction_id; 218 uint64_t transaction_id;
193 219
diff --git a/src/mint/mint_common.c b/src/mint/mint_common.c
index 734085e7b..bb55f30c4 100644
--- a/src/mint/mint_common.c
+++ b/src/mint/mint_common.c
@@ -93,7 +93,7 @@ TALER_MINT_read_denom_key (const char *filename,
93 uint64_t size; 93 uint64_t size;
94 size_t offset; 94 size_t offset;
95 void *data; 95 void *data;
96 struct TALER_RSA_PrivateKey *priv; 96 struct GNUNET_CRYPTO_rsa_PrivateKey *priv;
97 int ret; 97 int ret;
98 98
99 ret = GNUNET_SYSERR; 99 ret = GNUNET_SYSERR;
@@ -115,7 +115,8 @@ TALER_MINT_read_denom_key (const char *filename,
115 data, 115 data,
116 size)) 116 size))
117 goto cleanup; 117 goto cleanup;
118 if (NULL == (priv = TALER_RSA_decode_key (data + offset, size - offset))) 118 if (NULL == (priv = GNUNET_CRYPTO_rsa_private_key_decode (data + offset,
119 size - offset)))
119 goto cleanup; 120 goto cleanup;
120 dki->denom_priv = priv; 121 dki->denom_priv = priv;
121 memcpy (&dki->issue.signature, data, offset); 122 memcpy (&dki->issue.signature, data, offset);
@@ -138,22 +139,22 @@ int
138TALER_MINT_write_denom_key (const char *filename, 139TALER_MINT_write_denom_key (const char *filename,
139 const struct TALER_MINT_DenomKeyIssuePriv *dki) 140 const struct TALER_MINT_DenomKeyIssuePriv *dki)
140{ 141{
141 struct TALER_RSA_PrivateKeyBinaryEncoded *priv_enc; 142 char *priv_enc;
143 size_t priv_enc_size;
142 struct GNUNET_DISK_FileHandle *fh; 144 struct GNUNET_DISK_FileHandle *fh;
143 ssize_t wrote; 145 ssize_t wrote;
144 size_t wsize; 146 size_t wsize;
145 int ret; 147 int ret;
146 148
147 fh = NULL; 149 fh = NULL;
148 priv_enc = NULL; 150 priv_enc_size = GNUNET_CRYPTO_rsa_private_key_encode (dki->denom_priv,
151 &priv_enc);
149 ret = GNUNET_SYSERR; 152 ret = GNUNET_SYSERR;
150 if (NULL == (fh = GNUNET_DISK_file_open 153 if (NULL == (fh = GNUNET_DISK_file_open
151 (filename, 154 (filename,
152 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE, 155 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE,
153 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE))) 156 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)))
154 goto cleanup; 157 goto cleanup;
155 if (NULL == (priv_enc = TALER_RSA_encode_key (dki->denom_priv)))
156 goto cleanup;
157 wsize = sizeof (struct TALER_MINT_DenomKeyIssuePriv) 158 wsize = sizeof (struct TALER_MINT_DenomKeyIssuePriv)
158 - offsetof (struct TALER_MINT_DenomKeyIssuePriv, issue.signature); 159 - offsetof (struct TALER_MINT_DenomKeyIssuePriv, issue.signature);
159 if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh, 160 if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh,
@@ -162,12 +163,11 @@ TALER_MINT_write_denom_key (const char *filename,
162 goto cleanup; 163 goto cleanup;
163 if (wrote != wsize) 164 if (wrote != wsize)
164 goto cleanup; 165 goto cleanup;
165 wsize = ntohs (priv_enc->len);
166 if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh, 166 if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh,
167 priv_enc, 167 priv_enc,
168 wsize))) 168 priv_enc_size)))
169 goto cleanup; 169 goto cleanup;
170 if (wrote != wsize) 170 if (wrote != priv_enc_size)
171 goto cleanup; 171 goto cleanup;
172 ret = GNUNET_OK; 172 ret = GNUNET_OK;
173 cleanup: 173 cleanup:
diff --git a/src/mint/mint_db.c b/src/mint/mint_db.c
index 6ce60fc45..60ad14493 100644
--- a/src/mint/mint_db.c
+++ b/src/mint/mint_db.c
@@ -54,25 +54,44 @@ static char *TALER_MINT_db_connection_cfg_str;
54 if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ 54 if (cond) { GNUNET_break (0); goto EXITIF_exit; } \
55 } while (0) 55 } while (0)
56 56
57
58/**
59 * Locate the response for a /withdraw request under the
60 * key of the hash of the blinded message.
61 *
62 * @param db_conn database connection to use
63 * @param h_blind hash of the blinded message
64 * @param collectable corresponding collectable coin (blind signature)
65 * if a coin is found
66 * @return #GNUNET_SYSERR on internal error
67 * #GNUNET_NO if the collectable was not found
68 * #GNUNET_YES on success
69 */
57int 70int
58TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn, 71TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn,
59 struct TALER_RSA_BlindedSignaturePurpose *blind_ev, 72 const struct GNUNET_HashCode *h_blind,
60 struct CollectableBlindcoin *collectable) 73 struct CollectableBlindcoin *collectable)
61{ 74{
62 PGresult *result; 75 PGresult *result;
63 struct TALER_DB_QueryParam params[] = { 76 struct TALER_DB_QueryParam params[] = {
64 TALER_DB_QUERY_PARAM_PTR (blind_ev), 77 TALER_DB_QUERY_PARAM_PTR (h_blind),
65 TALER_DB_QUERY_PARAM_END 78 TALER_DB_QUERY_PARAM_END
66 }; 79 };
67 result = TALER_DB_exec_prepared (db_conn, "get_collectable_blindcoins", params); 80 char *sig_buf;
81 size_t sig_buf_size;
82
83 result = TALER_DB_exec_prepared (db_conn,
84 "get_collectable_blindcoins",
85 params);
68 86
69 if (PGRES_TUPLES_OK != PQresultStatus (result)) 87 if (PGRES_TUPLES_OK != PQresultStatus (result))
70 { 88 {
71 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Query failed: %s\n", PQresultErrorMessage (result)); 89 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
90 "Query failed: %s\n",
91 PQresultErrorMessage (result));
72 PQclear (result); 92 PQclear (result);
73 return GNUNET_SYSERR; 93 return GNUNET_SYSERR;
74 } 94 }
75
76 if (0 == PQntuples (result)) 95 if (0 == PQntuples (result))
77 { 96 {
78 PQclear (result); 97 PQclear (result);
@@ -80,7 +99,7 @@ TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn,
80 } 99 }
81 100
82 struct TALER_DB_ResultSpec rs[] = { 101 struct TALER_DB_ResultSpec rs[] = {
83 TALER_DB_RESULT_SPEC("blind_ev_sig", &collectable->ev_sig), 102 TALER_DB_RESULT_SPEC_VAR("blind_sig", &sig_buf, &sig_buf_size),
84 TALER_DB_RESULT_SPEC("denom_pub", &collectable->denom_pub), 103 TALER_DB_RESULT_SPEC("denom_pub", &collectable->denom_pub),
85 TALER_DB_RESULT_SPEC("reserve_sig", &collectable->reserve_sig), 104 TALER_DB_RESULT_SPEC("reserve_sig", &collectable->reserve_sig),
86 TALER_DB_RESULT_SPEC("reserve_pub", &collectable->reserve_pub), 105 TALER_DB_RESULT_SPEC("reserve_pub", &collectable->reserve_pub),
@@ -93,43 +112,66 @@ TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn,
93 PQclear (result); 112 PQclear (result);
94 return GNUNET_SYSERR; 113 return GNUNET_SYSERR;
95 } 114 }
96 (void) memcpy (&collectable->ev, blind_ev, sizeof (struct TALER_RSA_BlindedSignaturePurpose));
97 PQclear (result); 115 PQclear (result);
98 return GNUNET_OK; 116 return GNUNET_OK;
99} 117}
100 118
101 119
120/**
121 * Store collectable bit coin under the corresponding
122 * hash of the blinded message.
123 *
124 * @param db_conn database connection to use
125 * @param h_blind hash of the blinded message
126 * @param collectable corresponding collectable coin (blind signature)
127 * if a coin is found
128 * @return #GNUNET_SYSERR on internal error
129 * #GNUNET_NO if the collectable was not found
130 * #GNUNET_YES on success
131 */
102int 132int
103TALER_MINT_DB_insert_collectable_blindcoin (PGconn *db_conn, 133TALER_MINT_DB_insert_collectable_blindcoin (PGconn *db_conn,
134 const struct GNUNET_HashCode *h_blind,
104 const struct CollectableBlindcoin *collectable) 135 const struct CollectableBlindcoin *collectable)
105{ 136{
106 PGresult *result; 137 PGresult *result;
107 struct TALER_DB_QueryParam params[] = { 138 char *sig_buf;
108 TALER_DB_QUERY_PARAM_PTR (&collectable->ev), 139 size_t sig_buf_size;
109 TALER_DB_QUERY_PARAM_PTR (&collectable->ev_sig), 140
110 TALER_DB_QUERY_PARAM_PTR (&collectable->denom_pub), 141 sig_buf_size = GNUNET_CRYPTO_rsa_signature_encode (collectable->sig,
111 TALER_DB_QUERY_PARAM_PTR (&collectable->reserve_pub), 142 &sig_buf);
112 TALER_DB_QUERY_PARAM_PTR (&collectable->reserve_sig), 143 {
113 TALER_DB_QUERY_PARAM_END 144 struct TALER_DB_QueryParam params[] = {
114 }; 145 TALER_DB_QUERY_PARAM_PTR (&h_blind),
115 result = TALER_DB_exec_prepared (db_conn, "insert_collectable_blindcoins", params); 146 TALER_DB_QUERY_PARAM_PTR_SIZED (sig_buf, sig_buf_size),
147 TALER_DB_QUERY_PARAM_PTR (&collectable->denom_pub),
148 TALER_DB_QUERY_PARAM_PTR (&collectable->reserve_pub),
149 TALER_DB_QUERY_PARAM_PTR (&collectable->reserve_sig),
150 TALER_DB_QUERY_PARAM_END
151 };
116 152
117 if (PGRES_COMMAND_OK != PQresultStatus (result)) 153 result = TALER_DB_exec_prepared (db_conn,
118 { 154 "insert_collectable_blindcoins",
119 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Query failed: %s\n", PQresultErrorMessage (result)); 155 params);
120 PQclear (result); 156 if (PGRES_COMMAND_OK != PQresultStatus (result))
121 return GNUNET_SYSERR; 157 {
122 } 158 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
159 "Query failed: %s\n",
160 PQresultErrorMessage (result));
161 PQclear (result);
162 return GNUNET_SYSERR;
163 }
123 164
124 if (0 != strcmp ("1", PQcmdTuples (result))) 165 if (0 != strcmp ("1", PQcmdTuples (result)))
125 { 166 {
126 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Insert failed (updated '%s' tupes instead of '1')\n", 167 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
127 PQcmdTuples (result)); 168 "Insert failed (updated '%s' tupes instead of '1')\n",
169 PQcmdTuples (result));
170 PQclear (result);
171 return GNUNET_SYSERR;
172 }
128 PQclear (result); 173 PQclear (result);
129 return GNUNET_SYSERR;
130 } 174 }
131
132 PQclear (result);
133 return GNUNET_OK; 175 return GNUNET_OK;
134} 176}
135 177
@@ -730,7 +772,7 @@ int
730TALER_MINT_DB_insert_refresh_order (PGconn *db_conn, 772TALER_MINT_DB_insert_refresh_order (PGconn *db_conn,
731 uint16_t newcoin_index, 773 uint16_t newcoin_index,
732 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, 774 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
733 const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub) 775 const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub)
734{ 776{
735 uint16_t newcoin_index_nbo = htons (newcoin_index); 777 uint16_t newcoin_index_nbo = htons (newcoin_index);
736 struct TALER_DB_QueryParam params[] = { 778 struct TALER_DB_QueryParam params[] = {
@@ -1267,7 +1309,7 @@ int
1267TALER_MINT_DB_get_refresh_order (PGconn *db_conn, 1309TALER_MINT_DB_get_refresh_order (PGconn *db_conn,
1268 uint16_t newcoin_index, 1310 uint16_t newcoin_index,
1269 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, 1311 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
1270 struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub) 1312 struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub)
1271{ 1313{
1272 uint16_t newcoin_index_nbo = htons (newcoin_index); 1314 uint16_t newcoin_index_nbo = htons (newcoin_index);
1273 1315
@@ -1315,7 +1357,7 @@ int
1315TALER_MINT_DB_insert_refresh_collectable (PGconn *db_conn, 1357TALER_MINT_DB_insert_refresh_collectable (PGconn *db_conn,
1316 uint16_t newcoin_index, 1358 uint16_t newcoin_index,
1317 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, 1359 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
1318 const struct TALER_RSA_Signature *ev_sig) 1360 const struct GNUNET_CRYPTO_rsa_Signature *ev_sig)
1319{ 1361{
1320 uint16_t newcoin_index_nbo = htons (newcoin_index); 1362 uint16_t newcoin_index_nbo = htons (newcoin_index);
1321 struct TALER_DB_QueryParam params[] = { 1363 struct TALER_DB_QueryParam params[] = {
@@ -1343,7 +1385,7 @@ int
1343TALER_MINT_DB_get_refresh_collectable (PGconn *db_conn, 1385TALER_MINT_DB_get_refresh_collectable (PGconn *db_conn,
1344 uint16_t newcoin_index, 1386 uint16_t newcoin_index,
1345 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, 1387 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
1346 struct TALER_RSA_Signature *ev_sig) 1388 struct GNUNET_CRYPTO_rsa_Signature *ev_sig)
1347{ 1389{
1348 1390
1349 uint16_t newcoin_index_nbo = htons (newcoin_index); 1391 uint16_t newcoin_index_nbo = htons (newcoin_index);
@@ -1394,7 +1436,7 @@ TALER_MINT_DB_insert_refresh_melt (PGconn *db_conn,
1394 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, 1436 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
1395 uint16_t oldcoin_index, 1437 uint16_t oldcoin_index,
1396 const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub, 1438 const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
1397 const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub) 1439 const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub)
1398{ 1440{
1399 uint16_t oldcoin_index_nbo = htons (oldcoin_index); 1441 uint16_t oldcoin_index_nbo = htons (oldcoin_index);
1400 struct TALER_DB_QueryParam params[] = { 1442 struct TALER_DB_QueryParam params[] = {
@@ -1499,8 +1541,8 @@ TALER_db_get_link (PGconn *db_conn,
1499 for (i = 0; i < PQntuples (result); i++) 1541 for (i = 0; i < PQntuples (result); i++)
1500 { 1542 {
1501 struct LinkDataEnc link_data_enc; 1543 struct LinkDataEnc link_data_enc;
1502 struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; 1544 struct GNUNET_CRYPTO_rsa__PublicKey *denom_pub;
1503 struct TALER_RSA_Signature ev_sig; 1545 struct GNUNET_CRYPTO_rsa_Signature *sig;
1504 struct TALER_DB_ResultSpec rs[] = { 1546 struct TALER_DB_ResultSpec rs[] = {
1505 TALER_DB_RESULT_SPEC("link_vector_enc", &link_data_enc), 1547 TALER_DB_RESULT_SPEC("link_vector_enc", &link_data_enc),
1506 TALER_DB_RESULT_SPEC("denom_pub", &denom_pub), 1548 TALER_DB_RESULT_SPEC("denom_pub", &denom_pub),
diff --git a/src/mint/mint_db.h b/src/mint/mint_db.h
index 7998a01cf..01ad1a6ed 100644
--- a/src/mint/mint_db.h
+++ b/src/mint/mint_db.h
@@ -27,7 +27,6 @@
27#include <microhttpd.h> 27#include <microhttpd.h>
28#include <gnunet/gnunet_util_lib.h> 28#include <gnunet/gnunet_util_lib.h>
29#include "taler_util.h" 29#include "taler_util.h"
30#include "taler_rsa.h"
31#include "taler-mint-httpd_db.h" 30#include "taler-mint-httpd_db.h"
32#include "mint.h" 31#include "mint.h"
33 32
@@ -35,13 +34,40 @@
35int 34int
36TALER_MINT_DB_prepare (PGconn *db_conn); 35TALER_MINT_DB_prepare (PGconn *db_conn);
37 36
37
38/**
39 * Locate the response for a /withdraw request under the
40 * key of the hash of the blinded message.
41 *
42 * @param db_conn database connection to use
43 * @param h_blind hash of the blinded message
44 * @param collectable corresponding collectable coin (blind signature)
45 * if a coin is found
46 * @return #GNUNET_SYSERR on internal error
47 * #GNUNET_NO if the collectable was not found
48 * #GNUNET_YES on success
49 */
38int 50int
39TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn, 51TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn,
40 struct TALER_RSA_BlindedSignaturePurpose *blind_ev, 52 const struct GNUNET_HashCode *h_blind,
41 struct CollectableBlindcoin *collectable); 53 struct CollectableBlindcoin *collectable);
42 54
55
56/**
57 * Store collectable bit coin under the corresponding
58 * hash of the blinded message.
59 *
60 * @param db_conn database connection to use
61 * @param h_blind hash of the blinded message
62 * @param collectable corresponding collectable coin (blind signature)
63 * if a coin is found
64 * @return #GNUNET_SYSERR on internal error
65 * #GNUNET_NO if the collectable was not found
66 * #GNUNET_YES on success
67 */
43int 68int
44TALER_MINT_DB_insert_collectable_blindcoin (PGconn *db_conn, 69TALER_MINT_DB_insert_collectable_blindcoin (PGconn *db_conn,
70 const struct GNUNET_HashCode *h_blind,
45 const struct CollectableBlindcoin *collectable); 71 const struct CollectableBlindcoin *collectable);
46 72
47 73
@@ -62,6 +88,15 @@ TALER_MINT_DB_get_reserve (PGconn *db_conn,
62 const struct GNUNET_CRYPTO_EddsaPublicKey *reserve_pub, 88 const struct GNUNET_CRYPTO_EddsaPublicKey *reserve_pub,
63 struct Reserve *reserve_res); 89 struct Reserve *reserve_res);
64 90
91
92/**
93 * Update information about a reserve.
94 *
95 * @param db_conn
96 * @param reserve current reserve status
97 * @param fresh FIXME
98 * @return #GNUNET_OK on success
99 */
65int 100int
66TALER_MINT_DB_update_reserve (PGconn *db_conn, 101TALER_MINT_DB_update_reserve (PGconn *db_conn,
67 const struct Reserve *reserve, 102 const struct Reserve *reserve,
@@ -72,7 +107,7 @@ int
72TALER_MINT_DB_insert_refresh_order (PGconn *db_conn, 107TALER_MINT_DB_insert_refresh_order (PGconn *db_conn,
73 uint16_t newcoin_index, 108 uint16_t newcoin_index,
74 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, 109 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
75 const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub); 110 const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub);
76 111
77int 112int
78TALER_MINT_DB_get_refresh_session (PGconn *db_conn, 113TALER_MINT_DB_get_refresh_session (PGconn *db_conn,
@@ -123,19 +158,22 @@ int
123TALER_MINT_DB_get_refresh_order (PGconn *db_conn, 158TALER_MINT_DB_get_refresh_order (PGconn *db_conn,
124 uint16_t newcoin_index, 159 uint16_t newcoin_index,
125 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, 160 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
126 struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub); 161 struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub);
127 162
128 163
129int 164int
130TALER_MINT_DB_insert_refresh_collectable (PGconn *db_conn, 165TALER_MINT_DB_insert_refresh_collectable (PGconn *db_conn,
131 uint16_t newcoin_index, 166 uint16_t newcoin_index,
132 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, 167 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
133 const struct TALER_RSA_Signature *ev_sig); 168 const struct GNUNET_CRYPTO_rsa_Signature *ev_sig);
169
134int 170int
135TALER_MINT_DB_get_refresh_collectable (PGconn *db_conn, 171TALER_MINT_DB_get_refresh_collectable (PGconn *db_conn,
136 uint16_t newcoin_index, 172 uint16_t newcoin_index,
137 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, 173 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
138 struct TALER_RSA_Signature *ev_sig); 174 struct GNUNET_CRYPTO_rsa_Signature *ev_sig);
175
176
139int 177int
140TALER_MINT_DB_set_reveal_ok (PGconn *db_conn, 178TALER_MINT_DB_set_reveal_ok (PGconn *db_conn,
141 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub); 179 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub);
@@ -145,7 +183,7 @@ TALER_MINT_DB_insert_refresh_melt (PGconn *db_conn,
145 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, 183 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
146 uint16_t oldcoin_index, 184 uint16_t oldcoin_index,
147 const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub, 185 const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
148 const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub); 186 const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub);
149 187
150 188
151int 189int
@@ -158,8 +196,8 @@ TALER_MINT_DB_get_refresh_melt (PGconn *db_conn,
158typedef 196typedef
159int (*LinkIterator) (void *cls, 197int (*LinkIterator) (void *cls,
160 const struct LinkDataEnc *link_data_enc, 198 const struct LinkDataEnc *link_data_enc,
161 const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub, 199 const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub,
162 const struct TALER_RSA_Signature *ev_sig); 200 const struct GNUNET_CRYPTO_rsa_Signature *ev_sig);
163 201
164int 202int
165TALER_db_get_link (PGconn *db_conn, 203TALER_db_get_link (PGconn *db_conn,
diff --git a/src/mint/taler-mint-httpd.c b/src/mint/taler-mint-httpd.c
index 9dc03cdea..ffd97a1ad 100644
--- a/src/mint/taler-mint-httpd.c
+++ b/src/mint/taler-mint-httpd.c
@@ -29,7 +29,6 @@
29#include <pthread.h> 29#include <pthread.h>
30#include "mint.h" 30#include "mint.h"
31#include "taler_signatures.h" 31#include "taler_signatures.h"
32#include "taler_rsa.h"
33#include "taler_json_lib.h" 32#include "taler_json_lib.h"
34#include "taler-mint-httpd_parsing.h" 33#include "taler-mint-httpd_parsing.h"
35#include "taler-mint-httpd_mhd.h" 34#include "taler-mint-httpd_mhd.h"
diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c
index 369e88967..78946f50f 100644
--- a/src/mint/taler-mint-httpd_db.c
+++ b/src/mint/taler-mint-httpd_db.c
@@ -83,9 +83,9 @@ TALER_MINT_db_execute_deposit (struct MHD_Connection *connection,
83 83
84 if (GNUNET_SYSERR == res) 84 if (GNUNET_SYSERR == res)
85 { 85 {
86 GNUNET_break (0); 86 GNUNET_break (0);
87 /* FIXME: return error message to client via MHD! */ 87 /* FIXME: return error message to client via MHD! */
88 return MHD_NO; 88 return MHD_NO;
89 } 89 }
90 90
91 { 91 {
@@ -221,56 +221,65 @@ TALER_MINT_db_execute_withdraw_status (struct MHD_Connection *connection,
221 * Execute a /withdraw/sign. 221 * Execute a /withdraw/sign.
222 * 222 *
223 * @param connection the MHD connection to handle 223 * @param connection the MHD connection to handle
224 * @param wsrd_ro details about the withdraw request 224 * @param reserve public key of the reserve
225 * @param denomination_pub public key of the denomination requested
226 * @param blinded_msg blinded message to be signed
227 * @param blinded_msg_len number of bytes in @a blinded_msg
228 * @param signature signature over the withdraw request, to be stored in DB
225 * @return MHD result code 229 * @return MHD result code
226 */ 230 */
227int 231int
228TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection, 232TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,
229 const struct TALER_WithdrawRequest *wsrd_ro) 233 const struct GNUNET_CRYPTO_EddsaPublicKey *reserve,
234 const struct GNUNET_CRYPTO_rsa_PublicKey *denomination_pub,
235 const char *blinded_msg,
236 size_t blinded_msg_len,
237 const struct GNUNET_CRYPTO_EddsaSignature *signature)
230{ 238{
231 PGconn *db_conn; 239 PGconn *db_conn;
232 struct Reserve reserve; 240 struct Reserve db_reserve;
233 struct MintKeyState *key_state; 241 struct MintKeyState *key_state;
234 struct CollectableBlindcoin collectable; 242 struct CollectableBlindcoin collectable;
235 struct TALER_MINT_DenomKeyIssuePriv *dki; 243 struct TALER_MINT_DenomKeyIssuePriv *dki;
236 struct TALER_RSA_Signature ev_sig; 244 struct GNUNET_CRYPTO_rsa_Signature *sig;
237 struct TALER_Amount amount_required; 245 struct TALER_Amount amount_required;
238 /* FIXME: the fact that we do this here is a sign that we 246 struct GNUNET_HashCode h_blind;
239 need to have different versions of this struct for
240 the different places it is used! */
241 struct TALER_WithdrawRequest wsrd = *wsrd_ro;
242 int res; 247 int res;
243 248
249 GNUNET_CRYPTO_hash (blinded_msg,
250 blinded_msg_len,
251 &h_blind);
252
244 if (NULL == (db_conn = TALER_MINT_DB_get_connection ())) 253 if (NULL == (db_conn = TALER_MINT_DB_get_connection ()))
245 { 254 {
246 GNUNET_break (0); 255 GNUNET_break (0);
247 return TALER_MINT_reply_internal_db_error (connection); 256 return TALER_MINT_reply_internal_db_error (connection);
248 } 257 }
249
250
251 res = TALER_MINT_DB_get_collectable_blindcoin (db_conn, 258 res = TALER_MINT_DB_get_collectable_blindcoin (db_conn,
252 &wsrd.coin_envelope, 259 &h_blind,
253 &collectable); 260 &collectable);
254 if (GNUNET_SYSERR == res) 261 if (GNUNET_SYSERR == res)
255 { 262 {
256 // FIXME: return 'internal error'
257 GNUNET_break (0); 263 GNUNET_break (0);
258 return MHD_NO; 264 return TALER_MINT_reply_internal_db_error (connection);
259 } 265 }
260 266
261 /* Don't sign again if we have already signed the coin */ 267 /* Don't sign again if we have already signed the coin */
262 if (GNUNET_YES == res) 268 if (GNUNET_YES == res)
263 return TALER_MINT_reply_withdraw_sign_success (connection, 269 {
264 &collectable); 270 res = TALER_MINT_reply_withdraw_sign_success (connection,
271 &collectable);
272 GNUNET_CRYPTO_rsa_signature_free (collectable.sig);
273 return res;
274 }
265 GNUNET_assert (GNUNET_NO == res); 275 GNUNET_assert (GNUNET_NO == res);
266 res = TALER_MINT_DB_get_reserve (db_conn, 276 res = TALER_MINT_DB_get_reserve (db_conn,
267 &wsrd.reserve_pub, 277 reserve,
268 &reserve); 278 &db_reserve);
269 if (GNUNET_SYSERR == res) 279 if (GNUNET_SYSERR == res)
270 { 280 {
271 // FIXME: return 'internal error'
272 GNUNET_break (0); 281 GNUNET_break (0);
273 return MHD_NO; 282 return TALER_MINT_reply_internal_db_error (connection);
274 } 283 }
275 if (GNUNET_NO == res) 284 if (GNUNET_NO == res)
276 return TALER_MINT_reply_json_pack (connection, 285 return TALER_MINT_reply_json_pack (connection,
@@ -279,26 +288,9 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,
279 "error", 288 "error",
280 "Reserve not found"); 289 "Reserve not found");
281 290
282 // fill out all the missing info in the request before
283 // we can check the signature on the request
284
285 wsrd.purpose.purpose = htonl (TALER_SIGNATURE_WITHDRAW);
286 wsrd.purpose.size = htonl (sizeof (struct TALER_WithdrawRequest) -
287 offsetof (struct TALER_WithdrawRequest, purpose));
288
289 if (GNUNET_OK !=
290 GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WITHDRAW,
291 &wsrd.purpose,
292 &wsrd.sig,
293 &wsrd.reserve_pub))
294 return TALER_MINT_reply_json_pack (connection,
295 MHD_HTTP_UNAUTHORIZED,
296 "{s:s}",
297 "error", "Invalid Signature");
298
299 key_state = TALER_MINT_key_state_acquire (); 291 key_state = TALER_MINT_key_state_acquire ();
300 dki = TALER_MINT_get_denom_key (key_state, 292 dki = TALER_MINT_get_denom_key (key_state,
301 &wsrd.denomination_pub); 293 denomination_pub);
302 TALER_MINT_key_state_release (key_state); 294 TALER_MINT_key_state_release (key_state);
303 if (NULL == dki) 295 if (NULL == dki)
304 return TALER_MINT_reply_json_pack (connection, 296 return TALER_MINT_reply_json_pack (connection,
@@ -307,52 +299,54 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,
307 "error", 299 "error",
308 "Denomination not found"); 300 "Denomination not found");
309 301
310 amount_required = TALER_amount_ntoh (dki->issue.value); 302 amount_required = TALER_amount_add (TALER_amount_ntoh (dki->issue.value),
311 amount_required = TALER_amount_add (amount_required,
312 TALER_amount_ntoh (dki->issue.fee_withdraw)); 303 TALER_amount_ntoh (dki->issue.fee_withdraw));
313
314 if (0 < TALER_amount_cmp (amount_required, 304 if (0 < TALER_amount_cmp (amount_required,
315 TALER_amount_ntoh (reserve.balance))) 305 TALER_amount_ntoh (db_reserve.balance)))
316 return TALER_MINT_reply_json_pack (connection, 306 return TALER_MINT_reply_json_pack (connection,
317 MHD_HTTP_PAYMENT_REQUIRED, 307 MHD_HTTP_PAYMENT_REQUIRED,
318 "{s:s}", 308 "{s:s}",
319 "error", 309 "error",
320 "Insufficient funds"); 310 "Insufficient funds");
321 if (GNUNET_OK != 311
322 TALER_RSA_sign (dki->denom_priv, 312 db_reserve.balance = TALER_amount_hton
323 &wsrd.coin_envelope, 313 (TALER_amount_subtract (TALER_amount_ntoh (db_reserve.balance),
324 sizeof (struct TALER_RSA_BlindedSignaturePurpose), 314 amount_required));
325 &ev_sig)) 315
316 sig = GNUNET_CRYPTO_rsa_sign (dki->denom_priv,
317 blinded_msg,
318 blinded_msg_len);
319 if (NULL == sig)
326 { 320 {
327 // FIXME: return 'internal error'
328 GNUNET_break (0); 321 GNUNET_break (0);
329 return MHD_NO; 322 return TALER_MINT_reply_internal_error (connection,
323 "Internal error");
330 } 324 }
331 325
332 reserve.balance = TALER_amount_hton (TALER_amount_subtract (TALER_amount_ntoh (reserve.balance), 326 /* transaction start */
333 amount_required));
334 if (GNUNET_OK != 327 if (GNUNET_OK !=
335 TALER_MINT_DB_update_reserve (db_conn, 328 TALER_MINT_DB_update_reserve (db_conn,
336 &reserve, 329 &db_reserve,
337 GNUNET_YES)) 330 GNUNET_YES))
338 { 331 {
339 // FIXME: return 'internal error'
340 GNUNET_break (0); 332 GNUNET_break (0);
341 return MHD_NO; 333 return TALER_MINT_reply_internal_db_error (connection);
342 } 334 }
343
344 collectable.ev = wsrd.coin_envelope; 335 collectable.ev = wsrd.coin_envelope;
345 collectable.ev_sig = ev_sig; 336 collectable.sig = sig;
346 collectable.reserve_pub = wsrd.reserve_pub; 337 collectable.reserve_pub = wsrd.reserve_pub;
347 collectable.reserve_sig = wsrd.sig; 338 collectable.reserve_sig = wsrd.sig;
348 if (GNUNET_OK != 339 if (GNUNET_OK !=
349 TALER_MINT_DB_insert_collectable_blindcoin (db_conn, 340 TALER_MINT_DB_insert_collectable_blindcoin (db_conn,
341 &h_blind,
350 &collectable)) 342 &collectable))
351 { 343 {
352 // FIXME: return 'internal error'
353 GNUNET_break (0); 344 GNUNET_break (0);
354 return GNUNET_NO;; 345 GNUNET_CRYPTO_rsa_signature_free (sig);
346 return TALER_MINT_reply_internal_db_error (connection);
355 } 347 }
348 /* transaction end */
349 GNUNET_CRYPTO_rsa_signature_free (sig);
356 return TALER_MINT_reply_withdraw_sign_success (connection, 350 return TALER_MINT_reply_withdraw_sign_success (connection,
357 &collectable); 351 &collectable);
358} 352}
@@ -378,7 +372,7 @@ refresh_accept_denoms (struct MHD_Connection *connection,
378 const struct MintKeyState *key_state, 372 const struct MintKeyState *key_state,
379 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, 373 const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
380 unsigned int denom_pubs_count, 374 unsigned int denom_pubs_count,
381 const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pubs, 375 const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pubs,
382 struct TALER_Amount *r_amount) 376 struct TALER_Amount *r_amount)
383{ 377{
384 unsigned int i; 378 unsigned int i;
@@ -554,7 +548,7 @@ int
554TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection, 548TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
555 const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub, 549 const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
556 unsigned int num_new_denoms, 550 unsigned int num_new_denoms,
557 const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pubs, 551 const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pubs,
558 unsigned int coin_count, 552 unsigned int coin_count,
559 const struct TALER_CoinPublicInfo *coin_public_infos) 553 const struct TALER_CoinPublicInfo *coin_public_infos)
560{ 554{
@@ -821,10 +815,10 @@ helper_refresh_reveal_send_response (struct MHD_Connection *connection,
821{ 815{
822 int res; 816 int res;
823 unsigned int newcoin_index; 817 unsigned int newcoin_index;
824 struct TALER_RSA_Signature *sigs; 818 struct GNUNET_CRYPTO_rsa_Signature **sigs;
825 819
826 sigs = GNUNET_malloc (refresh_session->num_newcoins * 820 sigs = GNUNET_malloc (refresh_session->num_newcoins *
827 sizeof (struct TALER_RSA_Signature)); 821 sizeof (struct GNUNET_CRYPTO_rsa_Signature *));
828 for (newcoin_index = 0; newcoin_index < refresh_session->num_newcoins; newcoin_index++) 822 for (newcoin_index = 0; newcoin_index < refresh_session->num_newcoins; newcoin_index++)
829 { 823 {
830 res = TALER_MINT_DB_get_refresh_collectable (db_conn, 824 res = TALER_MINT_DB_get_refresh_collectable (db_conn,
@@ -984,10 +978,12 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
984 { 978 {
985 struct RefreshCommitCoin commit_coin; 979 struct RefreshCommitCoin commit_coin;
986 struct LinkData link_data; 980 struct LinkData link_data;
987 struct TALER_RSA_BlindedSignaturePurpose *coin_ev_check; 981 // struct BlindedSignaturePurpose *coin_ev_check;
988 struct GNUNET_CRYPTO_EcdsaPublicKey coin_pub; 982 struct GNUNET_CRYPTO_EcdsaPublicKey coin_pub;
989 struct TALER_RSA_BlindingKey *bkey; 983 struct GNUNET_CRYPTO_rsa_BlindingKey *bkey;
990 struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; 984 struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
985 char *buf;
986 size_t buf_len;
991 987
992 bkey = NULL; 988 bkey = NULL;
993 res = TALER_MINT_DB_get_refresh_commit_coin (db_conn, 989 res = TALER_MINT_DB_get_refresh_commit_coin (db_conn,
@@ -1011,7 +1007,8 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
1011 } 1007 }
1012 1008
1013 GNUNET_CRYPTO_ecdsa_key_get_public (&link_data.coin_priv, &coin_pub); 1009 GNUNET_CRYPTO_ecdsa_key_get_public (&link_data.coin_priv, &coin_pub);
1014 if (NULL == (bkey = TALER_RSA_blinding_key_decode (&link_data.bkey_enc))) 1010 if (NULL == (bkey = GNUNET_CRYPTO_rsa_blinding_key_decode (link_data.bkey_enc,
1011 link_data.bkey_enc_size)))
1015 { 1012 {
1016 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid blinding key\n"); 1013 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid blinding key\n");
1017 // FIXME: return error code! 1014 // FIXME: return error code!
@@ -1024,26 +1021,31 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
1024 // FIXME: return error code! 1021 // FIXME: return error code!
1025 return MHD_NO; 1022 return MHD_NO;
1026 } 1023 }
1027 if (NULL == (coin_ev_check = 1024 if (NULL == (buf_len =
1028 TALER_RSA_message_blind (&coin_pub, 1025 GNUNET_CRYPTO_rsa_blind (&h_msg,
1029 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
1030 bkey, 1026 bkey,
1031 &denom_pub))) 1027 denom_pub,
1028 &buf)))
1032 { 1029 {
1033 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "blind failed\n"); 1030 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "blind failed\n");
1034 // FIXME: return error code! 1031 // FIXME: return error code!
1035 return MHD_NO; 1032 return MHD_NO;
1036 } 1033 }
1037 1034
1038 if (0 != memcmp (&coin_ev_check, 1035 if ( (buf_len != commit_coin.coin_ev_size) ||
1039 &commit_coin.coin_ev, 1036 (0 != memcmp (buf,
1040 sizeof (struct TALER_RSA_BlindedSignaturePurpose))) 1037 commit_coin.coin_ev,
1038 buf_len)) )
1041 { 1039 {
1042 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "blind envelope does not match for kappa=%d, old=%d\n", 1040 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1041 "blind envelope does not match for kappa=%d, old=%d\n",
1043 (int) (i+off), (int) j); 1042 (int) (i+off), (int) j);
1044 // FIXME: return error code! 1043 // FIXME: return error code!
1044 GNUNET_free (buf);
1045 return MHD_NO; 1045 return MHD_NO;
1046 } 1046 }
1047 GNUNET_free (buf);
1048
1047 } 1049 }
1048 } 1050 }
1049 1051
@@ -1058,9 +1060,9 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
1058 for (j = 0; j < refresh_session.num_newcoins; j++) 1060 for (j = 0; j < refresh_session.num_newcoins; j++)
1059 { 1061 {
1060 struct RefreshCommitCoin commit_coin; 1062 struct RefreshCommitCoin commit_coin;
1061 struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; 1063 struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
1062 struct TALER_MINT_DenomKeyIssuePriv *dki; 1064 struct TALER_MINT_DenomKeyIssuePriv *dki;
1063 struct TALER_RSA_Signature ev_sig; 1065 struct GNUNET_CRYPTO_rsa_Signature *ev_sig;
1064 1066
1065 res = TALER_MINT_DB_get_refresh_commit_coin (db_conn, 1067 res = TALER_MINT_DB_get_refresh_commit_coin (db_conn,
1066 refresh_session_pub, 1068 refresh_session_pub,
@@ -1091,11 +1093,10 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
1091 // FIXME: return error code! 1093 // FIXME: return error code!
1092 return MHD_NO; 1094 return MHD_NO;
1093 } 1095 }
1094 if (GNUNET_OK != 1096 ev_sig = GNUNET_CRYPTO_rsa_sign (dki->denom_priv,
1095 TALER_RSA_sign (dki->denom_priv, 1097 commit_coin.coin_ev,
1096 &commit_coin.coin_ev, 1098 commit_coin.coin_ev_len);
1097 sizeof (struct TALER_RSA_BlindedSignaturePurpose), 1099 if (NULL == ev_sig)
1098 &ev_sig))
1099 { 1100 {
1100 GNUNET_break (0); 1101 GNUNET_break (0);
1101 // FIXME: return error code! 1102 // FIXME: return error code!
@@ -1144,25 +1145,33 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
1144static int 1145static int
1145link_iter (void *cls, 1146link_iter (void *cls,
1146 const struct LinkDataEnc *link_data_enc, 1147 const struct LinkDataEnc *link_data_enc,
1147 const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub, 1148 const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub,
1148 const struct TALER_RSA_Signature *ev_sig) 1149 const struct GNUNET_CRYPTO_rsa_Signature *ev_sig)
1149{ 1150{
1150 json_t *list = cls; 1151 json_t *list = cls;
1151 json_t *obj = json_object (); 1152 json_t *obj = json_object ();
1153 char *buf;
1154 size_t buf_len;
1155
1152 1156
1153 json_array_append_new (list, obj); 1157 json_array_append_new (list, obj);
1154 1158
1155 json_object_set_new (obj, "link_enc", 1159 json_object_set_new (obj, "link_enc",
1156 TALER_JSON_from_data (link_data_enc, 1160 TALER_JSON_from_data (link_data_enc,
1157 sizeof (struct LinkDataEnc))); 1161 sizeof (struct LinkDataEnc)));
1158 1162
1163 buf_len = GNUNET_CRYPTO_rsa_public_key_encode (denom_pub,
1164 &buf);
1159 json_object_set_new (obj, "denom_pub", 1165 json_object_set_new (obj, "denom_pub",
1160 TALER_JSON_from_data (denom_pub, 1166 TALER_JSON_from_data (buf,
1161 sizeof (struct TALER_RSA_PublicKeyBinaryEncoded))); 1167 buf_len));
1162 1168 GNUNET_free (buf);
1169 buf_len = GNUNET_CRYPTO_rsa_signature_encode (ev_sig,
1170 &buf);
1163 json_object_set_new (obj, "ev_sig", 1171 json_object_set_new (obj, "ev_sig",
1164 TALER_JSON_from_data (ev_sig, 1172 TALER_JSON_from_data (buf,
1165 sizeof (struct TALER_RSA_Signature))); 1173 buf_len));
1174 GNUNET_free (buf_len);
1166 1175
1167 return GNUNET_OK; 1176 return GNUNET_OK;
1168} 1177}
diff --git a/src/mint/taler-mint-httpd_db.h b/src/mint/taler-mint-httpd_db.h
index 2a03812aa..dd82cbcb1 100644
--- a/src/mint/taler-mint-httpd_db.h
+++ b/src/mint/taler-mint-httpd_db.h
@@ -25,7 +25,6 @@
25#include <microhttpd.h> 25#include <microhttpd.h>
26#include <gnunet/gnunet_util_lib.h> 26#include <gnunet/gnunet_util_lib.h>
27#include "taler_util.h" 27#include "taler_util.h"
28#include "taler_rsa.h"
29#include "taler-mint-httpd_keys.h" 28#include "taler-mint-httpd_keys.h"
30#include "mint.h" 29#include "mint.h"
31 30
@@ -62,12 +61,20 @@ TALER_MINT_db_execute_withdraw_status (struct MHD_Connection *connection,
62 * Execute a /withdraw/sign. 61 * Execute a /withdraw/sign.
63 * 62 *
64 * @param connection the MHD connection to handle 63 * @param connection the MHD connection to handle
65 * @param wsrd details about the withdraw request 64 * @param reserve public key of the reserve
65 * @param denomination_pub public key of the denomination requested
66 * @param blinded_msg blinded message to be signed
67 * @param blinded_msg_len number of bytes in @a blinded_msg
68 * @param signature signature over the withdraw request, to be stored in DB
66 * @return MHD result code 69 * @return MHD result code
67 */ 70 */
68int 71int
69TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection, 72TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,
70 const struct TALER_WithdrawRequest *wsrd); 73 const struct GNUNET_CRYPTO_EddsaPublicKey *reserve,
74 const struct GNUNET_CRYPTO_rsa_PublicKey *denomination_pub,
75 const char *blinded_msg,
76 size_t blinded_msg_len,
77 const struct GNUNET_CRYPTO_EddsaSignature *signature);
71 78
72 79
73 80
@@ -86,7 +93,7 @@ int
86TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection, 93TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
87 const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub, 94 const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
88 unsigned int num_new_denoms, 95 unsigned int num_new_denoms,
89 const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pubs, 96 const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pubs,
90 unsigned int coin_count, 97 unsigned int coin_count,
91 const struct TALER_CoinPublicInfo *coin_public_infos); 98 const struct TALER_CoinPublicInfo *coin_public_infos);
92 99
diff --git a/src/mint/taler-mint-httpd_deposit.c b/src/mint/taler-mint-httpd_deposit.c
index c4f4718e3..6eeb3bff1 100644
--- a/src/mint/taler-mint-httpd_deposit.c
+++ b/src/mint/taler-mint-httpd_deposit.c
@@ -36,7 +36,6 @@
36#include "mint.h" 36#include "mint.h"
37#include "mint_db.h" 37#include "mint_db.h"
38#include "taler_signatures.h" 38#include "taler_signatures.h"
39#include "taler_rsa.h"
40#include "taler_json_lib.h" 39#include "taler_json_lib.h"
41#include "taler-mint-httpd_parsing.h" 40#include "taler-mint-httpd_parsing.h"
42#include "taler-mint-httpd_keys.h" 41#include "taler-mint-httpd_keys.h"
diff --git a/src/mint/taler-mint-httpd_keys.c b/src/mint/taler-mint-httpd_keys.c
index aa1e2c6e6..24851575a 100644
--- a/src/mint/taler-mint-httpd_keys.c
+++ b/src/mint/taler-mint-httpd_keys.c
@@ -32,7 +32,6 @@
32#include <pthread.h> 32#include <pthread.h>
33#include "mint.h" 33#include "mint.h"
34#include "taler_signatures.h" 34#include "taler_signatures.h"
35#include "taler_rsa.h"
36#include "taler_json_lib.h" 35#include "taler_json_lib.h"
37#include "taler-mint-httpd_parsing.h" 36#include "taler-mint-httpd_parsing.h"
38#include "taler-mint-httpd_keys.h" 37#include "taler-mint-httpd_keys.h"
@@ -66,14 +65,23 @@ static int reload_pipe[2];
66static json_t * 65static json_t *
67denom_key_issue_to_json (const struct TALER_MINT_DenomKeyIssue *dki) 66denom_key_issue_to_json (const struct TALER_MINT_DenomKeyIssue *dki)
68{ 67{
68 char *buf;
69 size_t buf_len;
69 json_t *dk_json = json_object (); 70 json_t *dk_json = json_object ();
71
70 json_object_set_new (dk_json, "master_sig", 72 json_object_set_new (dk_json, "master_sig",
71 TALER_JSON_from_data (&dki->signature, sizeof (struct GNUNET_CRYPTO_EddsaSignature))); 73 TALER_JSON_from_data (&dki->signature, sizeof (struct GNUNET_CRYPTO_EddsaSignature)));
72 json_object_set_new (dk_json, "stamp_start", TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->start))); 74 json_object_set_new (dk_json, "stamp_start", TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->start)));
73 json_object_set_new (dk_json, "stamp_expire_withdraw", TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->expire_withdraw))); 75 json_object_set_new (dk_json, "stamp_expire_withdraw", TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->expire_withdraw)));
74 json_object_set_new (dk_json, "stamp_expire_deposit", TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->expire_spend))); 76 json_object_set_new (dk_json, "stamp_expire_deposit", TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->expire_spend)));
77
78
79 buf_len = GNUNET_CRYPTO_rsa_public_key_encode (dki->denom_pub,
80 &buf);
75 json_object_set_new (dk_json, "denom_pub", 81 json_object_set_new (dk_json, "denom_pub",
76 TALER_JSON_from_data (&dki->denom_pub, sizeof (struct TALER_RSA_PublicKeyBinaryEncoded))); 82 TALER_JSON_from_data (buf,
83 buf_len));
84 GNUNET_free (buf);
77 json_object_set_new (dk_json, "value", 85 json_object_set_new (dk_json, "value",
78 TALER_JSON_from_amount (TALER_amount_ntoh (dki->value))); 86 TALER_JSON_from_amount (TALER_amount_ntoh (dki->value)));
79 json_object_set_new (dk_json, 87 json_object_set_new (dk_json,
@@ -341,14 +349,19 @@ TALER_MINT_key_state_acquire (void)
341 */ 349 */
342struct TALER_MINT_DenomKeyIssuePriv * 350struct TALER_MINT_DenomKeyIssuePriv *
343TALER_MINT_get_denom_key (const struct MintKeyState *key_state, 351TALER_MINT_get_denom_key (const struct MintKeyState *key_state,
344 const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub) 352 const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub)
345{ 353{
346 struct TALER_MINT_DenomKeyIssuePriv *issue; 354 struct TALER_MINT_DenomKeyIssuePriv *issue;
347 struct GNUNET_HashCode hash; 355 struct GNUNET_HashCode hash;
356 char *buf;
357 size_t buf_len;
348 358
349 GNUNET_CRYPTO_hash (denom_pub, 359 buf_len = GNUNET_CRYPTO_rsa_public_key_encode (denom_pub,
350 sizeof (struct TALER_RSA_PublicKeyBinaryEncoded), 360 *buf);
361 GNUNET_CRYPTO_hash (buf,
362 buf_len,
351 &hash); 363 &hash);
364 GNUNET_free (buf);
352 issue = GNUNET_CONTAINER_multihashmap_get (key_state->denomkey_map, &hash); 365 issue = GNUNET_CONTAINER_multihashmap_get (key_state->denomkey_map, &hash);
353 return issue; 366 return issue;
354} 367}
@@ -373,10 +386,10 @@ TALER_MINT_test_coin_valid (const struct MintKeyState *key_state,
373 dki = TALER_MINT_get_denom_key (key_state, &coin_public_info->denom_pub); 386 dki = TALER_MINT_get_denom_key (key_state, &coin_public_info->denom_pub);
374 if (NULL == dki) 387 if (NULL == dki)
375 return GNUNET_NO; 388 return GNUNET_NO;
376 if (GNUNET_OK != TALER_RSA_verify (&coin_public_info->coin_pub, 389 if (GNUNET_OK !=
377 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), 390 GNUNET_CRYPTO_rsa_verify (&c_hash,
378 &coin_public_info->denom_sig, 391 coin_public_info->denom_sig,
379 &dki->issue.denom_pub)) 392 dki->issue.denom_pub))
380 { 393 {
381 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 394 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
382 "coin signature is invalid\n"); 395 "coin signature is invalid\n");
diff --git a/src/mint/taler-mint-httpd_keys.h b/src/mint/taler-mint-httpd_keys.h
index cef0ac950..596350345 100644
--- a/src/mint/taler-mint-httpd_keys.h
+++ b/src/mint/taler-mint-httpd_keys.h
@@ -107,7 +107,7 @@ TALER_MINT_key_state_acquire (void);
107 */ 107 */
108struct TALER_MINT_DenomKeyIssuePriv * 108struct TALER_MINT_DenomKeyIssuePriv *
109TALER_MINT_get_denom_key (const struct MintKeyState *key_state, 109TALER_MINT_get_denom_key (const struct MintKeyState *key_state,
110 const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub); 110 const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub);
111 111
112 112
113/** 113/**
@@ -116,9 +116,9 @@ TALER_MINT_get_denom_key (const struct MintKeyState *key_state,
116 * 116 *
117 * @param key_state the key state to use for checking the coin's validity 117 * @param key_state the key state to use for checking the coin's validity
118 * @param coin_public_info the coin public info to check for validity 118 * @param coin_public_info the coin public info to check for validity
119 * @return GNUNET_YES if the coin is valid, 119 * @return #GNUNET_YES if the coin is valid,
120 * GNUNET_NO if it is invalid 120 * #GNUNET_NO if it is invalid
121 * GNUNET_SYSERROR if an internal error occured 121 * #GNUNET_SYSERROR if an internal error occured
122 */ 122 */
123int 123int
124TALER_MINT_test_coin_valid (const struct MintKeyState *key_state, 124TALER_MINT_test_coin_valid (const struct MintKeyState *key_state,
@@ -129,7 +129,7 @@ TALER_MINT_test_coin_valid (const struct MintKeyState *key_state,
129 * Read signals from a pipe in a loop, and reload keys from disk if 129 * Read signals from a pipe in a loop, and reload keys from disk if
130 * SIGUSR1 is read from the pipe. 130 * SIGUSR1 is read from the pipe.
131 * 131 *
132 * @return GNUNET_OK if we terminated normally, GNUNET_SYSERR on error 132 * @return #GNUNET_OK if we terminated normally, #GNUNET_SYSERR on error
133 */ 133 */
134int 134int
135TALER_MINT_key_reload_loop (void); 135TALER_MINT_key_reload_loop (void);
diff --git a/src/mint/taler-mint-httpd_parsing.c b/src/mint/taler-mint-httpd_parsing.c
index 56744c6b0..c4e28bba7 100644
--- a/src/mint/taler-mint-httpd_parsing.c
+++ b/src/mint/taler-mint-httpd_parsing.c
@@ -553,22 +553,29 @@ TALER_MINT_parse_json_data (struct MHD_Connection *connection,
553{ 553{
554 unsigned int i; 554 unsigned int i;
555 int ret; 555 int ret;
556 void *ptr;
556 557
557 ret = GNUNET_YES; 558 ret = GNUNET_YES;
558 for (i=0; NULL != spec[i].field_name; i++) 559 for (i=0; NULL != spec[i].field_name; i++)
559 { 560 {
560 if (0 == spec[i].destination_size_in) 561 if (0 == spec[i].destination_size_in)
562 {
563 ptr = NULL;
561 parse_variable_json_data (connection, root, 564 parse_variable_json_data (connection, root,
562 spec[i].field_name, 565 spec[i].field_name,
563 (void **) spec[i].destination, 566 &ptr,
564 &spec[i].destination_size_out, 567 &spec[i].destination_size_out,
565 &ret); 568 &ret);
569 spec[i].destination = ptr;
570 }
566 else 571 else
572 {
567 parse_fixed_json_data (connection, root, 573 parse_fixed_json_data (connection, root,
568 spec[i].field_name, 574 spec[i].field_name,
569 spec[i].destination, 575 spec[i].destination,
570 spec[i].destination_size_in, 576 spec[i].destination_size_in,
571 &ret); 577 &ret);
578 }
572 } 579 }
573 if (GNUNET_YES != ret) 580 if (GNUNET_YES != ret)
574 TALER_MINT_release_parsed_data (spec); 581 TALER_MINT_release_parsed_data (spec);
@@ -641,4 +648,63 @@ TALER_MINT_mhd_request_arg_data (struct MHD_Connection *connection,
641 return GNUNET_OK; 648 return GNUNET_OK;
642} 649}
643 650
651
652/**
653 * Extraxt variable-size base32crockford encoded data from request.
654 *
655 * Queues an error response to the connection if the parameter is missing
656 * or the encoding is invalid.
657 *
658 * @param connection the MHD connection
659 * @param param_name the name of the parameter with the key
660 * @param[out] out_data pointer to allocate buffer and store the result
661 * @param[out] out_size set to the size of the buffer allocated in @a out_data
662 * @return
663 * #GNUNET_YES if the the argument is present
664 * #GNUNET_NO if the argument is absent or malformed
665 * #GNUNET_SYSERR on internal error (error response could not be sent)
666 */
667int
668TALER_MINT_mhd_request_var_arg_data (struct MHD_Connection *connection,
669 const char *param_name,
670 void **out_data,
671 size_t *out_size)
672{
673 const char *str;
674 size_t slen;
675 size_t olen;
676 void *out;
677
678 str = MHD_lookup_connection_value (connection,
679 MHD_GET_ARGUMENT_KIND,
680 param_name);
681 if (NULL == str)
682 {
683 return (MHD_NO ==
684 TALER_MINT_reply_arg_missing (connection, param_name))
685 ? GNUNET_SYSERR : GNUNET_NO;
686 }
687 slen = strlen (str);
688 olen = (slen * 5) / 8;
689 out = GNUNET_malloc (olen);
690 if (GNUNET_OK !=
691 GNUNET_STRINGS_string_to_data (str,
692 strlen (str),
693 out,
694 olen))
695 {
696 GNUNET_free (out);
697 *out_size = 0;
698 return (MHD_NO ==
699 TALER_MINT_reply_arg_invalid (connection, param_name))
700 ? GNUNET_SYSERR : GNUNET_NO;
701 }
702 *out_data = out;
703 *out_size = olen;
704 return GNUNET_OK;
705
706}
707
708
709
644/* end of taler-mint-httpd_parsing.c */ 710/* end of taler-mint-httpd_parsing.c */
diff --git a/src/mint/taler-mint-httpd_parsing.h b/src/mint/taler-mint-httpd_parsing.h
index 59c31f595..5f5f35dfc 100644
--- a/src/mint/taler-mint-httpd_parsing.h
+++ b/src/mint/taler-mint-httpd_parsing.h
@@ -209,9 +209,8 @@ TALER_MINT_release_parsed_data (struct GNUNET_MINT_ParseFieldSpec *spec);
209 * Generate line in parser specification for variable-size value. 209 * Generate line in parser specification for variable-size value.
210 * 210 *
211 * @param field name of the field 211 * @param field name of the field
212 * @param value where to store the value
213 */ 212 */
214#define TALER_MINT_PARSE_VARIABLE(field,value) { field, &value, 0, 0 } 213#define TALER_MINT_PARSE_VARIABLE(field) { field, NULL, 0, 0 }
215 214
216/** 215/**
217 * Generate line in parser specification indicating the end of the spec. 216 * Generate line in parser specification indicating the end of the spec.
@@ -220,7 +219,7 @@ TALER_MINT_release_parsed_data (struct GNUNET_MINT_ParseFieldSpec *spec);
220 219
221 220
222/** 221/**
223 * Extraxt base32crockford encoded data from request. 222 * Extraxt fixed-size base32crockford encoded data from request.
224 * 223 *
225 * Queues an error response to the connection if the parameter is missing or 224 * Queues an error response to the connection if the parameter is missing or
226 * invalid. 225 * invalid.
@@ -241,6 +240,28 @@ TALER_MINT_mhd_request_arg_data (struct MHD_Connection *connection,
241 size_t out_size); 240 size_t out_size);
242 241
243 242
243/**
244 * Extraxt variable-size base32crockford encoded data from request.
245 *
246 * Queues an error response to the connection if the parameter is missing
247 * or the encoding is invalid.
248 *
249 * @param connection the MHD connection
250 * @param param_name the name of the parameter with the key
251 * @param[out] out_data pointer to allocate buffer and store the result
252 * @param[out] out_size set to the size of the buffer allocated in @a out_data
253 * @return
254 * #GNUNET_YES if the the argument is present
255 * #GNUNET_NO if the argument is absent or malformed
256 * #GNUNET_SYSERR on internal error (error response could not be sent)
257 */
258int
259TALER_MINT_mhd_request_var_arg_data (struct MHD_Connection *connection,
260 const char *param_name,
261 void **out_data,
262 size_t *out_size);
263
264
244 265
245 266
246#endif /* TALER_MICROHTTPD_LIB_H_ */ 267#endif /* TALER_MICROHTTPD_LIB_H_ */
diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c
index 69ba87c29..40737ae31 100644
--- a/src/mint/taler-mint-httpd_refresh.c
+++ b/src/mint/taler-mint-httpd_refresh.c
@@ -34,7 +34,6 @@
34#include "mint.h" 34#include "mint.h"
35#include "mint_db.h" 35#include "mint_db.h"
36#include "taler_signatures.h" 36#include "taler_signatures.h"
37#include "taler_rsa.h"
38#include "taler_json_lib.h" 37#include "taler_json_lib.h"
39#include "taler-mint-httpd_parsing.h" 38#include "taler-mint-httpd_parsing.h"
40#include "taler-mint-httpd_keys.h" 39#include "taler-mint-httpd_keys.h"
@@ -94,7 +93,7 @@ check_confirm_signature (struct MHD_Connection *connection,
94 * @param connection the connection to send error responses to 93 * @param connection the connection to send error responses to
95 * @param root the JSON object to extract the coin info from 94 * @param root the JSON object to extract the coin info from
96 * @return #GNUNET_YES if coin public info in JSON was valid 95 * @return #GNUNET_YES if coin public info in JSON was valid
97 * #GNUNET_NO otherwise 96 * #GNUNET_NO JSON was invalid, response was generated
98 * #GNUNET_SYSERR on internal error 97 * #GNUNET_SYSERR on internal error
99 */ 98 */
100static int 99static int
@@ -103,33 +102,38 @@ request_json_require_coin_public_info (struct MHD_Connection *connection,
103 struct TALER_CoinPublicInfo *r_public_info) 102 struct TALER_CoinPublicInfo *r_public_info)
104{ 103{
105 int ret; 104 int ret;
106 105 struct GNUNET_CRYPTO_rsa_Signature *sig;
107 GNUNET_assert (NULL != root); 106 struct GNUNET_CRYPTO_rsa_PublicKey *pk;
108 107 struct GNUNET_MINT_ParseFieldSpec spec[] =
109 ret = GNUNET_MINT_parse_navigate_json (connection, root, 108 {
110 JNAV_FIELD, "coin_pub", 109 TALER_MINT_PARSE_FIXED("coin_pub", &r_public_info->coin_pub),
111 JNAV_RET_DATA, 110 TALER_MINT_PARSE_VARIABLE("denom_sig"),
112 &r_public_info->coin_pub, 111 TALER_MINT_PARSE_VARIABLE("denom_pub"),
113 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); 112 TALER_MINT_PARSE_END
114 if (GNUNET_OK != ret) 113 };
115 return ret; 114
116 115 ret = TALER_MINT_parse_json_data (connection,
117 ret = GNUNET_MINT_parse_navigate_json (connection, root, 116 root,
118 JNAV_FIELD, "denom_sig", 117 spec);
119 JNAV_RET_DATA,
120 &r_public_info->denom_sig,
121 sizeof (struct TALER_RSA_Signature));
122 if (GNUNET_OK != ret)
123 return ret;
124
125 ret = GNUNET_MINT_parse_navigate_json (connection, root,
126 JNAV_FIELD, "denom_pub",
127 JNAV_RET_DATA,
128 &r_public_info->denom_pub,
129 sizeof (struct TALER_RSA_PublicKeyBinaryEncoded));
130 if (GNUNET_OK != ret) 118 if (GNUNET_OK != ret)
131 return ret; 119 return ret;
132 120 sig = GNUNET_CRYPTO_rsa_signature_decode (spec[1].destination,
121 spec[1].destination_size_out);
122 pk = GNUNET_CRYPTO_rsa_public_key_decode (spec[2].destination,
123 spec[2].destination_size_out);
124 TALER_MINT_release_parsed_data (spec);
125 if ( (NULL == pk) ||
126 (NULL == sig) )
127 {
128 if (NULL != sig)
129 GNUNET_CRYPTO_rsa_signature_free (sig);
130 if (NULL != pk)
131 GNUNET_CRYPTO_rsa_public_key_free (pk);
132 // FIXME: send error reply...
133 return GNUNET_NO;
134 }
135 r_public_info->denom_sig = sig;
136 r_public_info->denom_pub = pk;
133 return GNUNET_OK; 137 return GNUNET_OK;
134} 138}
135 139
@@ -247,7 +251,7 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
247 json_t *new_denoms; 251 json_t *new_denoms;
248 unsigned int num_new_denoms; 252 unsigned int num_new_denoms;
249 unsigned int i; 253 unsigned int i;
250 struct TALER_RSA_PublicKeyBinaryEncoded *denom_pubs; 254 struct GNUNET_CRYPTO_rsa_PublicKey *denom_pubs;
251 json_t *melt_coins; 255 json_t *melt_coins;
252 struct TALER_CoinPublicInfo *coin_public_infos; 256 struct TALER_CoinPublicInfo *coin_public_infos;
253 unsigned int coin_count; 257 unsigned int coin_count;
@@ -256,6 +260,8 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
256 struct MintKeyState *key_state; 260 struct MintKeyState *key_state;
257 struct RefreshMeltSignatureBody body; 261 struct RefreshMeltSignatureBody body;
258 json_t *melt_sig_json; 262 json_t *melt_sig_json;
263 char *buf;
264 size_t buf_size;
259 265
260 res = TALER_MINT_parse_post_json (connection, 266 res = TALER_MINT_parse_post_json (connection,
261 connection_cls, 267 connection_cls,
@@ -291,23 +297,31 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
291 return res; 297 return res;
292 num_new_denoms = json_array_size (new_denoms); 298 num_new_denoms = json_array_size (new_denoms);
293 denom_pubs = GNUNET_malloc (num_new_denoms * 299 denom_pubs = GNUNET_malloc (num_new_denoms *
294 sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)); 300 sizeof (struct GNUNET_CRYPTO_rsa_PublicKey *));
295 301
296 for (i=0;i<num_new_denoms;i++) 302 for (i=0;i<num_new_denoms;i++)
297 { 303 {
298 res = GNUNET_MINT_parse_navigate_json (connection, root, 304 res = GNUNET_MINT_parse_navigate_json (connection, root,
299 JNAV_FIELD, "new_denoms", 305 JNAV_FIELD, "new_denoms",
300 JNAV_INDEX, (int) i, 306 JNAV_INDEX, (int) i,
301 JNAV_RET_DATA, 307 JNAV_RET_DATA_VAR,
302 &denom_pubs[i], 308 &buf,
303 sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)); 309 &buf_size);
304
305 if (GNUNET_OK != res) 310 if (GNUNET_OK != res)
306 { 311 {
307 GNUNET_free (denom_pubs); 312 GNUNET_free (denom_pubs);
308 /* FIXME: proper cleanup! */ 313 /* FIXME: proper cleanup! */
309 return res; 314 return res;
310 } 315 }
316 denom_pubs[i] = GNUNET_CRYPTO_rsa_public_key_decode (buf, buf_size);
317 GNUNET_free (buf);
318 if (NULL == denom_pubs[i])
319 {
320 GNUNET_free (denom_pubs);
321 /* FIXME: proper cleanup! */
322 /* FIXME: generate error reply */
323 return GNUNET_SYSERR;
324 }
311 } 325 }
312 326
313 res = GNUNET_MINT_parse_navigate_json (connection, root, 327 res = GNUNET_MINT_parse_navigate_json (connection, root,
@@ -377,9 +391,14 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
377 /* check that signature from the session public key is ok */ 391 /* check that signature from the session public key is ok */
378 hash_context = GNUNET_CRYPTO_hash_context_start (); 392 hash_context = GNUNET_CRYPTO_hash_context_start ();
379 for (i = 0; i < num_new_denoms; i++) 393 for (i = 0; i < num_new_denoms; i++)
394 {
395 buf_size = GNUNET_CRYPTO_rsa_public_key_encode (denom_pubs[i],
396 &buf);
380 GNUNET_CRYPTO_hash_context_read (hash_context, 397 GNUNET_CRYPTO_hash_context_read (hash_context,
381 &denom_pubs[i], 398 buf,
382 sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)); 399 buf_size);
400 GNUNET_free (buf);
401 }
383 for (i = 0; i < coin_count; i++) 402 for (i = 0; i < coin_count; i++)
384 GNUNET_CRYPTO_hash_context_read (hash_context, 403 GNUNET_CRYPTO_hash_context_read (hash_context,
385 &coin_public_infos[i].coin_pub, 404 &coin_public_infos[i].coin_pub,
@@ -526,9 +545,9 @@ TALER_MINT_handler_refresh_commit (struct RequestHandler *rh,
526 JNAV_FIELD, "coin_evs", 545 JNAV_FIELD, "coin_evs",
527 JNAV_INDEX, (int) i, 546 JNAV_INDEX, (int) i,
528 JNAV_INDEX, (int) j, 547 JNAV_INDEX, (int) j,
529 JNAV_RET_DATA, 548 JNAV_RET_DATA_VAR,
530 commit_coin[i][j].coin_ev, 549 &commit_coin[i][j].coin_ev,
531 sizeof (struct TALER_RSA_BlindedSignaturePurpose)); 550 &commit_coin[i][j].coin_ev_size);
532 551
533 if (GNUNET_OK != res) 552 if (GNUNET_OK != res)
534 { 553 {
@@ -539,8 +558,8 @@ TALER_MINT_handler_refresh_commit (struct RequestHandler *rh,
539 } 558 }
540 559
541 GNUNET_CRYPTO_hash_context_read (hash_context, 560 GNUNET_CRYPTO_hash_context_read (hash_context,
542 &commit_coin[i][j].coin_ev, 561 commit_coin[i][j].coin_ev,
543 sizeof (struct TALER_RSA_BlindedSignaturePurpose)); 562 commit_coin[i][j].coin_ev_size);
544 563
545 res = GNUNET_MINT_parse_navigate_json (connection, root, 564 res = GNUNET_MINT_parse_navigate_json (connection, root,
546 JNAV_FIELD, "link_encs", 565 JNAV_FIELD, "link_encs",
diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c
index 75342cd2d..92bde3c70 100644
--- a/src/mint/taler-mint-httpd_responses.c
+++ b/src/mint/taler-mint-httpd_responses.c
@@ -295,10 +295,15 @@ TALER_MINT_reply_withdraw_sign_success (struct MHD_Connection *connection,
295 const struct CollectableBlindcoin *collectable) 295 const struct CollectableBlindcoin *collectable)
296{ 296{
297 json_t *root = json_object (); 297 json_t *root = json_object ();
298 size_t sig_buf_size;
299 char *sig_buf;
298 300
301 sig_buf_size = GNUNET_CRYPTO_rsa_signature_encode (collectable->sig,
302 &sig_buf);
299 json_object_set_new (root, "ev_sig", 303 json_object_set_new (root, "ev_sig",
300 TALER_JSON_from_data (&collectable->ev_sig, 304 TALER_JSON_from_data (sig_buf,
301 sizeof (struct TALER_RSA_Signature))); 305 sig_buf_size));
306 GNUNET_free (sig_buf);
302 return TALER_MINT_reply_json (connection, 307 return TALER_MINT_reply_json (connection,
303 root, 308 root,
304 MHD_HTTP_OK); 309 MHD_HTTP_OK);
@@ -388,19 +393,26 @@ TALER_MINT_reply_refresh_commit_success (struct MHD_Connection *connection,
388int 393int
389TALER_MINT_reply_refresh_reveal_success (struct MHD_Connection *connection, 394TALER_MINT_reply_refresh_reveal_success (struct MHD_Connection *connection,
390 unsigned int num_newcoins, 395 unsigned int num_newcoins,
391 const struct TALER_RSA_Signature *sigs) 396 const struct GNUNET_CRYPTO_rsa_Signature *sigs)
392{ 397{
393 int newcoin_index; 398 int newcoin_index;
394 json_t *root; 399 json_t *root;
395 json_t *list; 400 json_t *list;
401 char *buf;
402 size_t buf_size;
396 403
397 root = json_object (); 404 root = json_object ();
398 list = json_array (); 405 list = json_array ();
399 json_object_set_new (root, "ev_sigs", list); 406 json_object_set_new (root, "ev_sigs", list);
400 for (newcoin_index = 0; newcoin_index < num_newcoins; newcoin_index++) 407 for (newcoin_index = 0; newcoin_index < num_newcoins; newcoin_index++)
408 {
409 buf_size = GNUNET_CRYPTO_rsa_signature_encode (&sigs[newcoin_index],
410 &buf);
401 json_array_append_new (list, 411 json_array_append_new (list,
402 TALER_JSON_from_data (&sigs[newcoin_index], 412 TALER_JSON_from_data (buf,
403 sizeof (struct TALER_RSA_Signature))); 413 buf_size));
414 GNUNET_free (buf);
415 }
404 return TALER_MINT_reply_json (connection, 416 return TALER_MINT_reply_json (connection,
405 root, 417 root,
406 MHD_HTTP_OK); 418 MHD_HTTP_OK);
diff --git a/src/mint/taler-mint-httpd_responses.h b/src/mint/taler-mint-httpd_responses.h
index 11e916f16..f92101ff7 100644
--- a/src/mint/taler-mint-httpd_responses.h
+++ b/src/mint/taler-mint-httpd_responses.h
@@ -209,7 +209,7 @@ TALER_MINT_reply_refresh_melt_success (struct MHD_Connection *connection,
209int 209int
210TALER_MINT_reply_refresh_reveal_success (struct MHD_Connection *connection, 210TALER_MINT_reply_refresh_reveal_success (struct MHD_Connection *connection,
211 unsigned int num_newcoins, 211 unsigned int num_newcoins,
212 const struct TALER_RSA_Signature *sigs); 212 const struct GNUNET_CRYPTO_rsa_Signature *sigs);
213 213
214 214
215 215
diff --git a/src/mint/taler-mint-httpd_withdraw.c b/src/mint/taler-mint-httpd_withdraw.c
index 5259c7fbf..1cf410910 100644
--- a/src/mint/taler-mint-httpd_withdraw.c
+++ b/src/mint/taler-mint-httpd_withdraw.c
@@ -32,7 +32,6 @@
32#include "mint.h" 32#include "mint.h"
33#include "mint_db.h" 33#include "mint_db.h"
34#include "taler_signatures.h" 34#include "taler_signatures.h"
35#include "taler_rsa.h"
36#include "taler_json_lib.h" 35#include "taler_json_lib.h"
37#include "taler-mint-httpd_parsing.h" 36#include "taler-mint-httpd_parsing.h"
38#include "taler-mint-httpd_keys.h" 37#include "taler-mint-httpd_keys.h"
@@ -94,6 +93,12 @@ TALER_MINT_handler_withdraw_sign (struct RequestHandler *rh,
94{ 93{
95 struct TALER_WithdrawRequest wsrd; 94 struct TALER_WithdrawRequest wsrd;
96 int res; 95 int res;
96 const struct GNUNET_CRYPTO_rsa_PublicKey *denomination_pub;
97 char *denomination_pub_data;
98 size_t denomination_pub_data_size;
99 char *blinded_msg;
100 size_t blinded_msg_len;
101 const struct GNUNET_CRYPTO_EddsaSignature signature;
97 102
98 res = TALER_MINT_mhd_request_arg_data (connection, 103 res = TALER_MINT_mhd_request_arg_data (connection,
99 "reserve_pub", 104 "reserve_pub",
@@ -105,33 +110,66 @@ TALER_MINT_handler_withdraw_sign (struct RequestHandler *rh,
105 return MHD_YES; /* invalid request */ 110 return MHD_YES; /* invalid request */
106 111
107 /* FIXME: handle variable-size signing keys! */ 112 /* FIXME: handle variable-size signing keys! */
108 res = TALER_MINT_mhd_request_arg_data (connection, 113 res = TALER_MINT_mhd_request_var_arg_data (connection,
109 "denom_pub", 114 "denom_pub",
110 &wsrd.denomination_pub, 115 &denomination_pub_data,
111 sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)); 116 &denomination_pub_data_size);
112 if (GNUNET_SYSERR == res) 117 if (GNUNET_SYSERR == res)
113 return MHD_NO; /* internal error */ 118 return MHD_NO; /* internal error */
114 if (GNUNET_NO == res) 119 if (GNUNET_NO == res)
115 return MHD_YES; /* invalid request */ 120 return MHD_YES; /* invalid request */
116 res = TALER_MINT_mhd_request_arg_data (connection, 121 res = TALER_MINT_mhd_request_var_arg_data (connection,
117 "coin_ev", 122 "coin_ev",
118 &wsrd.coin_envelope, 123 &blinded_msg,
119 sizeof (struct TALER_RSA_Signature)); 124 &blinded_msg_len);
120 if (GNUNET_SYSERR == res) 125 if (GNUNET_SYSERR == res)
121 return MHD_NO; /* internal error */ 126 return MHD_NO; /* internal error */
122 if (GNUNET_NO == res) 127 if (GNUNET_NO == res)
123 return MHD_YES; /* invalid request */ 128 return MHD_YES; /* invalid request */
124 res = TALER_MINT_mhd_request_arg_data (connection, 129 res = TALER_MINT_mhd_request_arg_data (connection,
125 "reserve_sig", 130 "reserve_sig",
126 &wsrd.sig, 131 &signature,
127 sizeof (struct GNUNET_CRYPTO_EddsaSignature)); 132 sizeof (struct GNUNET_CRYPTO_EddsaSignature));
128 if (GNUNET_SYSERR == res) 133 if (GNUNET_SYSERR == res)
129 return MHD_NO; /* internal error */ 134 return MHD_NO; /* internal error */
130 if (GNUNET_NO == res) 135 if (GNUNET_NO == res)
131 return MHD_YES; /* invalid request */ 136 return MHD_YES; /* invalid request */
132 137
133 return TALER_MINT_db_execute_withdraw_sign (connection, 138 /* verify signature! */
134 &wsrd); 139 wsrd.purpose.size = htonl (sizeof (struct TALER_WithdrawRequest));
140 wsrd.purpose.type = htonl (TALER_SIGNATURE_WITHDRAW);
141 GNUNET_CRYPTO_hash (denomination_pub_data,
142 denomination_pub_data_size,
143 &wsrd.h_denomination_pub);
144 GNUNET_CRYPTO_hash (blinded_msg,
145 blinded_msg_len,
146 &wsrd.h_coin_envelope);
147 if (GNUNET_OK !=
148 GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WITHDRAW,
149 &wsrd.purpose,
150 &signature,
151 &wsrd.reserve_pub))
152 {
153 return 42; // FIXME: generate error reply
154 }
155 denomination_pub = GNUNET_CRYPTO_rsa_private_key_decode (denomination_pub_data,
156 denomination_pub_data_size);
157 if (NULL == denomination_pub)
158 {
159 GNUNET_free (denomination_pub_data);
160 GNUNET_free (blinded_msg);
161 return 42; // FIXME: generate error reply
162 }
163 res = TALER_MINT_db_execute_withdraw_sign (connection,
164 &wsrd.reserve_pub,
165 denomination_pub,
166 blinded_msg,
167 blinded_msg_len,
168 &signature);
169 GNUNET_free (denomination_pub_data);
170 GNUNET_free (blinded_msg);
171 GNUNET_CRYPTO_rsa_public_key_free (denomination_pub);
172 return res;
135} 173}
136 174
137/* end of taler-mint-httpd_withdraw.c */ 175/* end of taler-mint-httpd_withdraw.c */
diff --git a/src/mint/taler-mint-keyup.c b/src/mint/taler-mint-keyup.c
index 263618ade..c2a326566 100644
--- a/src/mint/taler-mint-keyup.c
+++ b/src/mint/taler-mint-keyup.c
@@ -105,7 +105,7 @@ static struct GNUNET_CRYPTO_EddsaPublicKey *master_pub;
105static struct GNUNET_TIME_Absolute lookahead_sign_stamp; 105static struct GNUNET_TIME_Absolute lookahead_sign_stamp;
106 106
107 107
108int 108static int
109config_get_denom (const char *section, const char *option, struct TALER_Amount *denom) 109config_get_denom (const char *section, const char *option, struct TALER_Amount *denom)
110{ 110{
111 char *str; 111 char *str;
@@ -117,7 +117,7 @@ config_get_denom (const char *section, const char *option, struct TALER_Amount *
117} 117}
118 118
119 119
120char * 120static char *
121get_signkey_dir () 121get_signkey_dir ()
122{ 122{
123 char *dir; 123 char *dir;
@@ -128,7 +128,7 @@ get_signkey_dir ()
128} 128}
129 129
130 130
131char * 131static char *
132get_signkey_file (struct GNUNET_TIME_Absolute start) 132get_signkey_file (struct GNUNET_TIME_Absolute start)
133{ 133{
134 char *dir; 134 char *dir;
@@ -140,13 +140,12 @@ get_signkey_file (struct GNUNET_TIME_Absolute start)
140} 140}
141 141
142 142
143
144/** 143/**
145 * Hash the data defining the coin type. 144 * Hash the data defining the coin type.
146 * Exclude information that may not be the same for all 145 * Exclude information that may not be the same for all
147 * instances of the coin type (i.e. the anchor, overlap). 146 * instances of the coin type (i.e. the anchor, overlap).
148 */ 147 */
149void 148static void
150hash_coin_type (const struct CoinTypeParams *p, struct GNUNET_HashCode *hash) 149hash_coin_type (const struct CoinTypeParams *p, struct GNUNET_HashCode *hash)
151{ 150{
152 struct CoinTypeNBO p_nbo; 151 struct CoinTypeNBO p_nbo;
@@ -254,7 +253,7 @@ get_anchor_iter (void *cls,
254 * @param overlap what's the overlap between the keys validity period? 253 * @param overlap what's the overlap between the keys validity period?
255 * @param[out] anchor the timestamp where the first new key should be generated 254 * @param[out] anchor the timestamp where the first new key should be generated
256 */ 255 */
257void 256static void
258get_anchor (const char *dir, 257get_anchor (const char *dir,
259 struct GNUNET_TIME_Relative duration, 258 struct GNUNET_TIME_Relative duration,
260 struct GNUNET_TIME_Relative overlap, 259 struct GNUNET_TIME_Relative overlap,
@@ -291,6 +290,7 @@ get_anchor (const char *dir,
291 // anchor is now the stamp where we need to create a new key 290 // anchor is now the stamp where we need to create a new key
292} 291}
293 292
293
294static void 294static void
295create_signkey_issue_priv (struct GNUNET_TIME_Absolute start, 295create_signkey_issue_priv (struct GNUNET_TIME_Absolute start,
296 struct GNUNET_TIME_Relative duration, 296 struct GNUNET_TIME_Relative duration,
@@ -327,7 +327,7 @@ check_signkey_valid (const char *signkey_filename)
327} 327}
328 328
329 329
330int 330static int
331mint_keys_update_signkeys () 331mint_keys_update_signkeys ()
332{ 332{
333 struct GNUNET_TIME_Relative signkey_duration; 333 struct GNUNET_TIME_Relative signkey_duration;
@@ -377,7 +377,7 @@ mint_keys_update_signkeys ()
377} 377}
378 378
379 379
380int 380static int
381get_cointype_params (const char *ct, struct CoinTypeParams *params) 381get_cointype_params (const char *ct, struct CoinTypeParams *params)
382{ 382{
383 const char *dir; 383 const char *dir;
@@ -434,8 +434,8 @@ static void
434create_denomkey_issue (struct CoinTypeParams *params, 434create_denomkey_issue (struct CoinTypeParams *params,
435 struct TALER_MINT_DenomKeyIssuePriv *dki) 435 struct TALER_MINT_DenomKeyIssuePriv *dki)
436{ 436{
437 GNUNET_assert (NULL != (dki->denom_priv = TALER_RSA_key_create ())); 437 GNUNET_assert (NULL != (dki->denom_priv = GNUNET_CRYPTO_rsa_private_key_create ()));
438 TALER_RSA_key_get_public (dki->denom_priv, &dki->issue.denom_pub); 438 dki->issue.denom_pub = GNUNET_CRYPTO_rsa_private_key_get_get_public (dki->denom_priv);
439 dki->issue.master = *master_pub; 439 dki->issue.master = *master_pub;
440 dki->issue.start = GNUNET_TIME_absolute_hton (params->anchor); 440 dki->issue.start = GNUNET_TIME_absolute_hton (params->anchor);
441 dki->issue.expire_withdraw = 441 dki->issue.expire_withdraw =
@@ -470,7 +470,7 @@ check_cointype_valid (const char *filename, struct CoinTypeParams *params)
470} 470}
471 471
472 472
473int 473static int
474mint_keys_update_cointype (const char *coin_alias) 474mint_keys_update_cointype (const char *coin_alias)
475{ 475{
476 struct CoinTypeParams p; 476 struct CoinTypeParams p;
@@ -496,7 +496,7 @@ mint_keys_update_cointype (const char *coin_alias)
496 printf ("Target path: %s\n", dkf); 496 printf ("Target path: %s\n", dkf);
497 create_denomkey_issue (&p, &denomkey_issue); 497 create_denomkey_issue (&p, &denomkey_issue);
498 ret = TALER_MINT_write_denom_key (dkf, &denomkey_issue); 498 ret = TALER_MINT_write_denom_key (dkf, &denomkey_issue);
499 TALER_RSA_key_free (denomkey_issue.denom_priv); 499 GNUNET_CRYPTO_rsa_private_key_free (denomkey_issue.denom_priv);
500 if (GNUNET_OK != ret) 500 if (GNUNET_OK != ret)
501 { 501 {
502 fprintf (stderr, "Can't write to file '%s'\n", dkf); 502 fprintf (stderr, "Can't write to file '%s'\n", dkf);
@@ -514,7 +514,7 @@ mint_keys_update_cointype (const char *coin_alias)
514} 514}
515 515
516 516
517int 517static int
518mint_keys_update_denomkeys () 518mint_keys_update_denomkeys ()
519{ 519{
520 char *coin_types; 520 char *coin_types;
@@ -659,4 +659,3 @@ main (int argc, char *const *argv)
659 return 1; 659 return 1;
660 return 0; 660 return 0;
661} 661}
662
diff --git a/src/mint/test_mint_common.c b/src/mint/test_mint_common.c
index d4bbb6c46..7946f4f1a 100644
--- a/src/mint/test_mint_common.c
+++ b/src/mint/test_mint_common.c
@@ -22,7 +22,6 @@
22 22
23#include "platform.h" 23#include "platform.h"
24#include "gnunet/gnunet_util_lib.h" 24#include "gnunet/gnunet_util_lib.h"
25#include "taler_rsa.h"
26#include "mint.h" 25#include "mint.h"
27 26
28#define EXITIF(cond) \ 27#define EXITIF(cond) \
@@ -34,9 +33,11 @@ int
34main (int argc, const char *const argv[]) 33main (int argc, const char *const argv[])
35{ 34{
36 struct TALER_MINT_DenomKeyIssuePriv dki; 35 struct TALER_MINT_DenomKeyIssuePriv dki;
37 struct TALER_RSA_PrivateKeyBinaryEncoded *enc; 36 char *enc;
37 size_t enc_size;
38 struct TALER_MINT_DenomKeyIssuePriv dki_read; 38 struct TALER_MINT_DenomKeyIssuePriv dki_read;
39 struct TALER_RSA_PrivateKeyBinaryEncoded *enc_read; 39 char *enc_read;
40 size_t enc_read_size;
40 char *tmpfile; 41 char *tmpfile;
41 42
42 int ret; 43 int ret;
@@ -51,20 +52,17 @@ main (int argc, const char *const argv[])
51 &dki.issue.signature, 52 &dki.issue.signature,
52 sizeof (dki) - offsetof (struct TALER_MINT_DenomKeyIssue, 53 sizeof (dki) - offsetof (struct TALER_MINT_DenomKeyIssue,
53 signature)); 54 signature));
54 dki.denom_priv = TALER_RSA_key_create (); 55 dki.denom_priv = GNUNET_CRYPTO_rsa_private_key_create ();
55 EXITIF (NULL == (enc = TALER_RSA_encode_key (dki.denom_priv))); 56 enc_size = GNUNET_CRYPTO_rsa_private_key_encode (dki.denom_priv, &enc);
56 EXITIF (NULL == (tmpfile = GNUNET_DISK_mktemp ("test_mint_common"))); 57 EXITIF (NULL == (tmpfile = GNUNET_DISK_mktemp ("test_mint_common")));
57 EXITIF (GNUNET_OK != TALER_MINT_write_denom_key (tmpfile, &dki)); 58 EXITIF (GNUNET_OK != TALER_MINT_write_denom_key (tmpfile, &dki));
58 EXITIF (GNUNET_OK != TALER_MINT_read_denom_key (tmpfile, &dki_read)); 59 EXITIF (GNUNET_OK != TALER_MINT_read_denom_key (tmpfile, &dki_read));
59 EXITIF (NULL == (enc_read = TALER_RSA_encode_key (dki_read.denom_priv))); 60 enc_read_size = GNUNET_CRYPTO_rsa_privae_key_encode (dki_read.denom_priv,
60 EXITIF (enc->len != enc_read->len); 61 &enc_read);
62 EXITIF (enc_size != enc_read_size);
61 EXITIF (0 != memcmp (enc, 63 EXITIF (0 != memcmp (enc,
62 enc_read, 64 enc_read,
63 ntohs(enc->len))); 65 enc_size));
64 EXITIF (0 != memcmp (&dki.issue.signature,
65 &dki_read.issue.signature,
66 sizeof (dki) - offsetof (struct TALER_MINT_DenomKeyIssue,
67 signature)));
68 ret = 0; 66 ret = 0;
69 67
70 EXITIF_exit: 68 EXITIF_exit:
@@ -76,8 +74,8 @@ main (int argc, const char *const argv[])
76 } 74 }
77 GNUNET_free_non_null (enc_read); 75 GNUNET_free_non_null (enc_read);
78 if (NULL != dki.denom_priv) 76 if (NULL != dki.denom_priv)
79 TALER_RSA_key_free (dki.denom_priv); 77 GNUNET_CRYPTO_rsa_private_key_free (dki.denom_priv);
80 if (NULL != dki_read.denom_priv) 78 if (NULL != dki_read.denom_priv)
81 TALER_RSA_key_free (dki_read.denom_priv); 79 GNUNET_CRYPOT_rsa_private_key_free (dki_read.denom_priv);
82 return ret; 80 return ret;
83} 81}
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 480b07a70..d280cfd04 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -6,8 +6,7 @@ lib_LTLIBRARIES = \
6libtalerutil_la_SOURCES = \ 6libtalerutil_la_SOURCES = \
7 util.c \ 7 util.c \
8 json.c \ 8 json.c \
9 db.c \ 9 db.c
10 rsa.c
11 10
12libtalerutil_la_LIBADD = \ 11libtalerutil_la_LIBADD = \
13 -lgnunetutil \ 12 -lgnunetutil \
diff --git a/src/util/rsa.c b/src/util/rsa.c
deleted file mode 100644
index c34ab1661..000000000
--- a/src/util/rsa.c
+++ /dev/null
@@ -1,928 +0,0 @@
1/* NOTE: this is obsolete logic, we should migrate to the
2 GNUNET_CRYPTO_rsa-API as soon as possible */
3
4/*
5 This file is part of TALER
6 (C) 2014 Christian Grothoff (and other contributing authors)
7
8 TALER is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 3, or (at your option) any later version.
11
12 TALER is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along with
17 TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
18*/
19
20/**
21 * @file util/rsa.c
22 * @brief RSA key management utilities. Most of the code here is taken from
23 * gnunet-0.9.5a
24 * @author Sree Harsha Totakura <sreeharsha@totakura.in>
25 *
26 * Authors of the gnunet code:
27 * Christian Grothoff
28 * Krista Bennett
29 * Gerd Knorr <kraxel@bytesex.org>
30 * Ioana Patrascu
31 * Tzvetan Horozov
32 */
33
34#include "platform.h"
35#include "gcrypt.h"
36#include "gnunet/gnunet_util_lib.h"
37#include "taler_rsa.h"
38
39
40
41#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
42
43#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
44
45#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
46
47/**
48 * Log an error message at log-level 'level' that indicates
49 * a failure of the command 'cmd' with the message given
50 * by gcry_strerror(rc).
51 */
52#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0)
53
54/**
55 * Shorthand to cleanup non null mpi data types
56 */
57#define mpi_release_non_null(mpi) \
58 if (NULL != mpi) gcry_mpi_release (mpi);
59
60/**
61 * The private information of an RSA key pair.
62 * NOTE: this must match the definition in crypto_ksk.c and gnunet-rsa.c!
63 */
64struct TALER_RSA_PrivateKey
65{
66 /**
67 * Libgcrypt S-expression for the ECC key.
68 */
69 gcry_sexp_t sexp;
70};
71
72
73/**
74 * Extract values from an S-expression.
75 *
76 * @param array where to store the result(s)
77 * @param sexp S-expression to parse
78 * @param topname top-level name in the S-expression that is of interest
79 * @param elems names of the elements to extract
80 * @return 0 on success
81 */
82static int
83key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname,
84 const char *elems)
85{
86 gcry_sexp_t list;
87 gcry_sexp_t l2;
88 const char *s;
89 unsigned int i;
90 unsigned int idx;
91
92 if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
93 return 1;
94 l2 = gcry_sexp_cadr (list);
95 gcry_sexp_release (list);
96 list = l2;
97 if (! list)
98 return 2;
99 idx = 0;
100 for (s = elems; *s; s++, idx++)
101 {
102 if (! (l2 = gcry_sexp_find_token (list, s, 1)))
103 {
104 for (i = 0; i < idx; i++)
105 {
106 gcry_free (array[i]);
107 array[i] = NULL;
108 }
109 gcry_sexp_release (list);
110 return 3; /* required parameter not found */
111 }
112 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
113 gcry_sexp_release (l2);
114 if (! array[idx])
115 {
116 for (i = 0; i < idx; i++)
117 {
118 gcry_free (array[i]);
119 array[i] = NULL;
120 }
121 gcry_sexp_release (list);
122 return 4; /* required parameter is invalid */
123 }
124 }
125 gcry_sexp_release (list);
126 return 0;
127}
128
129/**
130 * If target != size, move target bytes to the
131 * end of the size-sized buffer and zero out the
132 * first target-size bytes.
133 *
134 * @param buf original buffer
135 * @param size number of bytes in the buffer
136 * @param target target size of the buffer
137 */
138static void
139adjust (unsigned char *buf, size_t size, size_t target)
140{
141 if (size < target)
142 {
143 memmove (&buf[target - size], buf, size);
144 memset (buf, 0, target - size);
145 }
146}
147
148
149/**
150 * Create a new private key. Caller must free return value.
151 *
152 * @return fresh private key
153 */
154struct TALER_RSA_PrivateKey *
155TALER_RSA_key_create ()
156{
157 struct TALER_RSA_PrivateKey *ret;
158 gcry_sexp_t s_key;
159 gcry_sexp_t s_keyparam;
160
161 GNUNET_assert (0 ==
162 gcry_sexp_build (&s_keyparam, NULL,
163 "(genkey(rsa(nbits %d)(rsa-use-e 3:257)))",
164 2048));
165 GNUNET_assert (0 == gcry_pk_genkey (&s_key, s_keyparam));
166 gcry_sexp_release (s_keyparam);
167#if EXTRA_CHECKS
168 GNUNET_assert (0 == gcry_pk_testkey (s_key));
169#endif
170 ret = GNUNET_malloc (sizeof (struct TALER_RSA_PrivateKey));
171 ret->sexp = s_key;
172 return ret;
173}
174
175
176/**
177 * Free memory occupied by the private key.
178 *
179 * @param key pointer to the memory to free
180 */
181void
182TALER_RSA_key_free (struct TALER_RSA_PrivateKey *key)
183{
184 gcry_sexp_release (key->sexp);
185 GNUNET_free (key);
186}
187
188
189/**
190 * Encode the private key in a format suitable for
191 * storing it into a file.
192 * @return encoding of the private key
193 */
194struct TALER_RSA_PrivateKeyBinaryEncoded *
195TALER_RSA_encode_key (const struct TALER_RSA_PrivateKey *hostkey)
196{
197 struct TALER_RSA_PrivateKeyBinaryEncoded *retval;
198 gcry_mpi_t pkv[6];
199 void *pbu[6];
200 size_t sizes[6];
201 int rc;
202 int i;
203 int size;
204
205#if EXTRA_CHECKS
206 if (gcry_pk_testkey (hostkey->sexp))
207 {
208 GNUNET_break (0);
209 return NULL;
210 }
211#endif
212
213 memset (pkv, 0, sizeof (gcry_mpi_t) * 6);
214 rc = key_from_sexp (pkv, hostkey->sexp, "private-key", "nedpqu");
215 if (rc)
216 rc = key_from_sexp (pkv, hostkey->sexp, "rsa", "nedpqu");
217 if (rc)
218 rc = key_from_sexp (pkv, hostkey->sexp, "private-key", "nedpq");
219 if (rc)
220 rc = key_from_sexp (pkv, hostkey->sexp, "rsa", "nedpq");
221 if (rc)
222 rc = key_from_sexp (pkv, hostkey->sexp, "private-key", "ned");
223 if (rc)
224 rc = key_from_sexp (pkv, hostkey->sexp, "rsa", "ned");
225 GNUNET_assert (0 == rc);
226 size = sizeof (struct TALER_RSA_PrivateKeyBinaryEncoded);
227 for (i = 0; i < 6; i++)
228 {
229 if (NULL != pkv[i])
230 {
231 GNUNET_assert (0 ==
232 gcry_mpi_aprint (GCRYMPI_FMT_USG,
233 (unsigned char **) &pbu[i], &sizes[i],
234 pkv[i]));
235 size += sizes[i];
236 }
237 else
238 {
239 pbu[i] = NULL;
240 sizes[i] = 0;
241 }
242 }
243 GNUNET_assert (size < 65536);
244 retval = GNUNET_malloc (size);
245 retval->len = htons (size);
246 i = 0;
247 retval->sizen = htons (sizes[0]);
248 memcpy (&((char *) (&retval[1]))[i], pbu[0], sizes[0]);
249 i += sizes[0];
250 retval->sizee = htons (sizes[1]);
251 memcpy (&((char *) (&retval[1]))[i], pbu[1], sizes[1]);
252 i += sizes[1];
253 retval->sized = htons (sizes[2]);
254 memcpy (&((char *) (&retval[1]))[i], pbu[2], sizes[2]);
255 i += sizes[2];
256 /* swap p and q! */
257 retval->sizep = htons (sizes[4]);
258 memcpy (&((char *) (&retval[1]))[i], pbu[4], sizes[4]);
259 i += sizes[4];
260 retval->sizeq = htons (sizes[3]);
261 memcpy (&((char *) (&retval[1]))[i], pbu[3], sizes[3]);
262 i += sizes[3];
263 retval->sizedmp1 = htons (0);
264 retval->sizedmq1 = htons (0);
265 memcpy (&((char *) (&retval[1]))[i], pbu[5], sizes[5]);
266 for (i = 0; i < 6; i++)
267 {
268 if (pkv[i] != NULL)
269 gcry_mpi_release (pkv[i]);
270 if (pbu[i] != NULL)
271 free (pbu[i]);
272 }
273 return retval;
274}
275
276
277/**
278 * Extract the public key of the given private key.
279 *
280 * @param priv the private key
281 * @param pub where to write the public key
282 */
283void
284TALER_RSA_key_get_public (const struct TALER_RSA_PrivateKey *priv,
285 struct TALER_RSA_PublicKeyBinaryEncoded *pub)
286{
287 gcry_mpi_t skey[2];
288 size_t size;
289 int rc;
290
291 rc = key_from_sexp (skey, priv->sexp, "public-key", "ne");
292 if (0 != rc)
293 rc = key_from_sexp (skey, priv->sexp, "private-key", "ne");
294 if (0 != rc)
295 rc = key_from_sexp (skey, priv->sexp, "rsa", "ne");
296 GNUNET_assert (0 == rc);
297 pub->len =
298 htons (sizeof (struct TALER_RSA_PublicKeyBinaryEncoded) -
299 sizeof (pub->padding));
300 pub->sizen = htons (TALER_RSA_DATA_ENCODING_LENGTH);
301 pub->padding = 0;
302 size = TALER_RSA_DATA_ENCODING_LENGTH;
303 GNUNET_assert (0 ==
304 gcry_mpi_print (GCRYMPI_FMT_USG, &pub->key[0], size, &size,
305 skey[0]));
306 adjust (&pub->key[0], size, TALER_RSA_DATA_ENCODING_LENGTH);
307 size = TALER_RSA_KEY_LENGTH - TALER_RSA_DATA_ENCODING_LENGTH;
308 GNUNET_assert (0 ==
309 gcry_mpi_print (GCRYMPI_FMT_USG,
310 &pub->key
311 [TALER_RSA_DATA_ENCODING_LENGTH], size,
312 &size, skey[1]));
313 adjust (&pub->key[TALER_RSA_DATA_ENCODING_LENGTH], size,
314 TALER_RSA_KEY_LENGTH -
315 TALER_RSA_DATA_ENCODING_LENGTH);
316 gcry_mpi_release (skey[0]);
317 gcry_mpi_release (skey[1]);
318}
319
320
321/**
322 * Decode the private key from the data-format back
323 * to the "normal", internal format.
324 *
325 * @param buf the buffer where the private key data is stored
326 * @param len the length of the data in 'buffer'
327 * @return NULL on error
328 */
329struct TALER_RSA_PrivateKey *
330TALER_RSA_decode_key (const char *buf, uint16_t len)
331{
332 struct TALER_RSA_PrivateKey *ret;
333 const struct TALER_RSA_PrivateKeyBinaryEncoded *encoding =
334 (const struct TALER_RSA_PrivateKeyBinaryEncoded *) buf;
335 gcry_sexp_t res;
336 gcry_mpi_t n;
337 gcry_mpi_t e;
338 gcry_mpi_t d;
339 gcry_mpi_t p;
340 gcry_mpi_t q;
341 gcry_mpi_t u;
342 int rc;
343 size_t size;
344 size_t pos;
345 uint16_t enc_len;
346 size_t erroff;
347
348 enc_len = ntohs (encoding->len);
349 if (len != enc_len)
350 return NULL;
351
352 pos = 0;
353 size = ntohs (encoding->sizen);
354 rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG,
355 &((const unsigned char *) (&encoding[1]))[pos], size,
356 &size);
357 pos += ntohs (encoding->sizen);
358 if (0 != rc)
359 {
360 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
361 return NULL;
362 }
363 size = ntohs (encoding->sizee);
364 rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG,
365 &((const unsigned char *) (&encoding[1]))[pos], size,
366 &size);
367 pos += ntohs (encoding->sizee);
368 if (0 != rc)
369 {
370 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
371 gcry_mpi_release (n);
372 return NULL;
373 }
374 size = ntohs (encoding->sized);
375 rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG,
376 &((const unsigned char *) (&encoding[1]))[pos], size,
377 &size);
378 pos += ntohs (encoding->sized);
379 if (0 != rc)
380 {
381 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
382 gcry_mpi_release (n);
383 gcry_mpi_release (e);
384 return NULL;
385 }
386 /* swap p and q! */
387 size = ntohs (encoding->sizep);
388 if (size > 0)
389 {
390 rc = gcry_mpi_scan (&q, GCRYMPI_FMT_USG,
391 &((const unsigned char *) (&encoding[1]))[pos], size,
392 &size);
393 pos += ntohs (encoding->sizep);
394 if (0 != rc)
395 {
396 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
397 gcry_mpi_release (n);
398 gcry_mpi_release (e);
399 gcry_mpi_release (d);
400 return NULL;
401 }
402 }
403 else
404 q = NULL;
405 size = ntohs (encoding->sizeq);
406 if (size > 0)
407 {
408 rc = gcry_mpi_scan (&p, GCRYMPI_FMT_USG,
409 &((const unsigned char *) (&encoding[1]))[pos], size,
410 &size);
411 pos += ntohs (encoding->sizeq);
412 if (0 != rc)
413 {
414 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
415 gcry_mpi_release (n);
416 gcry_mpi_release (e);
417 gcry_mpi_release (d);
418 if (NULL != q)
419 gcry_mpi_release (q);
420 return NULL;
421 }
422 }
423 else
424 p = NULL;
425 pos += ntohs (encoding->sizedmp1);
426 pos += ntohs (encoding->sizedmq1);
427 size =
428 ntohs (encoding->len) - sizeof (struct TALER_RSA_PrivateKeyBinaryEncoded) - pos;
429 if (size > 0)
430 {
431 rc = gcry_mpi_scan (&u, GCRYMPI_FMT_USG,
432 &((const unsigned char *) (&encoding[1]))[pos], size,
433 &size);
434 if (0 != rc)
435 {
436 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
437 gcry_mpi_release (n);
438 gcry_mpi_release (e);
439 gcry_mpi_release (d);
440 if (NULL != p)
441 gcry_mpi_release (p);
442 if (NULL != q)
443 gcry_mpi_release (q);
444 return NULL;
445 }
446 }
447 else
448 u = NULL;
449
450 if ((NULL != p) && (NULL != q) && (NULL != u))
451 {
452 rc = gcry_sexp_build (&res, &erroff,
453 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
454 n, e, d, p, q, u);
455 }
456 else
457 {
458 if ((NULL != p) && (NULL != q))
459 {
460 rc = gcry_sexp_build (&res, &erroff,
461 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
462 n, e, d, p, q);
463 }
464 else
465 {
466 rc = gcry_sexp_build (&res, &erroff,
467 "(private-key(rsa(n %m)(e %m)(d %m)))", n, e, d);
468 }
469 }
470 gcry_mpi_release (n);
471 gcry_mpi_release (e);
472 gcry_mpi_release (d);
473 if (NULL != p)
474 gcry_mpi_release (p);
475 if (NULL != q)
476 gcry_mpi_release (q);
477 if (NULL != u)
478 gcry_mpi_release (u);
479
480 if (0 != rc)
481 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
482 if (0 != (rc = gcry_pk_testkey (res)))
483 {
484 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
485 return NULL;
486 }
487 ret = GNUNET_malloc (sizeof (struct TALER_RSA_PrivateKey));
488 ret->sexp = res;
489 return ret;
490}
491
492
493/**
494 * Convert a public key to a string.
495 *
496 * @param pub key to convert
497 * @return string representing 'pub'
498 */
499char *
500TALER_RSA_public_key_to_string (const struct TALER_RSA_PublicKeyBinaryEncoded *pub)
501{
502 char *pubkeybuf;
503 size_t keylen = (sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)) * 8;
504 char *end;
505
506 if (keylen % 5 > 0)
507 keylen += 5 - keylen % 5;
508 keylen /= 5;
509 pubkeybuf = GNUNET_malloc (keylen + 1);
510 end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
511 sizeof (struct TALER_RSA_PublicKeyBinaryEncoded),
512 pubkeybuf,
513 keylen);
514 if (NULL == end)
515 {
516 GNUNET_free (pubkeybuf);
517 return NULL;
518 }
519 *end = '\0';
520 return pubkeybuf;
521}
522
523
524/**
525 * Convert a string representing a public key to a public key.
526 *
527 * @param enc encoded public key
528 * @param enclen number of bytes in enc (without 0-terminator)
529 * @param pub where to store the public key
530 * @return GNUNET_OK on success
531 */
532int
533TALER_RSA_public_key_from_string (const char *enc,
534 size_t enclen,
535 struct TALER_RSA_PublicKeyBinaryEncoded *pub)
536{
537 size_t keylen = (sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)) * 8;
538
539 if (keylen % 5 > 0)
540 keylen += 5 - keylen % 5;
541 keylen /= 5;
542 if (enclen != keylen)
543 return GNUNET_SYSERR;
544
545 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen,
546 (unsigned char*) pub,
547 sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)))
548 return GNUNET_SYSERR;
549 if ( (ntohs (pub->len) != sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)) ||
550 (ntohs (pub->padding) != 0) ||
551 (ntohs (pub->sizen) != TALER_RSA_DATA_ENCODING_LENGTH) )
552 return GNUNET_SYSERR;
553 return GNUNET_OK;
554}
555
556
557/**
558 * Convert the data specified in the given purpose argument to an
559 * S-expression suitable for signature operations.
560 *
561 * @param ptr pointer to the data to convert
562 * @param size the size of the data
563 * @return converted s-expression
564 */
565static gcry_sexp_t
566data_to_sexp (const void *ptr, size_t size)
567{
568 gcry_mpi_t value;
569 gcry_sexp_t data;
570
571 value = NULL;
572 data = NULL;
573 GNUNET_assert (0 == gcry_mpi_scan (&value, GCRYMPI_FMT_USG, ptr, size, NULL));
574 GNUNET_assert (0 == gcry_sexp_build (&data, NULL, "(data (flags raw) (value %M))", value));
575 gcry_mpi_release (value);
576 return data;
577}
578
579
580/**
581 * Sign the given hash block.
582 *
583 * @param key private key to use for the signing
584 * @param hash the block containing the hash of the message to sign
585 * @param hash_size the size of the hash block
586 * @param sig where to write the signature
587 * @return GNUNET_SYSERR on error, GNUNET_OK on success
588 */
589int
590TALER_RSA_sign (const struct TALER_RSA_PrivateKey *key,
591 const void *hash,
592 size_t hash_size,
593 struct TALER_RSA_Signature *sig)
594{
595 gcry_sexp_t result;
596 gcry_sexp_t data;
597 size_t ssize;
598 gcry_mpi_t rval;
599
600 data = data_to_sexp (hash, hash_size);
601 GNUNET_assert (0 == gcry_pk_sign (&result, data, key->sexp));
602 gcry_sexp_release (data);
603 GNUNET_assert (0 == key_from_sexp (&rval, result, "rsa", "s"));
604 gcry_sexp_release (result);
605 ssize = sizeof (struct TALER_RSA_Signature);
606 GNUNET_assert (0 ==
607 gcry_mpi_print (GCRYMPI_FMT_USG, (unsigned char *) sig, ssize,
608 &ssize, rval));
609 gcry_mpi_release (rval);
610 adjust (sig->sig, ssize, sizeof (struct TALER_RSA_Signature));
611 return GNUNET_OK;
612}
613
614
615/**
616 * Convert the given public key from the network format to the
617 * S-expression that can be used by libgcrypt.
618 *
619 * @param publicKey public key to decode
620 * @return NULL on error
621 */
622static gcry_sexp_t
623decode_public_key (const struct TALER_RSA_PublicKeyBinaryEncoded *publicKey)
624{
625 gcry_sexp_t result;
626 gcry_mpi_t n;
627 gcry_mpi_t e;
628 size_t size;
629 size_t erroff;
630 int rc;
631
632 if ((ntohs (publicKey->sizen) != TALER_RSA_DATA_ENCODING_LENGTH) ||
633 (ntohs (publicKey->len) !=
634 sizeof (struct TALER_RSA_PublicKeyBinaryEncoded) -
635 sizeof (publicKey->padding)))
636 {
637 GNUNET_break (0);
638 return NULL;
639 }
640 size = TALER_RSA_DATA_ENCODING_LENGTH;
641 if (0 != (rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG, &publicKey->key[0], size, &size)))
642 {
643 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
644 return NULL;
645 }
646 size = TALER_RSA_KEY_LENGTH - TALER_RSA_DATA_ENCODING_LENGTH;
647 if (0 != (rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG,
648 &publicKey->key[TALER_RSA_DATA_ENCODING_LENGTH],
649 size, &size)))
650 {
651 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
652 gcry_mpi_release (n);
653 return NULL;
654 }
655 rc = gcry_sexp_build (&result, &erroff, "(public-key(rsa(n %m)(e %m)))", n,
656 e);
657 gcry_mpi_release (n);
658 gcry_mpi_release (e);
659 if (0 != rc)
660 {
661 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); /* erroff gives more info */
662 return NULL;
663 }
664 return result;
665}
666
667
668/**
669 * Verify signature with the given hash.
670 *
671 * @param hash the hash code to verify against the signature
672 * @param sig signature that is being validated
673 * @param publicKey public key of the signer
674 * @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid
675 */
676int
677TALER_RSA_hash_verify (const struct GNUNET_HashCode *hash,
678 const struct TALER_RSA_Signature *sig,
679 const struct TALER_RSA_PublicKeyBinaryEncoded *publicKey)
680{
681 gcry_sexp_t data;
682 gcry_sexp_t sigdata;
683 size_t size;
684 gcry_mpi_t val;
685 gcry_sexp_t psexp;
686 size_t erroff;
687 int rc;
688
689 size = sizeof (struct TALER_RSA_Signature);
690 GNUNET_assert (0 ==
691 gcry_mpi_scan (&val, GCRYMPI_FMT_USG,
692 (const unsigned char *) sig, size, &size));
693 GNUNET_assert (0 ==
694 gcry_sexp_build (&sigdata, &erroff, "(sig-val(rsa(s %m)))",
695 val));
696 gcry_mpi_release (val);
697 data = data_to_sexp (hash, sizeof (struct GNUNET_HashCode));
698 if (! (psexp = decode_public_key (publicKey)))
699 {
700 gcry_sexp_release (data);
701 gcry_sexp_release (sigdata);
702 return GNUNET_SYSERR;
703 }
704 rc = gcry_pk_verify (sigdata, data, psexp);
705 gcry_sexp_release (psexp);
706 gcry_sexp_release (data);
707 gcry_sexp_release (sigdata);
708 if (rc)
709 {
710 LOG (GNUNET_ERROR_TYPE_WARNING,
711 _("RSA signature verification failed at %s:%d: %s\n"), __FILE__,
712 __LINE__, gcry_strerror (rc));
713 return GNUNET_SYSERR;
714 }
715 return GNUNET_OK;
716}
717
718
719/**
720 * Verify signature on the given message
721 *
722 * @param msg the message
723 * @param size the size of the message
724 * @param sig signature that is being validated
725 * @param publicKey public key of the signer
726 * @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid
727 */
728int
729TALER_RSA_verify (const void *msg, size_t size,
730 const struct TALER_RSA_Signature *sig,
731 const struct TALER_RSA_PublicKeyBinaryEncoded *publicKey)
732{
733 struct GNUNET_HashCode hash;
734
735 GNUNET_CRYPTO_hash (msg, size, &hash);
736 return TALER_RSA_hash_verify (&hash, sig, publicKey);
737}
738
739/**
740 * The blinding key is equal in length to the RSA modulus
741 */
742#define TALER_RSA_BLINDING_KEY_LEN TALER_RSA_DATA_ENCODING_LENGTH
743
744struct TALER_RSA_BlindingKey
745{
746 /**
747 * The blinding factor
748 */
749 gcry_mpi_t r;
750};
751
752struct TALER_RSA_BlindingKey *
753TALER_RSA_blinding_key_create ()
754{
755 struct TALER_RSA_BlindingKey *blind;
756
757 blind = GNUNET_new (struct TALER_RSA_BlindingKey);
758 blind->r = gcry_mpi_new (TALER_RSA_BLINDING_KEY_LEN * 8);
759 gcry_mpi_randomize (blind->r, TALER_RSA_BLINDING_KEY_LEN * 8, GCRY_STRONG_RANDOM);
760 return blind;
761}
762
763
764void
765TALER_RSA_blinding_key_destroy (struct TALER_RSA_BlindingKey *bkey)
766{
767 gcry_mpi_release (bkey->r);
768 GNUNET_free (bkey);
769}
770
771
772struct TALER_RSA_BlindedSignaturePurpose *
773TALER_RSA_message_blind (const void *msg, size_t size,
774 struct TALER_RSA_BlindingKey *bkey,
775 struct TALER_RSA_PublicKeyBinaryEncoded *pkey)
776{
777 struct TALER_RSA_BlindedSignaturePurpose *bsp;
778 struct GNUNET_HashCode hash;
779 gcry_sexp_t psexp;
780 gcry_mpi_t data;
781 gcry_mpi_t skey[2];
782 gcry_mpi_t r_e;
783 gcry_mpi_t data_r_e;
784 size_t rsize;
785 gcry_error_t rc;
786 int ret;
787
788 bsp = NULL;
789 psexp = NULL;
790 data = NULL;
791 skey[0] = skey[1] = NULL;
792 r_e = NULL;
793 data_r_e = NULL;
794 rsize = 0;
795 rc = 0;
796 ret = 0;
797 if (! (psexp = decode_public_key (pkey)))
798 return NULL;
799 ret = key_from_sexp (skey, psexp, "public-key", "ne");
800 if (0 != ret)
801 ret = key_from_sexp (skey, psexp, "rsa", "ne");
802 gcry_sexp_release (psexp);
803 psexp = NULL;
804 GNUNET_assert (0 == ret);
805 GNUNET_CRYPTO_hash (msg, size, &hash);
806 if (0 != (rc=gcry_mpi_scan (&data, GCRYMPI_FMT_USG,
807 (const unsigned char *) msg, size, &rsize)))
808 {
809 LOG_GCRY (GNUNET_ERROR_TYPE_WARNING, "gcry_mpi_scan", rc);
810 goto cleanup;
811 }
812 r_e = gcry_mpi_new (0);
813 gcry_mpi_powm (r_e, bkey->r,
814 skey[1], /* e */
815 skey[0]); /* n */
816
817 data_r_e = gcry_mpi_new (0);
818 gcry_mpi_mulm (data_r_e, data, r_e, skey[0]);
819
820 bsp = GNUNET_new (struct TALER_RSA_BlindedSignaturePurpose);
821 rc = gcry_mpi_print (GCRYMPI_FMT_USG,
822 (unsigned char *) bsp,
823 sizeof (struct TALER_RSA_BlindedSignaturePurpose),
824 &rsize,
825 data_r_e);
826 GNUNET_assert (0 == rc);
827 adjust ((unsigned char *) bsp, rsize,
828 sizeof (struct TALER_RSA_BlindedSignaturePurpose));
829
830 cleanup:
831 if (NULL != psexp) gcry_sexp_release (psexp);
832 mpi_release_non_null (skey[0]);
833 mpi_release_non_null (skey[1]);
834 mpi_release_non_null (data);
835 mpi_release_non_null (r_e);
836 mpi_release_non_null (data_r_e);
837 return bsp;
838}
839
840
841int
842TALER_RSA_unblind (struct TALER_RSA_Signature *sig,
843 struct TALER_RSA_BlindingKey *bkey,
844 struct TALER_RSA_PublicKeyBinaryEncoded *pkey)
845{
846 gcry_sexp_t psexp;
847 gcry_mpi_t skey;
848 gcry_mpi_t sigval;
849 gcry_mpi_t r_inv;
850 gcry_mpi_t ubsig;
851 size_t rsize;
852 gcry_error_t rc;
853 int ret;
854
855 psexp = NULL;
856 skey = NULL;
857 sigval = NULL;
858 r_inv = NULL;
859 ubsig = NULL;
860 rsize = 0;
861 rc = 0;
862 ret = GNUNET_SYSERR;
863 if (! (psexp = decode_public_key (pkey)))
864 return GNUNET_SYSERR;
865 ret = key_from_sexp (&skey, psexp, "public-key", "n");
866 if (0 != ret)
867 ret = key_from_sexp (&skey, psexp, "rsa", "n");
868 gcry_sexp_release (psexp);
869 psexp = NULL;
870 if (0 != (rc = gcry_mpi_scan (&sigval, GCRYMPI_FMT_USG,
871 (const unsigned char *) sig,
872 sizeof (struct TALER_RSA_Signature),
873 &rsize)))
874 {
875 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
876 goto cleanup;
877 }
878 r_inv = gcry_mpi_new (0);
879 GNUNET_assert (1 == gcry_mpi_invm (r_inv, bkey->r, skey)); /* n: skey */
880 ubsig = gcry_mpi_new (0);
881 gcry_mpi_mulm (ubsig, sigval, r_inv, skey);
882 rc = gcry_mpi_print (GCRYMPI_FMT_USG,
883 (unsigned char *) sig,
884 sizeof (struct TALER_RSA_Signature),
885 &rsize,
886 ubsig);
887 GNUNET_assert (0 == rc);
888 adjust ((unsigned char *) sig, rsize, sizeof (struct TALER_RSA_Signature));
889 ret = GNUNET_OK;
890
891 cleanup:
892 if (NULL != psexp) gcry_sexp_release (psexp);
893 mpi_release_non_null (skey);
894 mpi_release_non_null (sigval);
895 mpi_release_non_null (r_inv);
896 mpi_release_non_null (ubsig);
897 return ret;
898}
899
900
901/**
902 * Encode a blinding key
903 *
904 * @param bkey the blinding key to encode
905 * @param bkey_enc where to store the encoded binary key
906 * @return #GNUNET_OK upon successful encoding; #GNUNET_SYSERR upon failure
907 */
908int
909TALER_RSA_blinding_key_encode (struct TALER_RSA_BlindingKey *bkey,
910 struct TALER_RSA_BlindingKeyBinaryEncoded *bkey_enc)
911{
912 GNUNET_abort (); /* FIXME: not implemented */
913}
914
915
916/**
917 * Decode a blinding key from its encoded form
918 *
919 * @param bkey_enc the encoded blinding key
920 * @return the decoded blinding key; NULL upon error
921 */
922struct TALER_RSA_BlindingKey *
923TALER_RSA_blinding_key_decode (struct TALER_RSA_BlindingKeyBinaryEncoded *bkey_enc)
924{
925 GNUNET_abort (); /* FIXME: not implemented */
926}
927
928/* end of util/rsa.c */