Merge branch 'master' of git+ssh://taler.net/var/git/mint

This commit is contained in:
Christian Grothoff 2015-05-18 18:53:12 +02:00
commit 7b4623706c
37 changed files with 1105 additions and 686 deletions

10
contrib/coverage.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/sh
# Run from 'taler-mint/' top-level directory to generate
# code coverage data.
TOP=`pwd`
mkdir -p doc/coverage/
lcov -d $TOP -z
make check
lcov -d $TOP -c -o doc/coverage/coverage.info
cd doc/coverage/
genhtml coverage.info

View File

@ -8,7 +8,7 @@ WIREFORMAT = SEPA
# How to access our database # How to access our database
DB = postgres DB = postgres
DB_CONN_STR = "" DB_CONN_STR = "postgres:///taler"
# HTTP port the mint listens to # HTTP port the mint listens to
PORT = 4241 PORT = 4241

View File

@ -874,6 +874,23 @@ be added to the basic protocol.
\subsection{Refunds} \subsection{Refunds}
The refresh protocol offers an easy way to enable refunds to
customers, even if they are anonymous. Refunds can be supported
by including a public signing key of the mechant in the transaction
details, and having the customer keep the private key of the spent
coins on file.
Given this, the merchant can simply sign a {\em refund confirmation}
and share it with the mint (and the customer). Assuming the mint has
a way to recover the funds from the merchant (or simply not performed
the transfer yet), the mint can simply add the value of the refunded
transaction back to the original coin, re-enabling those funds to be
spent again by the original customer.
The (anonymous) customer -- but nobody else -- can then use the
refresh protocol to melt the refunded coin and create a fresh coin
that is unlinkable to the previous transaction.
\subsection{Incremental spending} \subsection{Incremental spending}
@ -1029,45 +1046,57 @@ protocol with the mint.
%\end{figure} %\end{figure}
\subsection{Probabilistic donations}
\subsection{Probabilistic spending} Similar to Peppercoin, Taler supports probabilistic {\em micro}donations of coins to
support cost-effective transactions for small amounts. We consider
amounts to be ``micro'' if the value of the transaction is close or
even below the business cost of an individual transaction to the mint.
Similar to Peppercoin, Taler supports probabilistic spending of coins to To support microdonations, an ordinary transaction is performed based
support cost-effective transactions for small amounts. Here, an on the result of a biased coin flip with a probability related to the
ordinary transaction is performed based on the result of a biased coin desired transaction amount in relation to the value of the coin. More
flip with a probability related to the desired transaction amount in specifically, a microdonation of value $\epsilon$ is upgraded to a
relation to the value of the coin. Unlike Peppercoin, in Taler either macropayment of value $m$ with a probability of $\frac{\epsilon}{m}$.
the merchant wins and the customer looses the coin, or the merchant Here, $m$ is chosen such that the business transaction cost at the
looses and the customer keeps the coin. Thus, there is no opportunity mint is small in relation to $m$. The mint is only involved in the
for the merchant and the customer to conspire against the mint. To tiny fraction of transactions that are upgraded. On average both
determine if the coin is to be transferred, merchant and customer customers and merchants end up paying (or receiving) the expected
execute a secure coin flipping protocol~\cite{blum1981}. The commit amount $\epsilon$ per microdonation.
values are included in the business contract and are revealed after
the contract has been signed using the private key of the coin. If Unlike Peppercoin, in Taler either the merchant wins and the customer
the coin flip is decided in favor of the merchant, the merchant can looses the coin, or the merchant looses and the customer keeps the
redeem the coin at the mint. coin. Thus, there is no opportunity for the merchant and the customer
to conspire against the mint. To determine if the coin is to be
transferred, merchant and customer execute a secure coin flipping
protocol~\cite{blum1981}. The commit values are included in the
business contract and are revealed after the contract has been signed
using the private key of the coin. If the coin flip is decided in
favor of the merchant, the merchant can redeem the coin at the mint.
One issue in this protocol is that the customer may use a worthless One issue in this protocol is that the customer may use a worthless
coin by offering a coin that has already been spent. This kind of coin by offering a coin that has already been spent. This kind of
fraud would only be detected if the customer actually lost the coin fraud would only be detected if the customer actually lost the coin
flip, and at this point the merchant might not be able to recover from flip, and at this point the merchant might not be able to recover from
the loss. A fradulent anonymous customer may run the protocol using the loss. A fradulent anonymous customer may run the protocol using
already spent coins until the coin flip is in his favor. As with already spent coins until the coin flip is in his favor.
incremental spending, lock permissions could be used to ensure that
the customer cannot defraud the merchant by offering a coin that has
already been spent. However, as this means involving the mint even if
the merchant looses the coin flip, such a scheme is unsuitable for
microdonations as the transaction costs from involving the mint might
be disproportionate to the value of the transaction, and thus with
locking the probabilistic scheme has no advantage over simply using
fractional payments.
Hence, Taler uses probabilistic transactions {\em without} the online As with incremental spending, lock permissions could be used to ensure
that the customer cannot defraud the merchant by offering a coin that
has already been spent. However, as this means involving the mint
even if the merchant looses the coin flip, such a scheme is unsuitable
for microdonations as the transaction costs from involving the mint
might be disproportionate to the value of the transaction, and thus
with locking the probabilistic scheme has no advantage over simply
using fractional payments.
Hence, Taler uses probabilistic transactions {\em without} online
double-spending detection. This enables the customer to defraud the double-spending detection. This enables the customer to defraud the
merchant by paying with a coin that was already spent. However, as, merchant by paying with a coin that was already spent. However, as,
by definition, such microdonations are for tiny amounts, the incentive by definition, such microdonations are for tiny amounts, the incentive
for customers to pursue this kind of fraud is limited. for customers to pursue this kind of fraud is limited. Still, to
clarify that the customer must be honest, we prefer the term
micro{\em donations} over micro{\em payments} for this scheme.
The following steps are executed for microdonations with upgrade probability $p$: The following steps are executed for microdonations with upgrade probability $p$:
@ -1083,6 +1112,4 @@ The following steps are executed for microdonations with upgrade probability $p$
with $H(r_c)$. with $H(r_c)$.
\end{enumerate} \end{enumerate}
\end{document} \end{document}

View File

@ -17,6 +17,7 @@
* @file include/taler_crypto_lib.h * @file include/taler_crypto_lib.h
* @brief taler-specific crypto functions * @brief taler-specific crypto functions
* @author Sree Harsha Totakura <sreeharsha@totakura.in> * @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Christian Grothoff <christian@grothoff.org>
*/ */
#ifndef TALER_CRYPTO_LIB_H #ifndef TALER_CRYPTO_LIB_H
#define TALER_CRYPTO_LIB_H #define TALER_CRYPTO_LIB_H
@ -100,7 +101,7 @@ struct TALER_MerchantPrivateKeyP
struct TALER_TransferPublicKeyP struct TALER_TransferPublicKeyP
{ {
/** /**
* Taler uses ECDSA for transfer keys. * Taler uses ECDHE for transfer keys.
*/ */
struct GNUNET_CRYPTO_EcdhePublicKey ecdhe_pub; struct GNUNET_CRYPTO_EcdhePublicKey ecdhe_pub;
}; };
@ -113,7 +114,7 @@ struct TALER_TransferPublicKeyP
struct TALER_TransferPrivateKeyP struct TALER_TransferPrivateKeyP
{ {
/** /**
* Taler uses ECDSA for melting session keys. * Taler uses ECDHE for melting session keys.
*/ */
struct GNUNET_CRYPTO_EcdhePrivateKey ecdhe_priv; struct GNUNET_CRYPTO_EcdhePrivateKey ecdhe_priv;
}; };
@ -196,37 +197,28 @@ struct TALER_MasterSignatureP
/** /**
* @brief Type of public keys for Taler coins. The same key material is used * @brief Type of public keys for Taler coins. The same key material is used
* for ECDSA and ECDHE operations. * for EdDSA and ECDHE operations.
*/ */
union TALER_CoinSpendPublicKeyP struct TALER_CoinSpendPublicKeyP
{ {
/** /**
* Taler uses ECDSA for coins when signing deposit requests. * Taler uses EdDSA for coins when signing deposit requests.
*/ */
struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_pub; struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub;
/**
* Taler uses ECDH(E) for coin linkage during refresh operations.
*/
struct GNUNET_CRYPTO_EcdhePublicKey ecdhe_pub;
}; };
/** /**
* @brief Type of private keys for Taler coins. The same key material is used * @brief Type of private keys for Taler coins. The same key material is used
* for ECDSA and ECDHE operations. * for EdDSA and ECDHE operations.
*/ */
union TALER_CoinSpendPrivateKeyP struct TALER_CoinSpendPrivateKeyP
{ {
/** /**
* Taler uses ECDSA for coins when signing deposit requests. * Taler uses EdDSA for coins when signing deposit requests.
*/ */
struct GNUNET_CRYPTO_EcdsaPrivateKey ecdsa_priv; struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv;
/**
* Taler uses ECDHE for coin linkage during refresh operations.
*/
struct GNUNET_CRYPTO_EcdhePrivateKey ecdhe_priv;
}; };
@ -236,9 +228,9 @@ union TALER_CoinSpendPrivateKeyP
struct TALER_CoinSpendSignatureP struct TALER_CoinSpendSignatureP
{ {
/** /**
* Taler uses ECDSA for coins. * Taler uses EdDSA for coins.
*/ */
struct GNUNET_CRYPTO_EcdsaSignature ecdsa_signature; struct GNUNET_CRYPTO_EddsaSignature eddsa_signature;
}; };
@ -302,7 +294,7 @@ struct TALER_CoinPublicInfo
/** /**
* The coin's public key. * The coin's public key.
*/ */
union TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
/** /**
* Public key representing the denomination of the coin * Public key representing the denomination of the coin
@ -383,7 +375,7 @@ struct TALER_RefreshLinkDecrypted
/** /**
* Private key of the coin. * Private key of the coin.
*/ */
union TALER_CoinSpendPrivateKeyP coin_priv; struct TALER_CoinSpendPrivateKeyP coin_priv;
/** /**
* Blinding key. * Blinding key.
@ -416,7 +408,7 @@ struct TALER_RefreshLinkEncrypted
/** /**
* Encrypted private key of the coin. * Encrypted private key of the coin.
*/ */
char coin_priv_enc[sizeof (union TALER_CoinSpendPrivateKeyP)]; char coin_priv_enc[sizeof (struct TALER_CoinSpendPrivateKeyP)];
}; };
@ -427,7 +419,7 @@ struct TALER_RefreshLinkEncrypted
* private key and the coin's public key. * private key and the coin's public key.
* *
* @param secret_enc encrypted link secret * @param secret_enc encrypted link secret
* @param transfer_priv transfer private key * @param trans_priv transfer private key
* @param coin_pub coin public key * @param coin_pub coin public key
* @param[out] secret set to the shared secret * @param[out] secret set to the shared secret
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
@ -435,7 +427,7 @@ struct TALER_RefreshLinkEncrypted
int int
TALER_link_decrypt_secret (const struct TALER_EncryptedLinkSecretP *secret_enc, TALER_link_decrypt_secret (const struct TALER_EncryptedLinkSecretP *secret_enc,
const struct TALER_TransferPrivateKeyP *trans_priv, const struct TALER_TransferPrivateKeyP *trans_priv,
const union TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_LinkSecretP *secret); struct TALER_LinkSecretP *secret);
@ -445,7 +437,7 @@ TALER_link_decrypt_secret (const struct TALER_EncryptedLinkSecretP *secret_enc,
* public key and the coin's private key. * public key and the coin's private key.
* *
* @param secret_enc encrypted link secret * @param secret_enc encrypted link secret
* @param transfer_pub transfer public key * @param trans_pub transfer public key
* @param coin_priv coin private key * @param coin_priv coin private key
* @param[out] secret set to the shared secret * @param[out] secret set to the shared secret
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
@ -453,7 +445,7 @@ TALER_link_decrypt_secret (const struct TALER_EncryptedLinkSecretP *secret_enc,
int int
TALER_link_decrypt_secret2 (const struct TALER_EncryptedLinkSecretP *secret_enc, TALER_link_decrypt_secret2 (const struct TALER_EncryptedLinkSecretP *secret_enc,
const struct TALER_TransferPublicKeyP *trans_pub, const struct TALER_TransferPublicKeyP *trans_pub,
const union TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_LinkSecretP *secret); struct TALER_LinkSecretP *secret);
@ -463,14 +455,14 @@ TALER_link_decrypt_secret2 (const struct TALER_EncryptedLinkSecretP *secret_enc,
* *
* @param secret link secret to encrypt * @param secret link secret to encrypt
* @param coin_pub coin public key * @param coin_pub coin public key
* @param transfer_priv[out] set to transfer private key * @param[out] trans_priv set to transfer private key
* @param transfer_pub[out] set to transfer public key * @param[out] trans_pub set to transfer public key
* @param[out] secret_enc set to the encryptd @a secret * @param[out] secret_enc set to the encryptd @a secret
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/ */
int int
TALER_link_encrypt_secret (const struct TALER_LinkSecretP *secret, TALER_link_encrypt_secret (const struct TALER_LinkSecretP *secret,
const union TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_TransferPrivateKeyP *trans_priv, struct TALER_TransferPrivateKeyP *trans_priv,
struct TALER_TransferPublicKeyP *trans_pub, struct TALER_TransferPublicKeyP *trans_pub,
struct TALER_EncryptedLinkSecretP *secret_enc); struct TALER_EncryptedLinkSecretP *secret_enc);

View File

@ -64,18 +64,6 @@ TALER_json_from_eddsa_sig (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpo
const struct GNUNET_CRYPTO_EddsaSignature *signature); const struct GNUNET_CRYPTO_EddsaSignature *signature);
/**
* Convert a signature (with purpose) to a JSON object representation.
*
* @param purpose purpose of the signature
* @param signature the signature
* @return the JSON reporesentation of the signature with purpose
*/
json_t *
TALER_json_from_ecdsa_sig (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
const struct GNUNET_CRYPTO_EcdsaSignature *signature);
/** /**
* Convert RSA public key to JSON. * Convert RSA public key to JSON.
* *
@ -108,17 +96,6 @@ json_t *
TALER_json_from_data (const void *data, size_t size); TALER_json_from_data (const void *data, size_t size);
/**
* Convert binary hash to a JSON string with the base32crockford
* encoding.
*
* @param hc binary data
* @return json string that encodes @a hc
*/
json_t *
TALER_json_from_hash (const struct GNUNET_HashCode *hc);
/** /**
* Parse given JSON object to Amount * Parse given JSON object to Amount
* *
@ -154,6 +131,27 @@ TALER_json_to_data (json_t *json,
void *out, void *out,
size_t out_size); size_t out_size);
/**
* Convert JSON to RSA public key.
*
* @param pk JSON encoding to convert
* @return corresponding public key
*/
struct GNUNET_CRYPTO_rsa_PublicKey *
TALER_json_to_rsa_public_key (json_t *json);
/**
* Convert JSON to RSA signature.
*
* @param pk JSON encoding to convert
* @return corresponding signature
*/
struct GNUNET_CRYPTO_rsa_Signature *
TALER_json_to_rsa_signature (json_t *json);
/** /**
* Check if the given wire format JSON object is correctly formatted * Check if the given wire format JSON object is correctly formatted
* *

View File

@ -22,7 +22,6 @@
#define _TALER_MINT_SERVICE_H #define _TALER_MINT_SERVICE_H
#include "taler_util.h" #include "taler_util.h"
#include <jansson.h>
/** /**
* @brief Handle to this library context * @brief Handle to this library context

View File

@ -23,7 +23,6 @@
#ifndef TALER_MINTDB_LIB_H #ifndef TALER_MINTDB_LIB_H
#define TALER_MINTDB_LIB_H #define TALER_MINTDB_LIB_H
#include <gnunet/gnunet_util_lib.h>
#include "taler_signatures.h" #include "taler_signatures.h"
/** /**

View File

@ -23,8 +23,6 @@
#define TALER_MINTDB_PLUGIN_H #define TALER_MINTDB_PLUGIN_H
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include "taler_util.h"
#include "taler_signatures.h"
#include "taler_mintdb_lib.h" #include "taler_mintdb_lib.h"
@ -685,7 +683,9 @@ struct TALER_MINTDB_Plugin
/** /**
* Insert a incoming transaction into reserves. New reserves are * Insert a incoming transaction into reserves. New reserves are
* also created through this function. * also created through this function. Note that this API call
* starts (and stops) its own transaction scope (so the application
* must not do so).
* *
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param db the database connection handle * @param db the database connection handle
@ -704,7 +704,7 @@ struct TALER_MINTDB_Plugin
const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_Amount *balance, const struct TALER_Amount *balance,
const char *details, const char *details,
const struct GNUNET_TIME_Absolute expiry); struct GNUNET_TIME_Absolute expiry);
/** /**
@ -1066,7 +1066,7 @@ struct TALER_MINTDB_Plugin
struct TALER_MINTDB_LinkDataList * struct TALER_MINTDB_LinkDataList *
(*get_link_data_list) (void *cls, (*get_link_data_list) (void *cls,
struct TALER_MINTDB_Session *sesssion, struct TALER_MINTDB_Session *sesssion,
const union TALER_CoinSpendPublicKeyP *coin_pub); const struct TALER_CoinSpendPublicKeyP *coin_pub);
/** /**
@ -1083,7 +1083,7 @@ struct TALER_MINTDB_Plugin
/** /**
* Obtain shared secret and transfer public key from the public key of * Obtain shared secret and transfer public key from the public key of
* the coin. This information and the link information returned by * the coin. This information and the link information returned by
* #TALER_db_get_link() enable the owner of an old coin to determine * @e get_link_data_list() enable the owner of an old coin to determine
* the private keys of the new coins after the melt. * the private keys of the new coins after the melt.
* *
* *
@ -1099,7 +1099,7 @@ struct TALER_MINTDB_Plugin
int int
(*get_transfer) (void *cls, (*get_transfer) (void *cls,
struct TALER_MINTDB_Session *sesssion, struct TALER_MINTDB_Session *sesssion,
const union TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_TransferPublicKeyP *transfer_pub, struct TALER_TransferPublicKeyP *transfer_pub,
struct TALER_EncryptedLinkSecretP *shared_secret_enc); struct TALER_EncryptedLinkSecretP *shared_secret_enc);
@ -1111,7 +1111,7 @@ struct TALER_MINTDB_Plugin
* @param sesssion database connection * @param sesssion database connection
* @param lock lock operation * @param lock lock operation
* @return #GNUNET_YES if known, * @return #GNUNET_YES if known,
* #GNUENT_NO if not, * #GNUNET_NO if not,
* #GNUNET_SYSERR on internal error * #GNUNET_SYSERR on internal error
*/ */
int int
@ -1147,7 +1147,7 @@ struct TALER_MINTDB_Plugin
struct TALER_MINTDB_TransactionList * struct TALER_MINTDB_TransactionList *
(*get_coin_transactions) (void *cls, (*get_coin_transactions) (void *cls,
struct TALER_MINTDB_Session *sesssion, struct TALER_MINTDB_Session *sesssion,
const union TALER_CoinSpendPublicKeyP *coin_pub); const struct TALER_CoinSpendPublicKeyP *coin_pub);
/** /**

View File

@ -108,7 +108,7 @@ struct TALER_PQ_QueryParam
/** /**
* End of query parameter specification. * End of query parameter specification.
*/ */
#define TALER_PQ_QUERY_PARAM_END { TALER_PQ_QF_END, NULL, 0 } #define TALER_PQ_query_param_end { TALER_PQ_QF_END, NULL, 0 }
/** /**
* Generate fixed-size query parameter with size given explicitly. * Generate fixed-size query parameter with size given explicitly.
@ -116,7 +116,7 @@ struct TALER_PQ_QueryParam
* @param x pointer to the query parameter to pass * @param x pointer to the query parameter to pass
* @param s number of bytes of @a x to use for the query * @param s number of bytes of @a x to use for the query
*/ */
#define TALER_PQ_QUERY_PARAM_PTR_SIZED(x,s) { TALER_PQ_QF_FIXED_BLOB, (x), (s) } #define TALER_PQ_query_param_fixed_size(x,s) { TALER_PQ_QF_FIXED_BLOB, (x), (s) }
/** /**
@ -125,7 +125,7 @@ struct TALER_PQ_QueryParam
* *
* @param x pointer to the query parameter to pass. * @param x pointer to the query parameter to pass.
*/ */
#define TALER_PQ_QUERY_PARAM_PTR(x) { TALER_PQ_QF_VARSIZE_BLOB, x, sizeof (*(x)) } #define TALER_PQ_query_param_auto_from_type(x) { TALER_PQ_QF_VARSIZE_BLOB, x, sizeof (*(x)) }
/** /**
@ -137,7 +137,7 @@ struct TALER_PQ_QueryParam
* @param x pointer to the query parameter to pass * @param x pointer to the query parameter to pass
*/ */
struct TALER_PQ_QueryParam struct TALER_PQ_QueryParam
TALER_PQ_QUERY_PARAM_AMOUNT_NBO(const struct TALER_AmountNBO *x); TALER_PQ_query_param_amount_nbo(const struct TALER_AmountNBO *x);
/** /**
@ -149,7 +149,7 @@ TALER_PQ_QUERY_PARAM_AMOUNT_NBO(const struct TALER_AmountNBO *x);
* @param x pointer to the query parameter to pass * @param x pointer to the query parameter to pass
*/ */
struct TALER_PQ_QueryParam struct TALER_PQ_QueryParam
TALER_PQ_QUERY_PARAM_AMOUNT(const struct TALER_Amount *x); TALER_PQ_query_param_amount(const struct TALER_Amount *x);
/** /**
@ -159,7 +159,7 @@ TALER_PQ_QUERY_PARAM_AMOUNT(const struct TALER_Amount *x);
* @param x the query parameter to pass. * @param x the query parameter to pass.
*/ */
struct TALER_PQ_QueryParam struct TALER_PQ_QueryParam
TALER_PQ_QUERY_PARAM_RSA_PUBLIC_KEY(const struct GNUNET_CRYPTO_rsa_PublicKey *x); TALER_PQ_query_param_rsa_public_key(const struct GNUNET_CRYPTO_rsa_PublicKey *x);
/** /**
@ -169,7 +169,7 @@ TALER_PQ_QUERY_PARAM_RSA_PUBLIC_KEY(const struct GNUNET_CRYPTO_rsa_PublicKey *x)
* @param x the query parameter to pass * @param x the query parameter to pass
*/ */
struct TALER_PQ_QueryParam struct TALER_PQ_QueryParam
TALER_PQ_QUERY_PARAM_RSA_SIGNATURE(const struct GNUNET_CRYPTO_rsa_Signature *x); TALER_PQ_query_param_rsa_signature(const struct GNUNET_CRYPTO_rsa_Signature *x);
/** /**
@ -179,7 +179,7 @@ TALER_PQ_QUERY_PARAM_RSA_SIGNATURE(const struct GNUNET_CRYPTO_rsa_Signature *x);
* @param x pointer to the query parameter to pass * @param x pointer to the query parameter to pass
*/ */
struct TALER_PQ_QueryParam struct TALER_PQ_QueryParam
TALER_PQ_QUERY_PARAM_ABSOLUTE_TIME(struct GNUNET_TIME_Absolute x); TALER_PQ_query_param_absolute_time(const struct GNUNET_TIME_Absolute *x);
/** /**
@ -277,7 +277,7 @@ struct TALER_PQ_ResultSpec
* *
* @return array last entry for the result specification to use * @return array last entry for the result specification to use
*/ */
#define TALER_PQ_RESULT_SPEC_END { TALER_PQ_RF_END, NULL, 0, NULL, NULL } #define TALER_PQ_result_spec_end { TALER_PQ_RF_END, NULL, 0, NULL, NULL }
/** /**
* We expect a fixed-size result, with size given explicitly * We expect a fixed-size result, with size given explicitly
@ -287,7 +287,7 @@ struct TALER_PQ_ResultSpec
* @param s number of bytes we should use in @a dst * @param s number of bytes we should use in @a dst
* @return array entry for the result specification to use * @return array entry for the result specification to use
*/ */
#define TALER_PQ_RESULT_SPEC_SIZED(name, dst, s) { TALER_PQ_RF_FIXED_BLOB, (void *) (dst), (s), (name), NULL } #define TALER_PQ_result_spec_fixed_size(name, dst, s) { TALER_PQ_RF_FIXED_BLOB, (void *) (dst), (s), (name), NULL }
/** /**
@ -297,7 +297,7 @@ struct TALER_PQ_ResultSpec
* @param dst point to where to store the result, type fits expected result size * @param dst point to where to store the result, type fits expected result size
* @return array entry for the result specification to use * @return array entry for the result specification to use
*/ */
#define TALER_PQ_RESULT_SPEC(name, dst) { TALER_PQ_RF_VARSIZE_BLOB, (void *) dst, sizeof (*(dst)), name, NULL } #define TALER_PQ_result_spec_auto_from_type(name, dst) { TALER_PQ_RF_FIXED_BLOB, (void *) (dst), sizeof (*(dst)), name, NULL }
/** /**
@ -309,7 +309,7 @@ struct TALER_PQ_ResultSpec
* @return array entry for the result specification to use * @return array entry for the result specification to use
*/ */
struct TALER_PQ_ResultSpec struct TALER_PQ_ResultSpec
TALER_PQ_RESULT_SPEC_VAR (const char *name, TALER_PQ_result_spec_variable_size (const char *name,
void **dst, void **dst,
size_t *sptr); size_t *sptr);
@ -322,7 +322,7 @@ TALER_PQ_RESULT_SPEC_VAR (const char *name,
* @return array entry for the result specification to use * @return array entry for the result specification to use
*/ */
struct TALER_PQ_ResultSpec struct TALER_PQ_ResultSpec
TALER_PQ_RESULT_SPEC_AMOUNT_NBO (const char *name, TALER_PQ_result_spec_amount_nbo (const char *name,
struct TALER_AmountNBO *amount); struct TALER_AmountNBO *amount);
@ -334,7 +334,7 @@ TALER_PQ_RESULT_SPEC_AMOUNT_NBO (const char *name,
* @return array entry for the result specification to use * @return array entry for the result specification to use
*/ */
struct TALER_PQ_ResultSpec struct TALER_PQ_ResultSpec
TALER_PQ_RESULT_SPEC_AMOUNT (const char *name, TALER_PQ_result_spec_amount (const char *name,
struct TALER_Amount *amount); struct TALER_Amount *amount);
@ -346,7 +346,7 @@ TALER_PQ_RESULT_SPEC_AMOUNT (const char *name,
* @return array entry for the result specification to use * @return array entry for the result specification to use
*/ */
struct TALER_PQ_ResultSpec struct TALER_PQ_ResultSpec
TALER_PQ_RESULT_SPEC_RSA_PUBLIC_KEY (const char *name, TALER_PQ_result_spec_rsa_public_key (const char *name,
struct GNUNET_CRYPTO_rsa_PublicKey **rsa); struct GNUNET_CRYPTO_rsa_PublicKey **rsa);
@ -358,7 +358,7 @@ TALER_PQ_RESULT_SPEC_RSA_PUBLIC_KEY (const char *name,
* @return array entry for the result specification to use * @return array entry for the result specification to use
*/ */
struct TALER_PQ_ResultSpec struct TALER_PQ_ResultSpec
TALER_PQ_RESULT_SPEC_RSA_SIGNATURE (const char *name, TALER_PQ_result_spec_rsa_signature (const char *name,
struct GNUNET_CRYPTO_rsa_Signature **sig); struct GNUNET_CRYPTO_rsa_Signature **sig);
@ -370,7 +370,7 @@ TALER_PQ_RESULT_SPEC_RSA_SIGNATURE (const char *name,
* @return array entry for the result specification to use * @return array entry for the result specification to use
*/ */
struct TALER_PQ_ResultSpec struct TALER_PQ_ResultSpec
TALER_PQ_RESULT_SPEC_ABSOLUTE_TIME (const char *name, TALER_PQ_result_spec_absolute_time (const char *name,
struct GNUNET_TIME_Absolute *at); struct GNUNET_TIME_Absolute *at);
@ -394,7 +394,7 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
* is returned. * is returned.
* *
* @param result result to process * @param result result to process
* @param[in|out] rs result specification to extract for * @param[in,out] rs result specification to extract for
* @param row row from the result to extract * @param row row from the result to extract
* @return * @return
* #GNUNET_YES if all results could be extracted * #GNUNET_YES if all results could be extracted

View File

@ -122,16 +122,6 @@
/*******************/ /*******************/
/**
* ECDSA test signature.
*/
#define TALER_SIGNATURE_CLIENT_TEST_ECDSA 1300
/**
* ECDSA test signature.
*/
#define TALER_SIGNATURE_MINT_TEST_ECDSA 1301
/** /**
* EdDSA test signature. * EdDSA test signature.
*/ */
@ -207,7 +197,7 @@ struct TALER_DepositRequestPS
{ {
/** /**
* Purpose must be #TALER_SIGNATURE_WALLET_COIN_DEPOSIT. * Purpose must be #TALER_SIGNATURE_WALLET_COIN_DEPOSIT.
* Used for an ECDSA signature with the `union TALER_CoinSpendPublicKeyP`. * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`.
*/ */
struct GNUNET_CRYPTO_EccSignaturePurpose purpose; struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
@ -283,9 +273,9 @@ struct TALER_DepositRequestPS
/** /**
* The coin's public key. This is the value that must have been * The coin's public key. This is the value that must have been
* signed (blindly) by the Mint. The deposit request is to be * signed (blindly) by the Mint. The deposit request is to be
* signed by the corresponding private key (using ECDSA). * signed by the corresponding private key (using EdDSA).
*/ */
union TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
}; };
@ -341,9 +331,9 @@ struct TALER_DepositConfirmationPS
/** /**
* The coin's public key. This is the value that must have been * The coin's public key. This is the value that must have been
* signed (blindly) by the Mint. The deposit request is to be * signed (blindly) by the Mint. The deposit request is to be
* signed by the corresponding private key (using ECDSA). * signed by the corresponding private key (using EdDSA).
*/ */
union TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
/** /**
* The Merchant's public key. Allows the merchant to later refund * The Merchant's public key. Allows the merchant to later refund
@ -363,7 +353,7 @@ struct TALER_RefreshMeltCoinAffirmationPS
{ {
/** /**
* Purpose is #TALER_SIGNATURE_WALLET_COIN_MELT. * Purpose is #TALER_SIGNATURE_WALLET_COIN_MELT.
* Used for an ECDSA signature with the `union TALER_CoinSpendPublicKeyP`. * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`.
*/ */
struct GNUNET_CRYPTO_EccSignaturePurpose purpose; struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
@ -396,9 +386,9 @@ struct TALER_RefreshMeltCoinAffirmationPS
/** /**
* The coin's public key. This is the value that must have been * The coin's public key. This is the value that must have been
* signed (blindly) by the Mint. The deposit request is to be * signed (blindly) by the Mint. The deposit request is to be
* signed by the corresponding private key (using ECDSA). * signed by the corresponding private key (using EdDSA).
*/ */
union TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
}; };

View File

@ -108,7 +108,7 @@ TALER_config_get_denom (struct GNUNET_CONFIGURATION_Handle *cfg,
* @return a pointer to the dir path (to be freed by the caller) * @return a pointer to the dir path (to be freed by the caller)
*/ */
char * char *
TALER_os_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind); TALER_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind);
/** /**

View File

@ -21,9 +21,7 @@
#include "platform.h" #include "platform.h"
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include <libpq-fe.h> #include <libpq-fe.h>
#include "taler_util.h"
#include "taler_mintdb_plugin.h" #include "taler_mintdb_plugin.h"
#include "taler_mintdb_lib.h"
/** /**
* Mint directory with the keys. * Mint directory with the keys.

View File

@ -22,8 +22,6 @@
* @author Christian Grothoff * @author Christian Grothoff
*/ */
#include <platform.h> #include <platform.h>
#include <gnunet/gnunet_util_lib.h>
#include "taler_util.h"
#include "taler_mintdb_lib.h" #include "taler_mintdb_lib.h"
/** /**

View File

@ -22,11 +22,7 @@
#include "platform.h" #include "platform.h"
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include <libpq-fe.h> #include <libpq-fe.h>
#include "taler_util.h"
#include "taler_signatures.h"
#include "taler_pq_lib.h"
#include "taler_mintdb_plugin.h" #include "taler_mintdb_plugin.h"
#include "taler_mintdb_lib.h"
/** /**
* After what time to inactive reserves expire? * After what time to inactive reserves expire?
@ -98,6 +94,9 @@ main (int argc, char *const *argv)
{ {
fprintf (stderr, fprintf (stderr,
"Mint directory not given\n"); "Mint directory not given\n");
GNUNET_free_non_null (add_str);
GNUNET_free_non_null (details);
GNUNET_free_non_null (reserve_pub_str);
return 1; return 1;
} }
if ((NULL == reserve_pub_str) || if ((NULL == reserve_pub_str) ||
@ -109,6 +108,9 @@ main (int argc, char *const *argv)
{ {
fprintf (stderr, fprintf (stderr,
"Parsing reserve key invalid\n"); "Parsing reserve key invalid\n");
GNUNET_free_non_null (add_str);
GNUNET_free_non_null (details);
GNUNET_free_non_null (reserve_pub_str);
return 1; return 1;
} }
if ( (NULL == add_str) || if ( (NULL == add_str) ||
@ -119,6 +121,9 @@ main (int argc, char *const *argv)
fprintf (stderr, fprintf (stderr,
"Failed to parse currency amount `%s'\n", "Failed to parse currency amount `%s'\n",
add_str); add_str);
GNUNET_free_non_null (add_str);
GNUNET_free_non_null (details);
GNUNET_free_non_null (reserve_pub_str);
return 1; return 1;
} }
@ -126,6 +131,8 @@ main (int argc, char *const *argv)
{ {
fprintf (stderr, fprintf (stderr,
"No wiring details given (justification required)\n"); "No wiring details given (justification required)\n");
GNUNET_free_non_null (add_str);
GNUNET_free_non_null (reserve_pub_str);
return 1; return 1;
} }
@ -134,6 +141,9 @@ main (int argc, char *const *argv)
{ {
fprintf (stderr, fprintf (stderr,
"Failed to load mint configuration\n"); "Failed to load mint configuration\n");
GNUNET_free_non_null (add_str);
GNUNET_free_non_null (details);
GNUNET_free_non_null (reserve_pub_str);
return 1; return 1;
} }
ret = 1; ret = 1;
@ -153,34 +163,23 @@ main (int argc, char *const *argv)
"Failed to initialize DB session\n"); "Failed to initialize DB session\n");
goto cleanup; goto cleanup;
} }
if (GNUNET_OK !=
plugin->start (plugin->cls,
session))
{
fprintf (stderr,
"Failed to start transaction\n");
goto cleanup;
}
expiration = GNUNET_TIME_relative_to_absolute (RESERVE_EXPIRATION); expiration = GNUNET_TIME_relative_to_absolute (RESERVE_EXPIRATION);
if (GNUNET_OK != ret = plugin->reserves_in_insert (plugin->cls,
plugin->reserves_in_insert (plugin->cls,
session, session,
&reserve_pub, &reserve_pub,
&add_value, &add_value,
details, details,
expiration)) expiration);
if (GNUNET_SYSERR == ret)
{ {
fprintf (stderr, fprintf (stderr,
"Failed to update reserve.\n"); "Failed to update reserve.\n");
goto cleanup; goto cleanup;
} }
if (GNUNET_OK != if (GNUNET_NO == ret)
plugin->commit (plugin->cls,
session))
{ {
fprintf (stderr, fprintf (stderr,
"Failed to commit transaction\n"); "Record exists, reserve not updated.\n");
goto cleanup;
} }
ret = 0; ret = 0;
cleanup: cleanup:
@ -188,6 +187,9 @@ main (int argc, char *const *argv)
TALER_MINTDB_plugin_unload (plugin); TALER_MINTDB_plugin_unload (plugin);
if (NULL != cfg) if (NULL != cfg)
GNUNET_CONFIGURATION_destroy (cfg); GNUNET_CONFIGURATION_destroy (cfg);
GNUNET_free_non_null (add_str);
GNUNET_free_non_null (details);
GNUNET_free_non_null (reserve_pub_str);
return ret; return ret;
} }

View File

@ -26,8 +26,6 @@
#include <jansson.h> #include <jansson.h>
#include <microhttpd.h> #include <microhttpd.h>
#include <pthread.h> #include <pthread.h>
#include "taler_signatures.h"
#include "taler_util.h"
#include "taler-mint-httpd_parsing.h" #include "taler-mint-httpd_parsing.h"
#include "taler-mint-httpd_mhd.h" #include "taler-mint-httpd_mhd.h"
#include "taler-mint-httpd_deposit.h" #include "taler-mint-httpd_deposit.h"
@ -232,13 +230,6 @@ handle_mhd_request (void *cls,
"Only POST is allowed", 0, "Only POST is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED }, &TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/test/ecdsa", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0,
&TMH_TEST_handler_test_ecdsa, MHD_HTTP_OK },
{ "/test/ecdsa", NULL, "text/plain",
"Only POST is allowed", 0,
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
{ "/test/eddsa", MHD_HTTP_METHOD_POST, "application/json", { "/test/eddsa", MHD_HTTP_METHOD_POST, "application/json",
NULL, 0, NULL, 0,
&TMH_TEST_handler_test_eddsa, MHD_HTTP_OK }, &TMH_TEST_handler_test_eddsa, MHD_HTTP_OK },

View File

@ -21,12 +21,8 @@
#include "platform.h" #include "platform.h"
#include <pthread.h> #include <pthread.h>
#include <jansson.h> #include <jansson.h>
#include "taler-mint-httpd_db.h"
#include "taler_signatures.h"
#include "taler-mint-httpd_responses.h" #include "taler-mint-httpd_responses.h"
#include "taler_util.h"
#include "taler-mint-httpd_keystate.h" #include "taler-mint-httpd_keystate.h"
#include "taler_mintdb_lib.h"
/** /**
@ -926,7 +922,7 @@ check_commitment (struct MHD_Connection *connection,
for (j = 0; j < num_newcoins; j++) for (j = 0; j < num_newcoins; j++)
{ {
struct TALER_RefreshLinkDecrypted *link_data; struct TALER_RefreshLinkDecrypted *link_data;
union TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
struct GNUNET_HashCode h_msg; struct GNUNET_HashCode h_msg;
char *buf; char *buf;
size_t buf_len; size_t buf_len;
@ -942,10 +938,10 @@ check_commitment (struct MHD_Connection *connection,
? GNUNET_NO : GNUNET_SYSERR; ? GNUNET_NO : GNUNET_SYSERR;
} }
GNUNET_CRYPTO_ecdsa_key_get_public (&link_data->coin_priv.ecdsa_priv, GNUNET_CRYPTO_eddsa_key_get_public (&link_data->coin_priv.eddsa_priv,
&coin_pub.ecdsa_pub); &coin_pub.eddsa_pub);
GNUNET_CRYPTO_hash (&coin_pub, GNUNET_CRYPTO_hash (&coin_pub,
sizeof (union TALER_CoinSpendPublicKeyP), sizeof (struct TALER_CoinSpendPublicKeyP),
&h_msg); &h_msg);
if (0 == (buf_len = if (0 == (buf_len =
GNUNET_CRYPTO_rsa_blind (&h_msg, GNUNET_CRYPTO_rsa_blind (&h_msg,
@ -1248,7 +1244,7 @@ TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
*/ */
int int
TMH_DB_execute_refresh_link (struct MHD_Connection *connection, TMH_DB_execute_refresh_link (struct MHD_Connection *connection,
const union TALER_CoinSpendPublicKeyP *coin_pub) const struct TALER_CoinSpendPublicKeyP *coin_pub)
{ {
int res; int res;
struct TALER_MINTDB_Session *session; struct TALER_MINTDB_Session *session;

View File

@ -22,8 +22,6 @@
#define TALER_MINT_HTTPD_DB_H #define TALER_MINT_HTTPD_DB_H
#include <microhttpd.h> #include <microhttpd.h>
#include <gnunet/gnunet_util_lib.h>
#include "taler_util.h"
#include "taler_mintdb_plugin.h" #include "taler_mintdb_plugin.h"
@ -166,7 +164,7 @@ TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
*/ */
int int
TMH_DB_execute_refresh_link (struct MHD_Connection *connection, TMH_DB_execute_refresh_link (struct MHD_Connection *connection,
const union TALER_CoinSpendPublicKeyP *coin_pub); const struct TALER_CoinSpendPublicKeyP *coin_pub);
#endif #endif

View File

@ -30,11 +30,7 @@
#include <jansson.h> #include <jansson.h>
#include <microhttpd.h> #include <microhttpd.h>
#include <pthread.h> #include <pthread.h>
#include "taler_mintdb_plugin.h"
#include "taler_signatures.h"
#include "taler_util.h"
#include "taler-mint-httpd_parsing.h" #include "taler-mint-httpd_parsing.h"
#include "taler-mint-httpd_db.h"
#include "taler-mint-httpd_deposit.h" #include "taler-mint-httpd_deposit.h"
#include "taler-mint-httpd_responses.h" #include "taler-mint-httpd_responses.h"
#include "taler-mint-httpd_keystate.h" #include "taler-mint-httpd_keystate.h"
@ -73,10 +69,10 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
dr.merchant = deposit->merchant_pub; dr.merchant = deposit->merchant_pub;
dr.coin_pub = deposit->coin.coin_pub; dr.coin_pub = deposit->coin.coin_pub;
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CRYPTO_ecdsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
&dr.purpose, &dr.purpose,
&deposit->csig.ecdsa_signature, &deposit->csig.eddsa_signature,
&deposit->coin.coin_pub.ecdsa_pub)) &deposit->coin.coin_pub.eddsa_pub))
{ {
TALER_LOG_WARNING ("Invalid signature on /deposit request\n"); TALER_LOG_WARNING ("Invalid signature on /deposit request\n");
return TMH_RESPONSE_reply_signature_invalid (connection, return TMH_RESPONSE_reply_signature_invalid (connection,

View File

@ -24,9 +24,6 @@
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include <jansson.h> #include <jansson.h>
#include <microhttpd.h> #include <microhttpd.h>
#include "taler_mintdb_plugin.h"
#include "taler_signatures.h"
#include "taler_util.h"
#include "taler-mint-httpd_parsing.h" #include "taler-mint-httpd_parsing.h"
#include "taler-mint-httpd_mhd.h" #include "taler-mint-httpd_mhd.h"
#include "taler-mint-httpd_refresh.h" #include "taler-mint-httpd_refresh.h"
@ -269,10 +266,10 @@ verify_coin_public_info (struct MHD_Connection *connection,
TMH_KS_release (key_state); TMH_KS_release (key_state);
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CRYPTO_ecdsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT,
&body.purpose, &body.purpose,
&melt_detail->melt_sig.ecdsa_signature, &melt_detail->melt_sig.eddsa_signature,
&melt_detail->coin_info.coin_pub.ecdsa_pub)) &melt_detail->coin_info.coin_pub.eddsa_pub))
{ {
if (MHD_YES != if (MHD_YES !=
TMH_RESPONSE_reply_signature_invalid (connection, TMH_RESPONSE_reply_signature_invalid (connection,
@ -439,7 +436,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
{ {
if (0 == memcmp (&coin_melt_details[i].coin_info.coin_pub, if (0 == memcmp (&coin_melt_details[i].coin_info.coin_pub,
&coin_melt_details[j].coin_info.coin_pub, &coin_melt_details[j].coin_info.coin_pub,
sizeof (union TALER_CoinSpendPublicKeyP))) sizeof (struct TALER_CoinSpendPublicKeyP)))
{ {
for (j=0;j<i;j++) for (j=0;j<i;j++)
{ {
@ -458,7 +455,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
&coin_melt_details[i].melt_amount_with_fee); &coin_melt_details[i].melt_amount_with_fee);
GNUNET_CRYPTO_hash_context_read (hash_context, GNUNET_CRYPTO_hash_context_read (hash_context,
&coin_melt_details[i].coin_info.coin_pub, &coin_melt_details[i].coin_info.coin_pub,
sizeof (union TALER_CoinSpendPublicKeyP)); sizeof (struct TALER_CoinSpendPublicKeyP));
GNUNET_CRYPTO_hash_context_read (hash_context, GNUNET_CRYPTO_hash_context_read (hash_context,
&melt_amount, &melt_amount,
sizeof (struct TALER_AmountNBO)); sizeof (struct TALER_AmountNBO));
@ -891,13 +888,13 @@ TMH_REFRESH_handler_refresh_link (struct TMH_RequestHandler *rh,
const char *upload_data, const char *upload_data,
size_t *upload_data_size) size_t *upload_data_size)
{ {
union TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
int res; int res;
res = TMH_PARSE_mhd_request_arg_data (connection, res = TMH_PARSE_mhd_request_arg_data (connection,
"coin_pub", "coin_pub",
&coin_pub, &coin_pub,
sizeof (union TALER_CoinSpendPublicKeyP)); sizeof (struct TALER_CoinSpendPublicKeyP));
if (GNUNET_SYSERR == res) if (GNUNET_SYSERR == res)
return MHD_NO; return MHD_NO;
if (GNUNET_OK != res) if (GNUNET_OK != res)

View File

@ -303,7 +303,7 @@ TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection)
*/ */
int int
TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection, TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection,
const union TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_wire,
const struct GNUNET_HashCode *h_contract, const struct GNUNET_HashCode *h_contract,
uint64_t transaction_id, uint64_t transaction_id,
@ -381,8 +381,8 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
&deposit->deposit_fee); &deposit->deposit_fee);
dr.merchant = deposit->merchant_pub; dr.merchant = deposit->merchant_pub;
dr.coin_pub = deposit->coin.coin_pub; dr.coin_pub = deposit->coin.coin_pub;
transaction = TALER_json_from_ecdsa_sig (&dr.purpose, transaction = TALER_json_from_eddsa_sig (&dr.purpose,
&deposit->csig.ecdsa_signature); &deposit->csig.eddsa_signature);
break; break;
} }
case TALER_MINTDB_TT_REFRESH_MELT: case TALER_MINTDB_TT_REFRESH_MELT:
@ -400,8 +400,8 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
TALER_amount_hton (&ms.melt_fee, TALER_amount_hton (&ms.melt_fee,
&melt->melt_fee); &melt->melt_fee);
ms.coin_pub = melt->coin.coin_pub; ms.coin_pub = melt->coin.coin_pub;
transaction = TALER_json_from_ecdsa_sig (&ms.purpose, transaction = TALER_json_from_eddsa_sig (&ms.purpose,
&melt->coin_sig.ecdsa_signature); &melt->coin_sig.eddsa_signature);
} }
break; break;
case TALER_MINTDB_TT_LOCK: case TALER_MINTDB_TT_LOCK:
@ -678,7 +678,7 @@ TMH_RESPONSE_reply_withdraw_sign_success (struct MHD_Connection *connection,
*/ */
int int
TMH_RESPONSE_reply_refresh_melt_insufficient_funds (struct MHD_Connection *connection, TMH_RESPONSE_reply_refresh_melt_insufficient_funds (struct MHD_Connection *connection,
const union TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_Amount coin_value, struct TALER_Amount coin_value,
struct TALER_MINTDB_TransactionList *tl, struct TALER_MINTDB_TransactionList *tl,
struct TALER_Amount requested, struct TALER_Amount requested,
@ -692,7 +692,7 @@ TMH_RESPONSE_reply_refresh_melt_insufficient_funds (struct MHD_Connection *conne
"{s:s, s:o, s:o, s:o, s:o, s:o}", "{s:s, s:o, s:o, s:o, s:o, s:o}",
"error", "insufficient funds", "error", "insufficient funds",
"coin-pub", TALER_json_from_data (coin_pub, "coin-pub", TALER_json_from_data (coin_pub,
sizeof (union TALER_CoinSpendPublicKeyP)), sizeof (struct TALER_CoinSpendPublicKeyP)),
"original-value", TALER_json_from_amount (&coin_value), "original-value", TALER_json_from_amount (&coin_value),
"residual-value", TALER_json_from_amount (&residual), "residual-value", TALER_json_from_amount (&residual),
"requested-value", TALER_json_from_amount (&requested), "requested-value", TALER_json_from_amount (&requested),
@ -814,7 +814,7 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
json_object_set_new (rm_json, json_object_set_new (rm_json,
"coin_pub", "coin_pub",
TALER_json_from_data (&rm->coin.coin_pub, TALER_json_from_data (&rm->coin.coin_pub,
sizeof (union TALER_CoinSpendPublicKeyP))); sizeof (struct TALER_CoinSpendPublicKeyP)));
json_object_set_new (rm_json, json_object_set_new (rm_json,
"melt_amount_with_fee", "melt_amount_with_fee",
TALER_json_from_amount (&rm->amount_with_fee)); TALER_json_from_amount (&rm->amount_with_fee));
@ -856,7 +856,7 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
json_object_set_new (cc_json, json_object_set_new (cc_json,
"coin_priv_enc", "coin_priv_enc",
TALER_json_from_data (cc->refresh_link->coin_priv_enc, TALER_json_from_data (cc->refresh_link->coin_priv_enc,
sizeof (union TALER_CoinSpendPrivateKeyP))); sizeof (struct TALER_CoinSpendPrivateKeyP)));
json_object_set_new (cc_json, json_object_set_new (cc_json,
"blinding_key_enc", "blinding_key_enc",
TALER_json_from_data (cc->refresh_link->blinding_key_enc, TALER_json_from_data (cc->refresh_link->blinding_key_enc,
@ -933,7 +933,7 @@ TMH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
json_object_set_new (obj, json_object_set_new (obj,
"link_enc", "link_enc",
TALER_json_from_data (ldl->link_data_enc->coin_priv_enc, TALER_json_from_data (ldl->link_data_enc->coin_priv_enc,
sizeof (union TALER_CoinSpendPrivateKeyP) + sizeof (struct TALER_CoinSpendPrivateKeyP) +
ldl->link_data_enc->blinding_key_enc_size)); ldl->link_data_enc->blinding_key_enc_size));
json_object_set_new (obj, json_object_set_new (obj,
"denom_pub", "denom_pub",

View File

@ -200,7 +200,7 @@ TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection);
*/ */
int int
TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection, TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection,
const union TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_wire,
const struct GNUNET_HashCode *h_contract, const struct GNUNET_HashCode *h_contract,
uint64_t transaction_id, uint64_t transaction_id,
@ -291,7 +291,7 @@ TMH_RESPONSE_reply_refresh_melt_success (struct MHD_Connection *connection,
*/ */
int int
TMH_RESPONSE_reply_refresh_melt_insufficient_funds (struct MHD_Connection *connection, TMH_RESPONSE_reply_refresh_melt_insufficient_funds (struct MHD_Connection *connection,
const union TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_Amount coin_value, struct TALER_Amount coin_value,
struct TALER_MINTDB_TransactionList *tl, struct TALER_MINTDB_TransactionList *tl,
struct TALER_Amount requested, struct TALER_Amount requested,

View File

@ -24,7 +24,6 @@
#include <jansson.h> #include <jansson.h>
#include <microhttpd.h> #include <microhttpd.h>
#include "taler_signatures.h" #include "taler_signatures.h"
#include "taler_util.h"
#include "taler-mint-httpd_test.h" #include "taler-mint-httpd_test.h"
#include "taler-mint-httpd_parsing.h" #include "taler-mint-httpd_parsing.h"
#include "taler-mint-httpd_responses.h" #include "taler-mint-httpd_responses.h"
@ -296,98 +295,10 @@ TMH_TEST_handler_test_ecdhe (struct TMH_RequestHandler *rh,
} }
/**
* Handle a "/test/ecdsa" request. Parses the JSON in the post,
* which must contain a "ecdsa_pub" with a public key and an
*"ecdsa_sig" with the corresponding signature for a purpose
* of #TALER_SIGNATURE_CLIENT_TEST_ECDSA. If the signature is
* valid, a reply with a #TALER_SIGNATURE_MINT_TEST_ECDSA is
* returned using the same JSON format.
*
* @param rh context of the handler
* @param connection the MHD connection to handle
* @param[in,out] connection_cls the connection's closure (can be updated)
* @param upload_data upload data
* @param[in,out] upload_data_size number of bytes (left) in @a upload_data
* @return MHD result code
*/
int
TMH_TEST_handler_test_ecdsa (struct TMH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size)
{
json_t *json;
int res;
struct GNUNET_CRYPTO_EcdsaPublicKey pub;
struct GNUNET_CRYPTO_EcdsaSignature sig;
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
struct TMH_PARSE_FieldSpecification spec[] = {
TMH_PARSE_MEMBER_FIXED ("ecdsa_pub", &pub),
TMH_PARSE_MEMBER_FIXED ("ecdsa_sig", &sig),
TMH_PARSE_MEMBER_END
};
struct GNUNET_CRYPTO_EcdsaPrivateKey *pk;
res = TMH_PARSE_post_json (connection,
connection_cls,
upload_data,
upload_data_size,
&json);
if (GNUNET_SYSERR == res)
return MHD_NO;
if ( (GNUNET_NO == res) || (NULL == json) )
return MHD_YES;
res = TMH_PARSE_json_data (connection,
json,
spec);
json_decref (json);
if (GNUNET_YES != res)
return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
purpose.purpose = htonl (TALER_SIGNATURE_CLIENT_TEST_ECDSA);
if (GNUNET_OK !=
GNUNET_CRYPTO_ecdsa_verify (TALER_SIGNATURE_CLIENT_TEST_ECDSA,
&purpose,
&sig,
&pub))
{
TMH_PARSE_release_data (spec);
return TMH_RESPONSE_reply_signature_invalid (connection,
"ecdsa_sig");
}
TMH_PARSE_release_data (spec);
pk = GNUNET_CRYPTO_ecdsa_key_create ();
purpose.purpose = htonl (TALER_SIGNATURE_MINT_TEST_ECDSA);
if (GNUNET_OK !=
GNUNET_CRYPTO_ecdsa_sign (pk,
&purpose,
&sig))
{
GNUNET_free (pk);
return TMH_RESPONSE_reply_internal_error (connection,
"Failed to ECDSA-sign");
}
GNUNET_CRYPTO_ecdsa_key_get_public (pk,
&pub);
GNUNET_free (pk);
return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:o, s:o}",
"ecdsa_pub",
TALER_json_from_data (&pub,
sizeof (pub)),
"ecdsa_sig",
TALER_json_from_data (&sig,
sizeof (sig)));
}
/** /**
* Handle a "/test/eddsa" request. Parses the JSON in the post, * Handle a "/test/eddsa" request. Parses the JSON in the post,
* which must contain a "eddsa_pub" with a public key and an * which must contain a "eddsa_pub" with a public key and an
*"ecdsa_sig" with the corresponding signature for a purpose *"eddsa_sig" with the corresponding signature for a purpose
* of #TALER_SIGNATURE_CLIENT_TEST_EDDSA. If the signature is * of #TALER_SIGNATURE_CLIENT_TEST_EDDSA. If the signature is
* valid, a reply with a #TALER_SIGNATURE_MINT_TEST_EDDSA is * valid, a reply with a #TALER_SIGNATURE_MINT_TEST_EDDSA is
* returned using the same JSON format. * returned using the same JSON format.
@ -583,7 +494,7 @@ TMH_TEST_handler_test_transfer (struct TMH_RequestHandler *rh,
int res; int res;
struct TALER_EncryptedLinkSecretP secret_enc; struct TALER_EncryptedLinkSecretP secret_enc;
struct TALER_TransferPrivateKeyP trans_priv; struct TALER_TransferPrivateKeyP trans_priv;
union TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
struct TMH_PARSE_FieldSpecification spec[] = { struct TMH_PARSE_FieldSpecification spec[] = {
TMH_PARSE_MEMBER_FIXED ("secret_enc", &secret_enc), TMH_PARSE_MEMBER_FIXED ("secret_enc", &secret_enc),
TMH_PARSE_MEMBER_FIXED ("trans_priv", &trans_priv), TMH_PARSE_MEMBER_FIXED ("trans_priv", &trans_priv),

View File

@ -121,29 +121,6 @@ TMH_TEST_handler_test_ecdhe (struct TMH_RequestHandler *rh,
size_t *upload_data_size); size_t *upload_data_size);
/**
* Handle a "/test/ecdsa" request. Parses the JSON in the post,
* which must contain a "ecdsa_pub" with a public key and an
*"ecdsa_sig" with the corresponding signature for a purpose
* of #TALER_SIGNATURE_CLIENT_TEST_ECDSA. If the signature is
* valid, a reply with a #TALER_SIGNATURE_MINT_TEST_ECDSA is
* returned using the same JSON format.
*
* @param rh context of the handler
* @param connection the MHD connection to handle
* @param[in,out] connection_cls the connection's closure (can be updated)
* @param upload_data upload data
* @param[in,out] upload_data_size number of bytes (left) in @a upload_data
* @return MHD result code
*/
int
TMH_TEST_handler_test_ecdsa (struct TMH_RequestHandler *rh,
struct MHD_Connection *connection,
void **connection_cls,
const char *upload_data,
size_t *upload_data_size);
/** /**
* Handle a "/test/eddsa" request. Parses the JSON in the post, * Handle a "/test/eddsa" request. Parses the JSON in the post,
* which must contain a "eddsa_pub" with a public key and an * which must contain a "eddsa_pub" with a public key and an

View File

@ -20,7 +20,6 @@
* @author Sree Harsha Totakura <sreeharsha@totakura.in> * @author Sree Harsha Totakura <sreeharsha@totakura.in>
*/ */
#include "platform.h" #include "platform.h"
#include "taler_mintdb_lib.h"
#include "taler_mintdb_plugin.h" #include "taler_mintdb_plugin.h"
#include <ltdl.h> #include <ltdl.h>
@ -112,7 +111,7 @@ plugin_init ()
opath = lt_dlgetsearchpath (); opath = lt_dlgetsearchpath ();
if (NULL != opath) if (NULL != opath)
old_dlsearchpath = GNUNET_strdup (opath); old_dlsearchpath = GNUNET_strdup (opath);
path = TALER_os_installation_get_path (GNUNET_OS_IPK_LIBDIR); path = TALER_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR);
if (NULL != path) if (NULL != path)
{ {
if (NULL != opath) if (NULL != opath)

View File

@ -23,7 +23,6 @@
*/ */
#include "platform.h" #include "platform.h"
#include "taler_pq_lib.h" #include "taler_pq_lib.h"
#include "taler_signatures.h"
#include "taler_mintdb_plugin.h" #include "taler_mintdb_plugin.h"
#include <pthread.h> #include <pthread.h>
#include <libpq-fe.h> #include <libpq-fe.h>
@ -62,6 +61,12 @@
PQclear (result); result = NULL; \ PQclear (result); result = NULL; \
} while (0) } while (0)
#define SQLEXEC_IGNORE_ERROR_(conn, sql, result) \
do { \
result = PQexec (conn, sql); \
PQclear (result); result = NULL; \
} while (0)
/** /**
* Handle for a database session (per-thread, for transactions). * Handle for a database session (per-thread, for transactions).
@ -172,6 +177,7 @@ postgres_create_tables (void *cls,
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
#define SQLEXEC(sql) SQLEXEC_(conn, sql, result); #define SQLEXEC(sql) SQLEXEC_(conn, sql, result);
#define SQLEXEC_INDEX(sql) SQLEXEC_IGNORE_ERROR_(conn, sql, result);
/* Denomination table for holding the publicly available information of /* Denomination table for holding the publicly available information of
denominations keys. The denominations are to be referred to by using denominations keys. The denominations are to be referred to by using
foreign keys. The denominations are deleted by a housekeeping tool; foreign keys. The denominations are deleted by a housekeeping tool;
@ -216,14 +222,14 @@ postgres_create_tables (void *cls,
",balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" ",balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
",details VARCHAR NOT NULL " ",details VARCHAR NOT NULL "
",expiration_date INT8 NOT NULL" ",expiration_date INT8 NOT NULL"
" CONSTRAINT unique_details PRIMARY KEY (reserve_pub,details)" ",PRIMARY KEY (reserve_pub,details)"
");"); ");");
/* Create indices on reserves_in */ /* Create indices on reserves_in */
SQLEXEC ("CREATE INDEX reserves_in_reserve_pub_index" SQLEXEC_INDEX ("CREATE INDEX reserves_in_reserve_pub_index"
" ON reserves_in (reserve_pub);"); " ON reserves_in (reserve_pub);");
SQLEXEC ("CREATE INDEX reserves_in_reserve_pub_details_index" SQLEXEC_INDEX ("CREATE INDEX reserves_in_reserve_pub_details_index"
" ON reserves_in (reserve_pub,details);"); " ON reserves_in (reserve_pub,details);");
SQLEXEC ("CREATE INDEX expiration_index" SQLEXEC_INDEX ("CREATE INDEX expiration_index"
" ON reserves_in (expiration_date);"); " ON reserves_in (expiration_date);");
/* Table with the withdraw operations that have been performed on a reserve. /* Table with the withdraw operations that have been performed on a reserve.
TODO: maybe rename to "reserves_out"? TODO: maybe rename to "reserves_out"?
@ -237,7 +243,7 @@ postgres_create_tables (void *cls,
",reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)" ",reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)"
");"); ");");
/* Index blindcoins(reserve_pub) for get_reserves_blindcoins statement */ /* Index blindcoins(reserve_pub) for get_reserves_blindcoins statement */
SQLEXEC ("CREATE INDEX collectable_blindcoins_reserve_pub_index ON" SQLEXEC_INDEX ("CREATE INDEX collectable_blindcoins_reserve_pub_index ON"
" collectable_blindcoins (reserve_pub)"); " collectable_blindcoins (reserve_pub)");
/* Table with coins that have been (partially) spent, used to detect /* Table with coins that have been (partially) spent, used to detect
double-spending. double-spending.
@ -302,7 +308,7 @@ postgres_create_tables (void *cls,
")"); ")");
SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_melt" SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_melt"
"(" "("
" session_hash BYTEA NOT NULL CHECK(LENGTH(session_hash=64)) REFERENCES refresh_sessions (session_hash) " " session_hash BYTEA NOT NULL CHECK(LENGTH(session_hash)=64) REFERENCES refresh_sessions (session_hash) "
",coin_pub BYTEA NOT NULL CHECK(LENGTH(coin_pub)=32) REFERENCES known_coins (coin_pub) " ",coin_pub BYTEA NOT NULL CHECK(LENGTH(coin_pub)=32) REFERENCES known_coins (coin_pub) "
",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)" ",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)"
",denom_pub BYTEA NOT NULL " ",denom_pub BYTEA NOT NULL "
@ -841,7 +847,7 @@ postgres_commit (void *cls,
* Insert a denomination key * Insert a denomination key
* *
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param sesssion connection to use * @param session connection to use
* @param dki the denomination key information * @param dki the denomination key information
* @return #GNUNET_OK on success; #GNUNET_SYSERR on failure * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
*/ */
@ -855,15 +861,15 @@ postgres_insert_denomination (void *cls,
int ret; int ret;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_RSA_PUBLIC_KEY (dki->denom_pub.rsa_public_key), TALER_PQ_query_param_rsa_public_key (dki->denom_pub.rsa_public_key),
TALER_PQ_QUERY_PARAM_PTR (&issue->start.abs_value_us__), TALER_PQ_query_param_auto_from_type (&issue->start.abs_value_us__),
TALER_PQ_QUERY_PARAM_PTR (&issue->expire_withdraw.abs_value_us__), TALER_PQ_query_param_auto_from_type (&issue->expire_withdraw.abs_value_us__),
TALER_PQ_QUERY_PARAM_PTR (&issue->expire_spend.abs_value_us__), TALER_PQ_query_param_auto_from_type (&issue->expire_spend.abs_value_us__),
TALER_PQ_QUERY_PARAM_PTR (&issue->expire_legal.abs_value_us__), TALER_PQ_query_param_auto_from_type (&issue->expire_legal.abs_value_us__),
TALER_PQ_QUERY_PARAM_AMOUNT_NBO (&issue->value), TALER_PQ_query_param_amount_nbo (&issue->value),
TALER_PQ_QUERY_PARAM_AMOUNT_NBO (&issue->fee_withdraw), TALER_PQ_query_param_amount_nbo (&issue->fee_withdraw),
TALER_PQ_QUERY_PARAM_AMOUNT_NBO (&issue->fee_refresh), TALER_PQ_query_param_amount_nbo (&issue->fee_refresh),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
result = TALER_PQ_exec_prepared (session->conn, result = TALER_PQ_exec_prepared (session->conn,
"insert_denomination", "insert_denomination",
@ -899,13 +905,13 @@ postgres_reserve_get (void *cls,
{ {
PGresult *result; PGresult *result;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR(&reserve->pub), TALER_PQ_query_param_auto_from_type(&reserve->pub),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
struct TALER_PQ_ResultSpec rs[] = { struct TALER_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC_AMOUNT("current_balance", &reserve->balance), TALER_PQ_result_spec_amount("current_balance", &reserve->balance),
TALER_PQ_RESULT_SPEC_ABSOLUTE_TIME("expiration_date", &reserve->expiry), TALER_PQ_result_spec_absolute_time("expiration_date", &reserve->expiry),
TALER_PQ_RESULT_SPEC_END TALER_PQ_result_spec_end
}; };
result = TALER_PQ_exec_prepared (session->conn, result = TALER_PQ_exec_prepared (session->conn,
@ -914,7 +920,7 @@ postgres_reserve_get (void *cls,
if (PGRES_TUPLES_OK != PQresultStatus (result)) if (PGRES_TUPLES_OK != PQresultStatus (result))
{ {
QUERY_ERR (result); QUERY_ERR (result);
PQclear (resultE); PQclear (result);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
if (0 == PQntuples (result)) if (0 == PQntuples (result))
@ -955,10 +961,10 @@ postgres_reserves_update (void *cls,
if (NULL == reserve) if (NULL == reserve)
return GNUNET_SYSERR; return GNUNET_SYSERR;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_ABSOLUTE_TIME (reserve->expiry), TALER_PQ_query_param_absolute_time (&reserve->expiry),
TALER_PQ_QUERY_PARAM_AMOUNT (&reserve->balance), TALER_PQ_query_param_amount (&reserve->balance),
TALER_PQ_QUERY_PARAM_PTR (&reserve->pub), TALER_PQ_query_param_auto_from_type (&reserve->pub),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
result = TALER_PQ_exec_prepared (session->conn, result = TALER_PQ_exec_prepared (session->conn,
"update_reserve", "update_reserve",
@ -979,7 +985,8 @@ postgres_reserves_update (void *cls,
/** /**
* Insert a incoming transaction into reserves. New reserves are also created * Insert a incoming transaction into reserves. New reserves are also created
* through this function. * through this function. Note that this API call starts (and stops) its
* own transaction scope (so the application must not do so).
* *
* @param cls the `struct PostgresClosure` with the plugin-specific state * @param cls the `struct PostgresClosure` with the plugin-specific state
* @param session the database connection handle * @param session the database connection handle
@ -995,10 +1002,10 @@ postgres_reserves_update (void *cls,
static int static int
postgres_reserves_in_insert (void *cls, postgres_reserves_in_insert (void *cls,
struct TALER_MINTDB_Session *session, struct TALER_MINTDB_Session *session,
struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_Amount *balance, const struct TALER_Amount *balance,
const char *details, const char *details,
const struct GNUNET_TIME_Absolute expiry) struct GNUNET_TIME_Absolute expiry)
{ {
PGresult *result; PGresult *result;
int reserve_exists; int reserve_exists;
@ -1018,19 +1025,18 @@ postgres_reserves_in_insert (void *cls,
&reserve); &reserve);
if (GNUNET_SYSERR == reserve_exists) if (GNUNET_SYSERR == reserve_exists)
{ {
postgres_rollback (cls, GNUNET_break (0);
session); goto rollback;
return GNUNET_SYSERR;
} }
if (GNUNET_NO == reserve_exists) if (GNUNET_NO == reserve_exists)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Reserve does not exist; creating a new one\n"); "Reserve does not exist; creating a new one\n");
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR (reserve_pub), TALER_PQ_query_param_auto_from_type (reserve_pub),
TALER_PQ_QUERY_PARAM_AMOUNT (balance), TALER_PQ_query_param_amount (balance),
TALER_PQ_QUERY_PARAM_ABSOLUTE_TIME (expiry), TALER_PQ_query_param_absolute_time (&expiry),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
result = TALER_PQ_exec_prepared (session->conn, result = TALER_PQ_exec_prepared (session->conn,
"create_reserve", "create_reserve",
@ -1044,11 +1050,11 @@ postgres_reserves_in_insert (void *cls,
else else
{ {
/* Update reserve */ /* Update reserve */
updated_reserve.pub = reserve->pub; updated_reserve.pub = reserve.pub;
if (GNUNET_OK != if (GNUNET_OK !=
TALER_amount_add (&updated_reserve.balance, TALER_amount_add (&updated_reserve.balance,
&reserve->balance, &reserve.balance,
balance)) balance))
{ {
/* currency overflow or incompatible currency */ /* currency overflow or incompatible currency */
@ -1057,7 +1063,7 @@ postgres_reserves_in_insert (void *cls,
goto rollback; goto rollback;
} }
updated_reserve.expiry = GNUNET_TIME_absolute_max (expiry, updated_reserve.expiry = GNUNET_TIME_absolute_max (expiry,
reserve->expiry); reserve.expiry);
} }
if (NULL != result) if (NULL != result)
@ -1066,17 +1072,32 @@ postgres_reserves_in_insert (void *cls,
/* create new incoming transaction, SQL "primary key" logic /* create new incoming transaction, SQL "primary key" logic
is used to guard against duplicates! */ is used to guard against duplicates! */
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR (&reserve->pub), TALER_PQ_query_param_auto_from_type (&reserve.pub),
TALER_PQ_QUERY_PARAM_AMOUNT (balance), TALER_PQ_query_param_amount (balance),
TALER_PQ_QUERY_PARAM_PTR_SIZED (details, strlen (details)), TALER_PQ_query_param_fixed_size (details, strlen (details)),
TALER_PQ_QUERY_PARAM_ABSOLUTE_TIME (expiry), TALER_PQ_query_param_absolute_time (&expiry),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
result = TALER_PQ_exec_prepared (session->conn, result = TALER_PQ_exec_prepared (session->conn,
"create_reserves_in_transaction", "create_reserves_in_transaction",
params); params);
if (PGRES_COMMAND_OK != PQresultStatus(result)) if (PGRES_COMMAND_OK != PQresultStatus(result))
{ {
const char *efield;
efield = PQresultErrorField (result,
PG_DIAG_SQLSTATE);
if ( (PGRES_FATAL_ERROR == PQresultStatus(result)) &&
(NULL != strstr ("23505", /* unique violation */
efield)) )
{
/* This means we had the same reserve/justification/details
before */
PQclear (result);
postgres_rollback (cls,
session);
return GNUNET_NO;
}
QUERY_ERR (result); QUERY_ERR (result);
goto rollback; goto rollback;
} }
@ -1121,8 +1142,8 @@ postgres_get_collectable_blindcoin (void *cls,
{ {
PGresult *result; PGresult *result;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR (h_blind), TALER_PQ_query_param_auto_from_type (h_blind),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub; struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
struct GNUNET_CRYPTO_rsa_Signature *denom_sig; struct GNUNET_CRYPTO_rsa_Signature *denom_sig;
@ -1144,11 +1165,11 @@ postgres_get_collectable_blindcoin (void *cls,
goto cleanup; goto cleanup;
} }
struct TALER_PQ_ResultSpec rs[] = { struct TALER_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC_RSA_PUBLIC_KEY("denom_pub", &denom_pub), TALER_PQ_result_spec_rsa_public_key("denom_pub", &denom_pub),
TALER_PQ_RESULT_SPEC_RSA_SIGNATURE("denom_sig", &denom_sig), TALER_PQ_result_spec_rsa_signature("denom_sig", &denom_sig),
TALER_PQ_RESULT_SPEC("reserve_sig", &collectable->reserve_sig), TALER_PQ_result_spec_auto_from_type("reserve_sig", &collectable->reserve_sig),
TALER_PQ_RESULT_SPEC("reserve_pub", &collectable->reserve_pub), TALER_PQ_result_spec_auto_from_type("reserve_pub", &collectable->reserve_pub),
TALER_PQ_RESULT_SPEC_END TALER_PQ_result_spec_end
}; };
if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0)) if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0))
@ -1194,12 +1215,12 @@ postgres_insert_collectable_blindcoin (void *cls,
struct TALER_MINTDB_Reserve reserve; struct TALER_MINTDB_Reserve reserve;
int ret = GNUNET_SYSERR; int ret = GNUNET_SYSERR;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR (h_blind), TALER_PQ_query_param_auto_from_type (h_blind),
TALER_PQ_QUERY_PARAM_RSA_PUBLIC_KEY (collectable->denom_pub.rsa_public_key), TALER_PQ_query_param_rsa_public_key (collectable->denom_pub.rsa_public_key),
TALER_PQ_QUERY_PARAM_RSA_SIGNATURE (collectable->sig.rsa_signature), TALER_PQ_query_param_rsa_signature (collectable->sig.rsa_signature),
TALER_PQ_QUERY_PARAM_PTR (&collectable->reserve_pub), TALER_PQ_query_param_auto_from_type (&collectable->reserve_pub),
TALER_PQ_QUERY_PARAM_PTR (&collectable->reserve_sig), TALER_PQ_query_param_auto_from_type (&collectable->reserve_sig),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
if (GNUNET_OK != postgres_start (cls, if (GNUNET_OK != postgres_start (cls,
@ -1272,8 +1293,8 @@ postgres_get_reserve_history (void *cls,
{ {
struct TALER_MINTDB_BankTransfer *bt; struct TALER_MINTDB_BankTransfer *bt;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR (reserve_pub), TALER_PQ_query_param_auto_from_type (reserve_pub),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
result = TALER_PQ_exec_prepared (session->conn, result = TALER_PQ_exec_prepared (session->conn,
@ -1329,8 +1350,8 @@ postgres_get_reserve_history (void *cls,
struct GNUNET_CRYPTO_rsa_Signature *denom_sig; struct GNUNET_CRYPTO_rsa_Signature *denom_sig;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR (reserve_pub), TALER_PQ_query_param_auto_from_type (reserve_pub),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
result = TALER_PQ_exec_prepared (session->conn, result = TALER_PQ_exec_prepared (session->conn,
"get_reserves_blindcoins", "get_reserves_blindcoins",
@ -1346,11 +1367,11 @@ postgres_get_reserve_history (void *cls,
goto cleanup; goto cleanup;
} }
struct TALER_PQ_ResultSpec rs[] = { struct TALER_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC ("blind_ev", &blind_ev), TALER_PQ_result_spec_auto_from_type ("blind_ev", &blind_ev),
TALER_PQ_RESULT_SPEC_RSA_PUBLIC_KEY ("denom_pub", &denom_pub), TALER_PQ_result_spec_rsa_public_key ("denom_pub", &denom_pub),
TALER_PQ_RESULT_SPEC_RSA_SIGNATURE ("denom_sig", &denom_sig), TALER_PQ_result_spec_rsa_signature ("denom_sig", &denom_sig),
TALER_PQ_RESULT_SPEC ("reserve_sig", &reserve_sig), TALER_PQ_result_spec_auto_from_type ("reserve_sig", &reserve_sig),
TALER_PQ_RESULT_SPEC_END TALER_PQ_result_spec_end
}; };
GNUNET_assert (NULL != rh); GNUNET_assert (NULL != rh);
GNUNET_assert (NULL != rh_head); GNUNET_assert (NULL != rh_head);
@ -1405,10 +1426,10 @@ postgres_have_deposit (void *cls,
const struct TALER_MINTDB_Deposit *deposit) const struct TALER_MINTDB_Deposit *deposit)
{ {
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR (&deposit->coin.coin_pub), TALER_PQ_query_param_auto_from_type (&deposit->coin.coin_pub),
TALER_PQ_QUERY_PARAM_PTR (&deposit->transaction_id), TALER_PQ_query_param_auto_from_type (&deposit->transaction_id),
TALER_PQ_QUERY_PARAM_PTR (&deposit->merchant_pub), TALER_PQ_query_param_auto_from_type (&deposit->merchant_pub),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
PGresult *result; PGresult *result;
int ret; int ret;
@ -1458,18 +1479,18 @@ postgres_insert_deposit (void *cls,
ret = GNUNET_SYSERR; ret = GNUNET_SYSERR;
json_wire_enc = json_dumps (deposit->wire, JSON_COMPACT); json_wire_enc = json_dumps (deposit->wire, JSON_COMPACT);
struct TALER_PQ_QueryParam params[]= { struct TALER_PQ_QueryParam params[]= {
TALER_PQ_QUERY_PARAM_PTR (&deposit->coin.coin_pub), TALER_PQ_query_param_auto_from_type (&deposit->coin.coin_pub),
TALER_PQ_QUERY_PARAM_RSA_PUBLIC_KEY (deposit->coin.denom_pub.rsa_public_key), TALER_PQ_query_param_rsa_public_key (deposit->coin.denom_pub.rsa_public_key),
TALER_PQ_QUERY_PARAM_RSA_SIGNATURE (deposit->coin.denom_sig.rsa_signature), TALER_PQ_query_param_rsa_signature (deposit->coin.denom_sig.rsa_signature),
TALER_PQ_QUERY_PARAM_PTR (&deposit->transaction_id), TALER_PQ_query_param_auto_from_type (&deposit->transaction_id),
TALER_PQ_QUERY_PARAM_AMOUNT (&deposit->amount_with_fee), TALER_PQ_query_param_amount (&deposit->amount_with_fee),
TALER_PQ_QUERY_PARAM_PTR (&deposit->merchant_pub), TALER_PQ_query_param_auto_from_type (&deposit->merchant_pub),
TALER_PQ_QUERY_PARAM_PTR (&deposit->h_contract), TALER_PQ_query_param_auto_from_type (&deposit->h_contract),
TALER_PQ_QUERY_PARAM_PTR (&deposit->h_wire), TALER_PQ_query_param_auto_from_type (&deposit->h_wire),
TALER_PQ_QUERY_PARAM_PTR (&deposit->csig), TALER_PQ_query_param_auto_from_type (&deposit->csig),
TALER_PQ_QUERY_PARAM_PTR_SIZED (json_wire_enc, TALER_PQ_query_param_fixed_size (json_wire_enc,
strlen (json_wire_enc)), strlen (json_wire_enc)),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
result = TALER_PQ_exec_prepared (session->conn, "insert_deposit", params); result = TALER_PQ_exec_prepared (session->conn, "insert_deposit", params);
if (PGRES_COMMAND_OK != PQresultStatus (result)) if (PGRES_COMMAND_OK != PQresultStatus (result))
@ -1505,8 +1526,8 @@ postgres_get_refresh_session (void *cls,
{ {
PGresult *result; PGresult *result;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR(session_hash), TALER_PQ_query_param_auto_from_type(session_hash),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
int ret; int ret;
uint16_t num_oldcoins; uint16_t num_oldcoins;
@ -1537,10 +1558,10 @@ postgres_get_refresh_session (void *cls,
} }
memset (refresh_session, 0, sizeof (struct TALER_MINTDB_RefreshSession)); memset (refresh_session, 0, sizeof (struct TALER_MINTDB_RefreshSession));
struct TALER_PQ_ResultSpec rs[] = { struct TALER_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC("num_oldcoins", &num_oldcoins), TALER_PQ_result_spec_auto_from_type("num_oldcoins", &num_oldcoins),
TALER_PQ_RESULT_SPEC("num_newcoins", &num_newcoins), TALER_PQ_result_spec_auto_from_type("num_newcoins", &num_newcoins),
TALER_PQ_RESULT_SPEC("noreveal_index", &noreveal_index), TALER_PQ_result_spec_auto_from_type("noreveal_index", &noreveal_index),
TALER_PQ_RESULT_SPEC_END TALER_PQ_result_spec_end
}; };
if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0)) if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0))
{ {
@ -1580,11 +1601,11 @@ postgres_create_refresh_session (void *cls,
uint16_t num_newcoins; uint16_t num_newcoins;
uint16_t noreveal_index; uint16_t noreveal_index;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR(session_hash), TALER_PQ_query_param_auto_from_type(session_hash),
TALER_PQ_QUERY_PARAM_PTR(&num_oldcoins), TALER_PQ_query_param_auto_from_type(&num_oldcoins),
TALER_PQ_QUERY_PARAM_PTR(&num_newcoins), TALER_PQ_query_param_auto_from_type(&num_newcoins),
TALER_PQ_QUERY_PARAM_PTR(&noreveal_index), TALER_PQ_query_param_auto_from_type(&noreveal_index),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
num_oldcoins = htons (refresh_session->num_oldcoins); num_oldcoins = htons (refresh_session->num_oldcoins);
num_newcoins = htons (refresh_session->num_newcoins); num_newcoins = htons (refresh_session->num_newcoins);
@ -1626,11 +1647,11 @@ postgres_insert_refresh_melt (void *cls,
{ {
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR(&melt->session_hash), TALER_PQ_query_param_auto_from_type(&melt->session_hash),
TALER_PQ_QUERY_PARAM_PTR(&oldcoin_index_nbo), TALER_PQ_query_param_auto_from_type(&oldcoin_index_nbo),
TALER_PQ_QUERY_PARAM_PTR(&melt->coin.coin_pub), TALER_PQ_query_param_auto_from_type(&melt->coin.coin_pub),
TALER_PQ_QUERY_PARAM_RSA_PUBLIC_KEY(melt->coin.denom_pub.rsa_public_key), TALER_PQ_query_param_rsa_public_key(melt->coin.denom_pub.rsa_public_key),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
result = TALER_PQ_exec_prepared (session->conn, result = TALER_PQ_exec_prepared (session->conn,
"insert_refresh_melt", "insert_refresh_melt",
@ -1669,18 +1690,18 @@ postgres_get_refresh_melt (void *cls,
// FIXME: check logic! // FIXME: check logic!
uint16_t oldcoin_index_nbo = htons (oldcoin_index); uint16_t oldcoin_index_nbo = htons (oldcoin_index);
struct TALER_PQ_Query params[] = { struct TALER_PQ_Query params[] = {
TALER_PQ_QUERY_PARAM_PTR (session_hash), TALER_PQ_query_param_auto_from_type (session_hash),
TALER_PQ_QUERY_PARAM_PTR (&oldcoin_index_nbo), TALER_PQ_query_param_auto_from_type (&oldcoin_index_nbo),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
struct TALER_PQ_ResultSpec rs[] = { struct TALER_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC ("coin_pub", &melt->coin), TALER_PQ_result_spec_auto_from_type ("coin_pub", &melt->coin),
TALER_PQ_RESULT_SPEC ("coin_sig", &melt->coin_sig), TALER_PQ_result_spec_auto_from_type ("coin_sig", &melt->coin_sig),
TALER_PQ_RESULT_SPEC ("denom_pub", &melt->coin), TALER_PQ_result_spec_auto_from_type ("denom_pub", &melt->coin),
TALER_PQ_RESULT_SPEC ("denom_sig", &melt->coin), TALER_PQ_result_spec_auto_from_type ("denom_sig", &melt->coin),
TALER_PQ_RESULT_SPEC_AMOUNT ("amount", melt->amount_with_fee), TALER_PQ_result_spec_amount ("amount", melt->amount_with_fee),
TALER_PQ_RESULT_SPEC_AMOUNT ("fee", melt->melt_fee), TALER_PQ_result_spec_amount ("fee", melt->melt_fee),
TALER_PQ_RESULT_SPEC_END TALER_PQ_result_spec_end
}; };
result = TALER_PQ_exec_prepared (session->conn, result = TALER_PQ_exec_prepared (session->conn,
@ -1730,10 +1751,10 @@ postgres_insert_refresh_order (void *cls,
{ {
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR (&newcoin_index_nbo), TALER_PQ_query_param_auto_from_type (&newcoin_index_nbo),
TALER_PQ_QUERY_PARAM_PTR (session_hash), TALER_PQ_query_param_auto_from_type (session_hash),
TALER_PQ_QUERY_PARAM_RSA_PUBLIC_KEY (denom_pubs->rsa_public_key), TALER_PQ_query_param_rsa_public_key (denom_pubs->rsa_public_key),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
result = TALER_PQ_exec_prepared (session->conn, result = TALER_PQ_exec_prepared (session->conn,
"insert_refresh_order", "insert_refresh_order",
@ -1778,9 +1799,9 @@ postgres_get_refresh_order (void *cls,
uint16_t newcoin_index_nbo = htons (num_newcoins); uint16_t newcoin_index_nbo = htons (num_newcoins);
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR(session_hash), TALER_PQ_query_param_auto_from_type(session_hash),
TALER_PQ_QUERY_PARAM_PTR(&newcoin_index_nbo), TALER_PQ_query_param_auto_from_type(&newcoin_index_nbo),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
PGresult *result = TALER_PQ_exec_prepared (session->conn, PGresult *result = TALER_PQ_exec_prepared (session->conn,
@ -1801,8 +1822,8 @@ postgres_get_refresh_order (void *cls,
} }
GNUNET_assert (1 == PQntuples (result)); GNUNET_assert (1 == PQntuples (result));
struct TALER_PQ_ResultSpec rs[] = { struct TALER_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC_RSA_PUBLIC_KEY ("denom_pub", &denom_pubs->rsa_public_key), TALER_PQ_result_spec_rsa_public_key ("denom_pub", &denom_pubs->rsa_public_key),
TALER_PQ_RESULT_SPEC_END TALER_PQ_result_spec_end
}; };
if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0)) if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0))
{ {
@ -1841,14 +1862,14 @@ postgres_insert_refresh_commit_coins (void *cls,
uint16_t cnc_index_nbo = htons (i); uint16_t cnc_index_nbo = htons (i);
uint16_t newcoin_index_nbo = htons (num_newcoins); uint16_t newcoin_index_nbo = htons (num_newcoins);
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR(session_hash), TALER_PQ_query_param_auto_from_type(session_hash),
TALER_PQ_QUERY_PARAM_PTR_SIZED(commit_coins->coin_ev, commit_coins->coin_ev_size), TALER_PQ_query_param_fixed_size(commit_coins->coin_ev, commit_coins->coin_ev_size),
TALER_PQ_QUERY_PARAM_PTR(&cnc_index_nbo), TALER_PQ_query_param_auto_from_type(&cnc_index_nbo),
TALER_PQ_QUERY_PARAM_PTR(&newcoin_index_nbo), TALER_PQ_query_param_auto_from_type(&newcoin_index_nbo),
TALER_PQ_QUERY_PARAM_PTR_SIZED (commit_coins->refresh_link->coin_priv_enc, TALER_PQ_query_param_fixed_size (commit_coins->refresh_link->coin_priv_enc,
commit_coins->refresh_link->blinding_key_enc_size + commit_coins->refresh_link->blinding_key_enc_size +
sizeof (union TALER_CoinSpendPrivateKeyP)), sizeof (struct TALER_CoinSpendPrivateKeyP)),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
PGresult *result = TALER_PQ_exec_prepared (session->conn, PGresult *result = TALER_PQ_exec_prepared (session->conn,
@ -1899,10 +1920,10 @@ postgres_get_refresh_commit_coins (void *cls,
uint16_t cnc_index_nbo = htons (cnc_index); uint16_t cnc_index_nbo = htons (cnc_index);
uint16_t newcoin_index_nbo = htons (newcoin_index); uint16_t newcoin_index_nbo = htons (newcoin_index);
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR(session_hash), TALER_PQ_query_param_auto_from_type(session_hash),
TALER_PQ_QUERY_PARAM_PTR(&cnc_index_nbo), TALER_PQ_query_param_auto_from_type(&cnc_index_nbo),
TALER_PQ_QUERY_PARAM_PTR(&newcoin_index_nbo), TALER_PQ_query_param_auto_from_type(&newcoin_index_nbo),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
void *c_buf; void *c_buf;
size_t c_buf_size; size_t c_buf_size;
@ -1928,9 +1949,9 @@ postgres_get_refresh_commit_coins (void *cls,
} }
struct TALER_PQ_ResultSpec rs[] = { struct TALER_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC_VAR("coin_ev", &c_buf, &c_buf_size), TALER_PQ_result_spec_variable_size("coin_ev", &c_buf, &c_buf_size),
TALER_PQ_RESULT_SPEC_VAR("link_vector_enc", &rl_buf, &rl_buf_size), TALER_PQ_result_spec_variable_size("link_vector_enc", &rl_buf, &rl_buf_size),
TALER_PQ_RESULT_SPEC_END TALER_PQ_result_spec_end
}; };
if (GNUNET_YES != TALER_PQ_extract_result (result, rs, 0)) if (GNUNET_YES != TALER_PQ_extract_result (result, rs, 0))
{ {
@ -1938,7 +1959,7 @@ postgres_get_refresh_commit_coins (void *cls,
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
PQclear (result); PQclear (result);
if (rl_buf_size < sizeof (union TALER_CoinSpendPrivateKeyP)) if (rl_buf_size < sizeof (struct TALER_CoinSpendPrivateKeyP))
{ {
GNUNET_free (c_buf); GNUNET_free (c_buf);
GNUNET_free (rl_buf); GNUNET_free (rl_buf);
@ -1978,12 +1999,12 @@ postgres_insert_refresh_commit_links (void *cls,
uint16_t cnc_index_nbo = htons (i); uint16_t cnc_index_nbo = htons (i);
uint16_t oldcoin_index_nbo = htons (j); uint16_t oldcoin_index_nbo = htons (j);
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR(session_hash), TALER_PQ_query_param_auto_from_type(session_hash),
TALER_PQ_QUERY_PARAM_PTR(&commit_link->transfer_pub), TALER_PQ_query_param_auto_from_type(&commit_link->transfer_pub),
TALER_PQ_QUERY_PARAM_PTR(&cnc_index_nbo), TALER_PQ_query_param_auto_from_type(&cnc_index_nbo),
TALER_PQ_QUERY_PARAM_PTR(&oldcoin_index_nbo), TALER_PQ_query_param_auto_from_type(&oldcoin_index_nbo),
TALER_PQ_QUERY_PARAM_PTR(&commit_link->shared_secret_enc), TALER_PQ_query_param_auto_from_type(&commit_link->shared_secret_enc),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
PGresult *result = TALER_PQ_exec_prepared (session->conn, PGresult *result = TALER_PQ_exec_prepared (session->conn,
@ -2034,10 +2055,10 @@ postgres_get_refresh_commit_links (void *cls,
uint16_t oldcoin_index_nbo = htons (num_links); uint16_t oldcoin_index_nbo = htons (num_links);
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR(session_hash), TALER_PQ_query_param_auto_from_type(session_hash),
TALER_PQ_QUERY_PARAM_PTR(&cnc_index_nbo), TALER_PQ_query_param_auto_from_type(&cnc_index_nbo),
TALER_PQ_QUERY_PARAM_PTR(&oldcoin_index_nbo), TALER_PQ_query_param_auto_from_type(&oldcoin_index_nbo),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
PGresult *result = TALER_PQ_exec_prepared (session->conn, PGresult *result = TALER_PQ_exec_prepared (session->conn,
@ -2057,9 +2078,9 @@ postgres_get_refresh_commit_links (void *cls,
} }
struct TALER_PQ_ResultSpec rs[] = { struct TALER_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC("transfer_pub", &links->transfer_pub), TALER_PQ_result_spec_auto_from_type("transfer_pub", &links->transfer_pub),
TALER_PQ_RESULT_SPEC("link_secret_enc", &links->shared_secret_enc), TALER_PQ_result_spec_auto_from_type("link_secret_enc", &links->shared_secret_enc),
TALER_PQ_RESULT_SPEC_END TALER_PQ_result_spec_end
}; };
if (GNUNET_YES != TALER_PQ_extract_result (result, rs, 0)) if (GNUNET_YES != TALER_PQ_extract_result (result, rs, 0))
@ -2077,14 +2098,14 @@ postgres_get_refresh_commit_links (void *cls,
* Get all of the information from the given melt commit operation. * Get all of the information from the given melt commit operation.
* *
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param sesssion database connection to use * @param session database connection to use
* @param session_hash hash to identify refresh session * @param session_hash hash to identify refresh session
* @return NULL if the @a session_hash does not correspond to any known melt * @return NULL if the @a session_hash does not correspond to any known melt
* operation * operation
*/ */
static struct TALER_MINTDB_MeltCommitment * static struct TALER_MINTDB_MeltCommitment *
postgres_get_melt_commitment (void *cls, postgres_get_melt_commitment (void *cls,
struct TALER_MINTDB_Session *sesssion, struct TALER_MINTDB_Session *session,
const struct GNUNET_HashCode *session_hash) const struct GNUNET_HashCode *session_hash)
{ {
// FIXME: needs to be implemented! // FIXME: needs to be implemented!
@ -2145,10 +2166,10 @@ postgres_insert_refresh_collectable (void *cls,
{ {
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR(session_hash), TALER_PQ_query_param_auto_from_type(session_hash),
TALER_PQ_QUERY_PARAM_PTR(&newcoin_index_nbo), TALER_PQ_query_param_auto_from_type(&newcoin_index_nbo),
TALER_PQ_QUERY_PARAM_RSA_SIGNATURE(ev_sig->rsa_signature), TALER_PQ_query_param_rsa_signature(ev_sig->rsa_signature),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
result = TALER_PQ_exec_prepared (session->conn, result = TALER_PQ_exec_prepared (session->conn,
"insert_refresh_collectable", "insert_refresh_collectable",
@ -2177,14 +2198,14 @@ postgres_insert_refresh_collectable (void *cls,
static struct TALER_MINTDB_LinkDataList * static struct TALER_MINTDB_LinkDataList *
postgres_get_link_data_list (void *cls, postgres_get_link_data_list (void *cls,
struct TALER_MINTDB_Session *session, struct TALER_MINTDB_Session *session,
const union TALER_CoinSpendPublicKeyP *coin_pub) const struct TALER_CoinSpendPublicKeyP *coin_pub)
{ {
// FIXME: check logic! // FIXME: check logic!
struct TALER_MINTDB_LinkDataList *ldl; struct TALER_MINTDB_LinkDataList *ldl;
struct TALER_MINTDB_LinkDataList *pos; struct TALER_MINTDB_LinkDataList *pos;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR(coin_pub), TALER_PQ_query_param_auto_from_type(coin_pub),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
PGresult *result = TALER_PQ_exec_prepared (session->conn, "get_link", params); PGresult *result = TALER_PQ_exec_prepared (session->conn, "get_link", params);
@ -2211,10 +2232,10 @@ postgres_get_link_data_list (void *cls,
void *ld_buf; void *ld_buf;
size_t ld_buf_size; size_t ld_buf_size;
struct TALER_PQ_ResultSpec rs[] = { struct TALER_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC_VAR("link_vector_enc", &ld_buf, &ld_buf_size), TALER_PQ_result_spec_variable_size("link_vector_enc", &ld_buf, &ld_buf_size),
TALER_PQ_RESULT_SPEC_RSA_PUBLIC_KEY("denom_pub", &denom_pub), TALER_PQ_result_spec_rsa_public_key("denom_pub", &denom_pub),
TALER_PQ_RESULT_SPEC_RSA_SIGNATURE("ev_sig", &sig), TALER_PQ_result_spec_rsa_signature("ev_sig", &sig),
TALER_PQ_RESULT_SPEC_END TALER_PQ_result_spec_end
}; };
if (GNUNET_OK != TALER_PQ_extract_result (result, rs, i)) if (GNUNET_OK != TALER_PQ_extract_result (result, rs, i))
@ -2225,7 +2246,7 @@ postgres_get_link_data_list (void *cls,
ldl); ldl);
return NULL; return NULL;
} }
if (ld_buf_size < sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)) if (ld_buf_size < sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))
{ {
PQclear (result); PQclear (result);
GNUNET_free (ld_buf); GNUNET_free (ld_buf);
@ -2235,9 +2256,9 @@ postgres_get_link_data_list (void *cls,
} }
// FIXME: use util API for this! // FIXME: use util API for this!
link_enc = GNUNET_malloc (sizeof (struct TALER_RefreshLinkEncrypted) + link_enc = GNUNET_malloc (sizeof (struct TALER_RefreshLinkEncrypted) +
ld_buf_size - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); ld_buf_size - sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
link_enc->blinding_key_enc = (const char *) &link_enc[1]; link_enc->blinding_key_enc = (const char *) &link_enc[1];
link_enc->blinding_key_enc_size = ld_buf_size - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); link_enc->blinding_key_enc_size = ld_buf_size - sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey);
memcpy (link_enc->coin_priv_enc, memcpy (link_enc->coin_priv_enc,
ld_buf, ld_buf,
ld_buf_size); ld_buf_size);
@ -2271,14 +2292,14 @@ postgres_get_link_data_list (void *cls,
static int static int
postgres_get_transfer (void *cls, postgres_get_transfer (void *cls,
struct TALER_MINTDB_Session *session, struct TALER_MINTDB_Session *session,
const union TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_TransferPublicKeyP *transfer_pub, struct TALER_TransferPublicKeyP *transfer_pub,
struct TALER_EncryptedLinkSecretP *shared_secret_enc) struct TALER_EncryptedLinkSecretP *shared_secret_enc)
{ {
// FIXME: check logic! // FIXME: check logic!
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR(coin_pub), TALER_PQ_query_param_auto_from_type(coin_pub),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
PGresult *result = TALER_PQ_exec_prepared (session->conn, "get_transfer", params); PGresult *result = TALER_PQ_exec_prepared (session->conn, "get_transfer", params);
@ -2306,9 +2327,9 @@ postgres_get_transfer (void *cls,
} }
struct TALER_PQ_ResultSpec rs[] = { struct TALER_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC("transfer_pub", transfer_pub), TALER_PQ_result_spec_auto_from_type("transfer_pub", transfer_pub),
TALER_PQ_RESULT_SPEC("link_secret_enc", shared_secret_enc), TALER_PQ_result_spec_auto_from_type("link_secret_enc", shared_secret_enc),
TALER_PQ_RESULT_SPEC_END TALER_PQ_result_spec_end
}; };
if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0)) if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0))
@ -2335,7 +2356,7 @@ postgres_get_transfer (void *cls,
static struct TALER_MINTDB_TransactionList * static struct TALER_MINTDB_TransactionList *
postgres_get_coin_transactions (void *cls, postgres_get_coin_transactions (void *cls,
struct TALER_MINTDB_Session *session, struct TALER_MINTDB_Session *session,
const union TALER_CoinSpendPublicKeyP *coin_pub) const struct TALER_CoinSpendPublicKeyP *coin_pub)
{ {
PGresult *result; PGresult *result;
struct TALER_MINTDB_TransactionList *head; struct TALER_MINTDB_TransactionList *head;
@ -2353,8 +2374,8 @@ postgres_get_coin_transactions (void *cls,
{ {
struct TALER_MINTDB_Deposit *deposit; struct TALER_MINTDB_Deposit *deposit;
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_QUERY_PARAM_PTR (&coin_pub->ecdsa_pub), TALER_PQ_query_param_auto_from_type (&coin_pub->eddsa_pub),
TALER_PQ_QUERY_PARAM_END TALER_PQ_query_param_end
}; };
json_error_t json_error; json_error_t json_error;
void *json_wire_enc; void *json_wire_enc;
@ -2373,19 +2394,19 @@ postgres_get_coin_transactions (void *cls,
{ {
deposit = GNUNET_new (struct TALER_MINTDB_Deposit); deposit = GNUNET_new (struct TALER_MINTDB_Deposit);
struct TALER_PQ_ResultSpec rs[] = { struct TALER_PQ_ResultSpec rs[] = {
TALER_PQ_RESULT_SPEC ("coin_pub", &deposit->coin), TALER_PQ_result_spec_auto_from_type ("coin_pub", &deposit->coin),
TALER_PQ_RESULT_SPEC ("coin_sig", &deposit->csig), TALER_PQ_result_spec_auto_from_type ("coin_sig", &deposit->csig),
TALER_PQ_RESULT_SPEC ("merchant_pub", &deposit->merchant_pub), TALER_PQ_result_spec_auto_from_type ("merchant_pub", &deposit->merchant_pub),
TALER_PQ_RESULT_SPEC ("h_contract", &deposit->h_contract), TALER_PQ_result_spec_auto_from_type ("h_contract", &deposit->h_contract),
TALER_PQ_RESULT_SPEC ("h_wire", &deposit->h_wire), TALER_PQ_result_spec_auto_from_type ("h_wire", &deposit->h_wire),
TALER_PQ_RESULT_SPEC_VAR ("wire", &json_wire_enc, &json_wire_enc_size), TALER_PQ_result_spec_variable_size ("wire", &json_wire_enc, &json_wire_enc_size),
TALER_PQ_RESULT_SPEC ("transaction_id", &deposit->transaction_id), TALER_PQ_result_spec_auto_from_type ("transaction_id", &deposit->transaction_id),
/** FIXME: /** FIXME:
* TALER_PQ_RESULT_SPEC ("timestamp", &deposit->timestamp), * TALER_PQ_result_spec_auto_from_type ("timestamp", &deposit->timestamp),
* TALER_PQ_RESULT_SPEC ("refund_deadline", &deposit->refund_deadline), * TALER_PQ_result_spec_auto_from_type ("refund_deadline", &deposit->refund_deadline),
* TALER_PQ_RESULT_AMOUNT_NBO ("deposit_fee", &deposit->deposit_fee) * TALER_PQ_RESULT_AMOUNT_NBO ("deposit_fee", &deposit->deposit_fee)
*/ */
TALER_PQ_RESULT_SPEC_END TALER_PQ_result_spec_end
}; };
if ((GNUNET_OK != TALER_PQ_extract_result (result, rs, i)) || if ((GNUNET_OK != TALER_PQ_extract_result (result, rs, i)) ||
(GNUNET_OK != TALER_PQ_extract_amount (result, (GNUNET_OK != TALER_PQ_extract_amount (result,

View File

@ -3,4 +3,4 @@
DB = postgres DB = postgres
#The connection string the plugin has to use for connecting to the database #The connection string the plugin has to use for connecting to the database
DB_CONN_STR = postgres:///taler DB_CONN_STR = postgres:///talercheck

View File

@ -127,7 +127,6 @@ run (void *cls,
{ {
struct TALER_MINTDB_Session *session; struct TALER_MINTDB_Session *session;
struct TALER_ReservePublicKeyP reserve_pub; struct TALER_ReservePublicKeyP reserve_pub;
struct TALER_MINTDB_Reserve reserve;
struct GNUNET_TIME_Absolute expiry; struct GNUNET_TIME_Absolute expiry;
struct TALER_Amount amount; struct TALER_Amount amount;
struct DenomKeyPair *dkp; struct DenomKeyPair *dkp;
@ -178,7 +177,6 @@ run (void *cls,
goto drop; goto drop;
} }
RND_BLK (&reserve_pub); RND_BLK (&reserve_pub);
reserve.pub = reserve_pub;
amount.value = 1; amount.value = 1;
amount.fraction = 1; amount.fraction = 1;
strcpy (amount.currency, CURRENCY); strcpy (amount.currency, CURRENCY);
@ -188,8 +186,9 @@ run (void *cls,
FAILIF (GNUNET_OK != FAILIF (GNUNET_OK !=
plugin->reserves_in_insert (plugin->cls, plugin->reserves_in_insert (plugin->cls,
session, session,
&reserve, &reserve_pub,
&amount, &amount,
"justification 1",
expiry)); expiry));
FAILIF (GNUNET_OK != FAILIF (GNUNET_OK !=
check_reserve (session, check_reserve (session,
@ -201,8 +200,9 @@ run (void *cls,
FAILIF (GNUNET_OK != FAILIF (GNUNET_OK !=
plugin->reserves_in_insert (plugin->cls, plugin->reserves_in_insert (plugin->cls,
session, session,
&reserve, &reserve_pub,
&amount, &amount,
"justification 2",
expiry)); expiry));
FAILIF (GNUNET_OK != FAILIF (GNUNET_OK !=
check_reserve (session, check_reserve (session,

View File

@ -60,6 +60,7 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
break; break;
case TALER_PQ_QF_RSA_PUBLIC_KEY: case TALER_PQ_QF_RSA_PUBLIC_KEY:
case TALER_PQ_QF_RSA_SIGNATURE: case TALER_PQ_QF_RSA_SIGNATURE:
case TALER_PQ_QF_TIME_ABSOLUTE:
len++; len++;
break; break;
default: default:
@ -67,6 +68,7 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
GNUNET_assert (0); GNUNET_assert (0);
break; break;
} }
i++;
} }
/* new scope to allow stack allocation without alloca */ /* new scope to allow stack allocation without alloca */
@ -111,7 +113,7 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
param_formats[off] = 1; param_formats[off] = 1;
off++; off++;
param_values[off] = (void *) amount->currency; param_values[off] = (void *) amount->currency;
param_lengths[off] = strlen (amount->currency) + 1; param_lengths[off] = strlen (amount->currency);
param_formats[off] = 1; param_formats[off] = 1;
off++; off++;
} }
@ -134,7 +136,7 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
param_formats[off] = 1; param_formats[off] = 1;
off++; off++;
param_values[off] = (void *) amount->currency; param_values[off] = (void *) amount->currency;
param_lengths[off] = strlen (amount->currency) + 1; param_lengths[off] = strlen (amount->currency);
param_formats[off] = 1; param_formats[off] = 1;
off++; off++;
} }
@ -176,8 +178,6 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
at_nbo = GNUNET_new (struct GNUNET_TIME_AbsoluteNBO); at_nbo = GNUNET_new (struct GNUNET_TIME_AbsoluteNBO);
scratch[soff++] = at_nbo; scratch[soff++] = at_nbo;
/* FIXME: this does not work for 'forever' as PQ uses 63-bit integers;
should check and handle! (Need testcase!) */
*at_nbo = GNUNET_TIME_absolute_hton (*at_hbo); *at_nbo = GNUNET_TIME_absolute_hton (*at_hbo);
param_values[off] = (void *) at_nbo; param_values[off] = (void *) at_nbo;
param_lengths[off] = sizeof (struct GNUNET_TIME_AbsoluteNBO); param_lengths[off] = sizeof (struct GNUNET_TIME_AbsoluteNBO);
@ -190,6 +190,7 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
GNUNET_assert (0); GNUNET_assert (0);
break; break;
} }
i++;
} }
GNUNET_assert (off == len); GNUNET_assert (off == len);
res = PQexecPrepared (db_conn, res = PQexecPrepared (db_conn,
@ -200,7 +201,7 @@ TALER_PQ_exec_prepared (PGconn *db_conn,
param_formats, param_formats,
1); 1);
for (off = 0; off < soff; off++) for (off = 0; off < soff; off++)
GNUNET_free (scratch[soff]); GNUNET_free (scratch[off]);
return res; return res;
} }
} }
@ -222,25 +223,34 @@ TALER_PQ_cleanup_result (struct TALER_PQ_ResultSpec *rs)
switch (rs[i].format) switch (rs[i].format)
{ {
case TALER_PQ_RF_VARSIZE_BLOB: case TALER_PQ_RF_VARSIZE_BLOB:
if (NULL != rs[i].dst)
{ {
GNUNET_free (rs[i].dst); void **dst = rs[i].dst;
rs[i].dst = NULL; if (NULL != *dst)
{
GNUNET_free (*dst);
*dst = NULL;
*rs[i].result_size = 0; *rs[i].result_size = 0;
} }
break; break;
}
case TALER_PQ_RF_RSA_PUBLIC_KEY: case TALER_PQ_RF_RSA_PUBLIC_KEY:
if (NULL != rs[i].dst)
{ {
GNUNET_CRYPTO_rsa_public_key_free (rs[i].dst); void **dst = rs[i].dst;
rs[i].dst = NULL; if (NULL != *dst)
{
GNUNET_CRYPTO_rsa_public_key_free (*dst);
*dst = NULL;
} }
break; break;
}
case TALER_PQ_RF_RSA_SIGNATURE: case TALER_PQ_RF_RSA_SIGNATURE:
if (NULL != rs[i].dst)
{ {
GNUNET_CRYPTO_rsa_signature_free (rs[i].dst); void **dst = rs[i].dst;
rs[i].dst = NULL; if (NULL != *dst)
{
GNUNET_CRYPTO_rsa_signature_free (*dst);
*dst = NULL;
}
} }
break; break;
default: default:
@ -256,7 +266,7 @@ TALER_PQ_cleanup_result (struct TALER_PQ_ResultSpec *rs)
* is returned. * is returned.
* *
* @param result result to process * @param result result to process
* @param[in|out] rs result specification to extract for * @param[in,out] rs result specification to extract for
* @param row row from the result to extract * @param row row from the result to extract
* @return * @return
* #GNUNET_YES if all results could be extracted * #GNUNET_YES if all results could be extracted
@ -525,8 +535,6 @@ TALER_PQ_extract_result (PGresult *result,
PQgetvalue (result, PQgetvalue (result,
row, row,
fnum); fnum);
/* FIXME: this does not work for 'forever' as PQ uses 63-bit integers;
should check and handle! (Need testcase!) */
*dst = GNUNET_TIME_absolute_ntoh (*res); *dst = GNUNET_TIME_absolute_ntoh (*res);
break; break;
} }

214
src/pq/pq_helper.c Normal file
View File

@ -0,0 +1,214 @@
/*
This file is part of TALER
Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors)
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
*/
/**
* @file pq/pq_helper.c
* @brief functions to initialize parameter arrays
* @author Christian Grothoff
*/
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include "taler_pq_lib.h"
/**
* Generate query parameter for a currency, consisting of the three
* components "value", "fraction" and "currency" in this order. The
* types must be a 64-bit integer, 32-bit integer and a
* #TALER_CURRENCY_LEN-sized BLOB/VARCHAR respectively.
*
* @param x pointer to the query parameter to pass
* @return array entry for the query parameters to use
*/
struct TALER_PQ_QueryParam
TALER_PQ_query_param_amount_nbo (const struct TALER_AmountNBO *x)
{
struct TALER_PQ_QueryParam res =
{ TALER_PQ_QF_AMOUNT_NBO, x, sizeof (*x) };
return res;
}
/**
* Generate query parameter for a currency, consisting of the three
* components "value", "fraction" and "currency" in this order. The
* types must be a 64-bit integer, 32-bit integer and a
* #TALER_CURRENCY_LEN-sized BLOB/VARCHAR respectively.
*
* @param x pointer to the query parameter to pass
* @return array entry for the query parameters to use
*/
struct TALER_PQ_QueryParam
TALER_PQ_query_param_amount (const struct TALER_Amount *x)
{
struct TALER_PQ_QueryParam res =
{ TALER_PQ_QF_AMOUNT, x, sizeof (*x) };
return res;
}
/**
* Generate query parameter for an RSA public key. The
* database must contain a BLOB type in the respective position.
*
* @param x the query parameter to pass
* @return array entry for the query parameters to use
*/
struct TALER_PQ_QueryParam
TALER_PQ_query_param_rsa_public_key (const struct GNUNET_CRYPTO_rsa_PublicKey *x)
{
struct TALER_PQ_QueryParam res =
{ TALER_PQ_QF_RSA_PUBLIC_KEY, (x), 0 };
return res;
}
/**
* Generate query parameter for an RSA signature. The
* database must contain a BLOB type in the respective position.
*
* @param x the query parameter to pass
* @return array entry for the query parameters to use
*/
struct TALER_PQ_QueryParam
TALER_PQ_query_param_rsa_signature (const struct GNUNET_CRYPTO_rsa_Signature *x)
{
struct TALER_PQ_QueryParam res =
{ TALER_PQ_QF_RSA_SIGNATURE, (x), 0 };
return res;
}
/**
* Generate query parameter for an absolute time value.
* The database must store a 64-bit integer.
*
* @param x pointer to the query parameter to pass
* @return array entry for the query parameters to use
*/
struct TALER_PQ_QueryParam
TALER_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x)
{
struct TALER_PQ_QueryParam res =
{ TALER_PQ_QF_TIME_ABSOLUTE, x, sizeof (*x) };
return res;
}
/**
* Variable-size result expected.
*
* @param name name of the field in the table
* @param[out] dst where to store the result, allocated
* @param[out] sptr where to store the size of @a dst
* @return array entry for the result specification to use
*/
struct TALER_PQ_ResultSpec
TALER_PQ_result_spec_variable_size (const char *name,
void **dst,
size_t *sptr)
{
struct TALER_PQ_ResultSpec res =
{ TALER_PQ_RF_VARSIZE_BLOB, (void *) (dst), 0, name, sptr };
return res;
}
/**
* Currency amount expected.
*
* @param name name of the field in the table
* @param[out] amount where to store the result
* @return array entry for the result specification to use
*/
struct TALER_PQ_ResultSpec
TALER_PQ_result_spec_amount_nbo (const char *name,
struct TALER_AmountNBO *amount)
{
struct TALER_PQ_ResultSpec res =
{TALER_PQ_RF_AMOUNT_NBO, (void *) amount, sizeof (*amount), name, NULL };
return res;
}
/**
* Currency amount expected.
*
* @param name name of the field in the table
* @param[out] amount where to store the result
* @return array entry for the result specification to use
*/
struct TALER_PQ_ResultSpec
TALER_PQ_result_spec_amount (const char *name,
struct TALER_Amount *amount)
{
struct TALER_PQ_ResultSpec res =
{TALER_PQ_RF_AMOUNT, (void *) amount, sizeof (*amount), name, NULL };
return res;
}
/**
* RSA public key expected.
*
* @param name name of the field in the table
* @param[out] rsa where to store the result
* @return array entry for the result specification to use
*/
struct TALER_PQ_ResultSpec
TALER_PQ_result_spec_rsa_public_key (const char *name,
struct GNUNET_CRYPTO_rsa_PublicKey **rsa)
{
struct TALER_PQ_ResultSpec res =
{TALER_PQ_RF_RSA_PUBLIC_KEY, (void *) rsa, 0, name, NULL };
return res;
}
/**
* RSA signature expected.
*
* @param name name of the field in the table
* @param[out] sig where to store the result;
* @return array entry for the result specification to use
*/
struct TALER_PQ_ResultSpec
TALER_PQ_result_spec_rsa_signature (const char *name,
struct GNUNET_CRYPTO_rsa_Signature **sig)
{
struct TALER_PQ_ResultSpec res =
{TALER_PQ_RF_RSA_SIGNATURE, (void *) sig, 0, (name), NULL };
return res;
}
/**
* Absolute time expected.
*
* @param name name of the field in the table
* @param[out] at where to store the result
* @return array entry for the result specification to use
*/
struct TALER_PQ_ResultSpec
TALER_PQ_result_spec_absolute_time (const char *name,
struct GNUNET_TIME_Absolute *at)
{
struct TALER_PQ_ResultSpec res =
{TALER_PQ_RF_TIME_ABSOLUTE, (void *) at, sizeof (*at), (name), NULL };
return res;
}
/* end of pq_helper.c */

View File

@ -60,9 +60,10 @@ postgres_prepare (PGconn *db_conn)
",namount_val" ",namount_val"
",namount_frac" ",namount_frac"
",namount_curr" ",namount_curr"
",vsize"
") VALUES " ") VALUES "
"($1, $2, $3, $4, $5, $6," "($1, $2, $3, $4, $5, $6,"
"$7, $8, $9, $10, $11);", "$7, $8, $9, $10, $11, $12);",
11, NULL); 11, NULL);
PREPARE ("test_select", PREPARE ("test_select",
"SELECT" "SELECT"
@ -77,6 +78,7 @@ postgres_prepare (PGconn *db_conn)
",namount_val" ",namount_val"
",namount_frac" ",namount_frac"
",namount_curr" ",namount_curr"
",vsize"
" FROM test_pq" " FROM test_pq"
" ORDER BY abs_time DESC " " ORDER BY abs_time DESC "
" LIMIT 1;", " LIMIT 1;",
@ -108,47 +110,119 @@ run_queries (PGconn *conn)
struct TALER_Amount hamount2; struct TALER_Amount hamount2;
struct TALER_AmountNBO namount; struct TALER_AmountNBO namount;
struct TALER_AmountNBO namount2; struct TALER_AmountNBO namount2;
struct TALER_PQ_QueryParam params_insert[] = {
TALER_PQ_QUERY_PARAM_RSA_PUBLIC_KEY (pub),
TALER_PQ_QUERY_PARAM_RSA_SIGNATURE (sig),
TALER_PQ_QUERY_PARAM_ABSOLUTE_TIME (abs_time),
TALER_PQ_QUERY_PARAM_ABSOLUTE_TIME (forever),
TALER_PQ_QUERY_PARAM_PTR (&hc),
TALER_PQ_QUERY_PARAM_AMOUNT (hamount),
TALER_PQ_QUERY_PARAM_AMOUNT_NBO (namount),
TALER_PQ_QUERY_PARAM_END
};
struct TALER_PQ_QueryParam params_select[] = {
TALER_PQ_QUERY_PARAM_END
};
struct TALER_PQ_ResultSpec results_select[] = {
TALER_PQ_RESULT_SPEC_RSA_PUBLIC_KEY ("pub", pub2),
TALER_PQ_RESULT_SPEC_RSA_SIGNATURE ("sig", sig2),
TALER_PQ_RESULT_SPEC_ABSOLUTE_TIME ("abs_time", abs_time2),
TALER_PQ_RESULT_SPEC_ABSOLUTE_TIME ("forever", forever2),
TALER_PQ_RESULT_SPEC ("hash", &hc2),
TALER_PQ_RESULT_SPEC_AMOUNT ("hamount", hamount2),
TALER_PQ_RESULT_SPEC_AMOUNT_NBO ("namount", namount2),
TALER_PQ_RESULT_SPEC_END
};
PGresult *result; PGresult *result;
int ret; int ret;
struct GNUNET_CRYPTO_rsa_PrivateKey *priv;
char msg[] = "Hello";
void *msg2;
size_t msg2_len;
priv = GNUNET_CRYPTO_rsa_private_key_create (1024);
pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
sig = GNUNET_CRYPTO_rsa_sign (priv,
msg,
sizeof (msg));
TALER_string_to_amount ("EUR:5.5",
&hamount);
TALER_amount_hton (&namount,
&hamount);
TALER_string_to_amount ("EUR:4.4",
&hamount);
/* FIXME: test TALER_PQ_result_spec_variable_size */
{
struct TALER_PQ_QueryParam params_insert[] = {
TALER_PQ_query_param_rsa_public_key (pub),
TALER_PQ_query_param_rsa_signature (sig),
TALER_PQ_query_param_absolute_time (&abs_time),
TALER_PQ_query_param_absolute_time (&forever),
TALER_PQ_query_param_auto_from_type (&hc),
TALER_PQ_query_param_amount (&hamount),
TALER_PQ_query_param_amount_nbo (&namount),
TALER_PQ_query_param_fixed_size (msg, strlen (msg)),
TALER_PQ_query_param_end
};
struct TALER_PQ_QueryParam params_select[] = {
TALER_PQ_query_param_end
};
struct TALER_PQ_ResultSpec results_select[] = {
TALER_PQ_result_spec_rsa_public_key ("pub", &pub2),
TALER_PQ_result_spec_rsa_signature ("sig", &sig2),
TALER_PQ_result_spec_absolute_time ("abs_time", &abs_time2),
TALER_PQ_result_spec_absolute_time ("forever", &forever2),
TALER_PQ_result_spec_auto_from_type ("hash", &hc2),
TALER_PQ_result_spec_amount ("hamount", &hamount2),
TALER_PQ_result_spec_amount_nbo ("namount", &namount2),
TALER_PQ_result_spec_variable_size ("vsize", &msg2, &msg2_len),
TALER_PQ_result_spec_end
};
// FIXME: init pub, sig
result = TALER_PQ_exec_prepared (conn, result = TALER_PQ_exec_prepared (conn,
"test_insert", "test_insert",
params_insert); params_insert);
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Database failure: %s\n",
PQresultErrorMessage (result));
PQclear (result);
GNUNET_CRYPTO_rsa_signature_free (sig);
GNUNET_CRYPTO_rsa_private_key_free (priv);
GNUNET_CRYPTO_rsa_public_key_free (pub);
return 1;
}
PQclear (result); PQclear (result);
result = TALER_PQ_exec_prepared (conn, result = TALER_PQ_exec_prepared (conn,
"test_select", "test_select",
params_select); params_select);
if (1 !=
PQntuples (result))
{
GNUNET_break (0);
PQclear (result);
GNUNET_CRYPTO_rsa_signature_free (sig);
GNUNET_CRYPTO_rsa_private_key_free (priv);
GNUNET_CRYPTO_rsa_public_key_free (pub);
return 1;
}
ret = TALER_PQ_extract_result (result, ret = TALER_PQ_extract_result (result,
results_select, results_select,
0); 0);
// FIXME: cmp results! GNUNET_break (GNUNET_YES == ret);
GNUNET_break (abs_time.abs_value_us == abs_time2.abs_value_us);
GNUNET_break (forever.abs_value_us == forever2.abs_value_us);
GNUNET_break (0 ==
memcmp (&hc,
&hc2,
sizeof (struct GNUNET_HashCode)));
GNUNET_break (0 ==
TALER_amount_cmp (&hamount,
&hamount2));
TALER_string_to_amount ("EUR:5.5",
&hamount);
TALER_amount_ntoh (&hamount2,
&namount2);
GNUNET_break (0 ==
TALER_amount_cmp (&hamount,
&hamount2));
GNUNET_break (0 ==
GNUNET_CRYPTO_rsa_signature_cmp (sig,
sig2));
GNUNET_break (0 ==
GNUNET_CRYPTO_rsa_public_key_cmp (pub,
pub2));
GNUNET_break (strlen (msg) == msg2_len);
GNUNET_break (0 ==
strncmp (msg,
msg2,
msg2_len));
TALER_PQ_cleanup_result (results_select); TALER_PQ_cleanup_result (results_select);
PQclear (result); PQclear (result);
}
GNUNET_CRYPTO_rsa_signature_free (sig);
GNUNET_CRYPTO_rsa_private_key_free (priv);
GNUNET_CRYPTO_rsa_public_key_free (pub);
if (GNUNET_OK != ret) if (GNUNET_OK != ret)
return 1; return 1;
@ -164,8 +238,10 @@ main(int argc,
PGresult *result; PGresult *result;
int ret; int ret;
// FIXME: pass valid connect string for tests... GNUNET_log_setup ("test-pq",
conn = PQconnectdb (""); "WARNING",
NULL);
conn = PQconnectdb ("postgres:///talercheck");
if (CONNECTION_OK != PQstatus (conn)) if (CONNECTION_OK != PQstatus (conn))
{ {
fprintf (stderr, fprintf (stderr,
@ -177,7 +253,7 @@ main(int argc,
} }
result = PQexec (conn, result = PQexec (conn,
"CREATE TABLE test_pq (" "CREATE TEMPORARY TABLE IF NOT EXISTS test_pq ("
" pub BYTEA NOT NULL" " pub BYTEA NOT NULL"
",sig BYTEA NOT NULL" ",sig BYTEA NOT NULL"
",abs_time INT8 NOT NULL" ",abs_time INT8 NOT NULL"
@ -189,6 +265,7 @@ main(int argc,
",namount_val INT8 NOT NULL" ",namount_val INT8 NOT NULL"
",namount_frac INT4 NOT NULL" ",namount_frac INT4 NOT NULL"
",namount_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" ",namount_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
",vsize VARCHAR NOT NULL"
")"); ")");
if (PGRES_COMMAND_OK != PQresultStatus (result)) if (PGRES_COMMAND_OK != PQresultStatus (result))
{ {
@ -204,7 +281,6 @@ main(int argc,
postgres_prepare (conn)) postgres_prepare (conn))
{ {
GNUNET_break (0); GNUNET_break (0);
PQclear (result);
PQfinish (conn); PQfinish (conn);
return 1; return 1;
} }

View File

@ -50,7 +50,7 @@ fatal_error_handler (void *cls,
/** /**
* Initialize libgcrypt. * Initialize libgcrypt.
*/ */
void void __attribute__ ((constructor))
TALER_gcrypt_init () TALER_gcrypt_init ()
{ {
gcry_set_fatalerror_handler (&fatal_error_handler, gcry_set_fatalerror_handler (&fatal_error_handler,
@ -219,7 +219,7 @@ TALER_refresh_decrypt (const struct TALER_RefreshLinkEncrypted *input,
ret = GNUNET_new (struct TALER_RefreshLinkDecrypted); ret = GNUNET_new (struct TALER_RefreshLinkDecrypted);
memcpy (&ret->coin_priv, memcpy (&ret->coin_priv,
buf, buf,
sizeof (union TALER_CoinSpendPrivateKeyP)); sizeof (struct TALER_CoinSpendPrivateKeyP));
ret->blinding_key.rsa_blinding_key ret->blinding_key.rsa_blinding_key
= GNUNET_CRYPTO_rsa_blinding_key_decode (&buf[sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)], = GNUNET_CRYPTO_rsa_blinding_key_decode (&buf[sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)],
input->blinding_key_enc_size); input->blinding_key_enc_size);
@ -295,7 +295,7 @@ TALER_refresh_link_encrypted_decode (const char *buf,
{ {
struct TALER_RefreshLinkEncrypted *rle; struct TALER_RefreshLinkEncrypted *rle;
if (buf_len < sizeof (union TALER_CoinSpendPrivateKeyP)) if (buf_len < sizeof (struct TALER_CoinSpendPrivateKeyP))
return NULL; return NULL;
if (buf_len >= GNUNET_MAX_MALLOC_CHECKED) if (buf_len >= GNUNET_MAX_MALLOC_CHECKED)
{ {
@ -303,9 +303,9 @@ TALER_refresh_link_encrypted_decode (const char *buf,
return NULL; return NULL;
} }
rle = GNUNET_malloc (sizeof (struct TALER_RefreshLinkEncrypted) + rle = GNUNET_malloc (sizeof (struct TALER_RefreshLinkEncrypted) +
buf_len - sizeof (union TALER_CoinSpendPrivateKeyP)); buf_len - sizeof (struct TALER_CoinSpendPrivateKeyP));
rle->blinding_key_enc = (const char *) &rle[1]; rle->blinding_key_enc = (const char *) &rle[1];
rle->blinding_key_enc_size = buf_len - sizeof (union TALER_CoinSpendPrivateKeyP); rle->blinding_key_enc_size = buf_len - sizeof (struct TALER_CoinSpendPrivateKeyP);
memcpy (rle->coin_priv_enc, memcpy (rle->coin_priv_enc,
buf, buf,
buf_len); buf_len);
@ -326,12 +326,12 @@ TALER_refresh_link_encrypted_encode (const struct TALER_RefreshLinkEncrypted *rl
{ {
char *buf; char *buf;
if (rle->blinding_key_enc_size >= GNUNET_MAX_MALLOC_CHECKED - sizeof (union TALER_CoinSpendPrivateKeyP)) if (rle->blinding_key_enc_size >= GNUNET_MAX_MALLOC_CHECKED - sizeof (struct TALER_CoinSpendPrivateKeyP))
{ {
GNUNET_break (0); GNUNET_break (0);
return NULL; return NULL;
} }
*buf_len = sizeof (union TALER_CoinSpendPrivateKeyP) + rle->blinding_key_enc_size; *buf_len = sizeof (struct TALER_CoinSpendPrivateKeyP) + rle->blinding_key_enc_size;
buf = GNUNET_malloc (*buf_len); buf = GNUNET_malloc (*buf_len);
memcpy (buf, memcpy (buf,
rle->coin_priv_enc, rle->coin_priv_enc,
@ -376,7 +376,7 @@ TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info)
* private key and the coin's public key. * private key and the coin's public key.
* *
* @param secret_enc encrypted link secret * @param secret_enc encrypted link secret
* @param transfer_priv transfer private key * @param trans_priv transfer private key
* @param coin_pub coin public key * @param coin_pub coin public key
* @param[out] secret set to the shared secret * @param[out] secret set to the shared secret
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
@ -384,14 +384,14 @@ TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info)
int int
TALER_link_decrypt_secret (const struct TALER_EncryptedLinkSecretP *secret_enc, TALER_link_decrypt_secret (const struct TALER_EncryptedLinkSecretP *secret_enc,
const struct TALER_TransferPrivateKeyP *trans_priv, const struct TALER_TransferPrivateKeyP *trans_priv,
const union TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_LinkSecretP *secret) struct TALER_LinkSecretP *secret)
{ {
struct TALER_TransferSecretP transfer_secret; struct TALER_TransferSecretP transfer_secret;
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CRYPTO_ecc_ecdh (&trans_priv->ecdhe_priv, GNUNET_CRYPTO_ecdh_eddsa (&trans_priv->ecdhe_priv,
&coin_pub->ecdhe_pub, &coin_pub->eddsa_pub,
&transfer_secret.key)) &transfer_secret.key))
{ {
GNUNET_break (0); GNUNET_break (0);
@ -415,7 +415,7 @@ TALER_link_decrypt_secret (const struct TALER_EncryptedLinkSecretP *secret_enc,
* public key and the coin's private key. * public key and the coin's private key.
* *
* @param secret_enc encrypted link secret * @param secret_enc encrypted link secret
* @param transfer_pub transfer public key * @param trans_pub transfer public key
* @param coin_priv coin private key * @param coin_priv coin private key
* @param[out] secret set to the shared secret * @param[out] secret set to the shared secret
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
@ -423,13 +423,13 @@ TALER_link_decrypt_secret (const struct TALER_EncryptedLinkSecretP *secret_enc,
int int
TALER_link_decrypt_secret2 (const struct TALER_EncryptedLinkSecretP *secret_enc, TALER_link_decrypt_secret2 (const struct TALER_EncryptedLinkSecretP *secret_enc,
const struct TALER_TransferPublicKeyP *trans_pub, const struct TALER_TransferPublicKeyP *trans_pub,
const union TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_LinkSecretP *secret) struct TALER_LinkSecretP *secret)
{ {
struct TALER_TransferSecretP transfer_secret; struct TALER_TransferSecretP transfer_secret;
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CRYPTO_ecc_ecdh (&coin_priv->ecdhe_priv, GNUNET_CRYPTO_eddsa_ecdh (&coin_priv->eddsa_priv,
&trans_pub->ecdhe_pub, &trans_pub->ecdhe_pub,
&transfer_secret.key)) &transfer_secret.key))
{ {
@ -454,14 +454,14 @@ TALER_link_decrypt_secret2 (const struct TALER_EncryptedLinkSecretP *secret_enc,
* *
* @param secret link secret to encrypt * @param secret link secret to encrypt
* @param coin_pub coin public key * @param coin_pub coin public key
* @param transfer_priv[out] set to transfer private key * @param[out] trans_priv set to transfer private key
* @param transfer_pub[out] set to transfer public key * @param[out] trans_pub set to transfer public key
* @param[out] secret_enc set to the encryptd @a secret * @param[out] secret_enc set to the encryptd @a secret
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/ */
int int
TALER_link_encrypt_secret (const struct TALER_LinkSecretP *secret, TALER_link_encrypt_secret (const struct TALER_LinkSecretP *secret,
const union TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_TransferPrivateKeyP *trans_priv, struct TALER_TransferPrivateKeyP *trans_priv,
struct TALER_TransferPublicKeyP *trans_pub, struct TALER_TransferPublicKeyP *trans_pub,
struct TALER_EncryptedLinkSecretP *secret_enc) struct TALER_EncryptedLinkSecretP *secret_enc)
@ -471,8 +471,8 @@ TALER_link_encrypt_secret (const struct TALER_LinkSecretP *secret,
pk = GNUNET_CRYPTO_ecdhe_key_create (); pk = GNUNET_CRYPTO_ecdhe_key_create ();
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CRYPTO_ecc_ecdh (pk, GNUNET_CRYPTO_ecdh_eddsa (pk,
&coin_pub->ecdhe_pub, &coin_pub->eddsa_pub,
&transfer_secret.key)) &transfer_secret.key))
{ {
GNUNET_break (0); GNUNET_break (0);

View File

@ -21,7 +21,6 @@
#include "platform.h" #include "platform.h"
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include "taler_util.h" #include "taler_util.h"
#include "taler_json_lib.h"
/** /**
* Shorthand for exit jumps. * Shorthand for exit jumps.
@ -84,6 +83,9 @@ TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp)
json_t *j; json_t *j;
char *mystr; char *mystr;
int ret; int ret;
if (stamp.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
return json_string ("never");
ret = GNUNET_asprintf (&mystr, ret = GNUNET_asprintf (&mystr,
"%llu", "%llu",
(long long) (stamp.abs_value_us / (1000 * 1000))); (long long) (stamp.abs_value_us / (1000 * 1000)));
@ -128,40 +130,6 @@ TALER_json_from_eddsa_sig (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpo
} }
/**
* Convert a signature (with purpose) to a JSON object representation.
*
* @param purpose purpose of the signature
* @param signature the signature
* @return the JSON reporesentation of the signature with purpose
*/
json_t *
TALER_json_from_ecdsa_sig (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
const struct GNUNET_CRYPTO_EcdsaSignature *signature)
{
json_t *root;
json_t *el;
root = json_object ();
el = json_integer ((json_int_t) ntohl (purpose->size));
json_object_set_new (root, "size", el);
el = json_integer ((json_int_t) ntohl (purpose->purpose));
json_object_set_new (root, "purpose", el);
el = TALER_json_from_data (purpose,
ntohl (purpose->size));
json_object_set_new (root, "ecdsa_val", el);
el = TALER_json_from_data (signature,
sizeof (struct GNUNET_CRYPTO_EddsaSignature));
json_object_set_new (root, "ecdsa_sig", el);
return root;
}
/** /**
* Convert RSA public key to JSON. * Convert RSA public key to JSON.
* *
@ -184,6 +152,76 @@ TALER_json_from_rsa_public_key (struct GNUNET_CRYPTO_rsa_PublicKey *pk)
} }
/**
* Convert JSON to RSA public key.
*
* @param pk JSON encoding to convert
* @return corresponding public key
*/
struct GNUNET_CRYPTO_rsa_PublicKey *
TALER_json_to_rsa_public_key (json_t *json)
{
const char *enc;
char *buf;
size_t len;
size_t buf_len;
struct GNUNET_CRYPTO_rsa_PublicKey *pk;
buf = NULL;
EXITIF (NULL == (enc = json_string_value (json)));
len = strlen (enc);
buf_len = (len * 5) / 8;
buf = GNUNET_malloc (buf_len);
EXITIF (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (enc,
len,
buf,
buf_len));
EXITIF (NULL == (pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
buf_len)));
GNUNET_free (buf);
return pk;
EXITIF_exit:
GNUNET_free_non_null (buf);
return NULL;
}
/**
* Convert JSON to RSA signature.
*
* @param pk JSON encoding to convert
* @return corresponding signature
*/
struct GNUNET_CRYPTO_rsa_Signature *
TALER_json_to_rsa_signature (json_t *json)
{
const char *enc;
char *buf;
size_t len;
size_t buf_len;
struct GNUNET_CRYPTO_rsa_Signature *sig;
buf = NULL;
EXITIF (NULL == (enc = json_string_value (json)));
len = strlen (enc);
buf_len = (len * 5) / 8;
buf = GNUNET_malloc (buf_len);
EXITIF (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (enc,
len,
buf,
buf_len));
EXITIF (NULL == (sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
buf_len)));
GNUNET_free (buf);
return sig;
EXITIF_exit:
GNUNET_free_non_null (buf);
return NULL;
}
/** /**
* Convert RSA signature to JSON. * Convert RSA signature to JSON.
* *
@ -228,20 +266,6 @@ TALER_json_from_data (const void *data,
} }
/**
* Convert binary hash to a JSON string with the base32crockford
* encoding.
*
* @param hc binary data
* @return json string that encodes @a hc
*/
json_t *
TALER_json_from_hash (const struct GNUNET_HashCode *hc)
{
return TALER_json_from_data (hc, sizeof (struct GNUNET_HashCode));
}
/** /**
* Parse given JSON object to Amount * Parse given JSON object to Amount
* *
@ -262,10 +286,13 @@ TALER_json_to_amount (json_t *json,
&error, &error,
JSON_STRICT, JSON_STRICT,
"{s:s, s:I, s:I}", "{s:s, s:I, s:I}",
"curreny", &currency, "currency", &currency,
"value", &value, "value", &value,
"fraction", &fraction)); "fraction", &fraction));
EXITIF (3 < strlen (currency)); EXITIF (3 < strlen (currency));
EXITIF (TALER_CURRENCY_LEN <= strlen (currency));
strcpy (r_amount->currency,
currency);
r_amount->value = (uint32_t) value; r_amount->value = (uint32_t) value;
r_amount->fraction = (uint32_t) fraction; r_amount->fraction = (uint32_t) fraction;
return GNUNET_OK; return GNUNET_OK;
@ -291,6 +318,12 @@ TALER_json_to_abs (json_t *json,
GNUNET_assert (NULL != abs); GNUNET_assert (NULL != abs);
EXITIF (NULL == (str = json_string_value (json))); EXITIF (NULL == (str = json_string_value (json)));
if (0 == strcasecmp (str,
"never"))
{
*abs = GNUNET_TIME_UNIT_FOREVER_ABS;
return GNUNET_OK;
}
EXITIF (1 > sscanf (str, "%llu", &abs_value_s)); EXITIF (1 > sscanf (str, "%llu", &abs_value_s));
abs->abs_value_us = abs_value_s * 1000 * 1000; abs->abs_value_us = abs_value_s * 1000 * 1000;
return GNUNET_OK; return GNUNET_OK;
@ -317,7 +350,7 @@ TALER_json_to_data (json_t *json,
EXITIF (NULL == (enc = json_string_value (json))); EXITIF (NULL == (enc = json_string_value (json)));
len = strlen (enc); len = strlen (enc);
EXITIF ((((len * 5) / 8) + ((((len * 5) % 8) == 0) ? 0 : 1)) == out_size); EXITIF (((len * 5) / 8) != out_size);
EXITIF (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, len, out, out_size)); EXITIF (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, len, out, out_size));
return GNUNET_OK; return GNUNET_OK;
EXITIF_exit: EXITIF_exit:

View File

@ -454,7 +454,7 @@ os_get_exec_path ()
* @return a pointer to the dir path (to be freed by the caller) * @return a pointer to the dir path (to be freed by the caller)
*/ */
char * char *
TALER_os_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind) TALER_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind)
{ {
size_t n; size_t n;
const char *dirname; const char *dirname;

View File

@ -71,7 +71,7 @@ test_basics ()
GNUNET_assert (NULL != rld); GNUNET_assert (NULL != rld);
GNUNET_assert (0 == memcmp (&rld->coin_priv, GNUNET_assert (0 == memcmp (&rld->coin_priv,
&rl.coin_priv, &rl.coin_priv,
sizeof (union TALER_CoinSpendPrivateKeyP))); sizeof (struct TALER_CoinSpendPrivateKeyP)));
GNUNET_assert (0 == GNUNET_assert (0 ==
GNUNET_CRYPTO_rsa_blinding_key_cmp (rl.blinding_key.rsa_blinding_key, GNUNET_CRYPTO_rsa_blinding_key_cmp (rl.blinding_key.rsa_blinding_key,
rld->blinding_key.rsa_blinding_key)); rld->blinding_key.rsa_blinding_key));
@ -121,21 +121,21 @@ test_rled ()
static int static int
test_high_level () test_high_level ()
{ {
struct GNUNET_CRYPTO_EcdsaPrivateKey *pk; struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
struct TALER_LinkSecretP secret; struct TALER_LinkSecretP secret;
struct TALER_LinkSecretP secret2; struct TALER_LinkSecretP secret2;
union TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
union TALER_CoinSpendPrivateKeyP coin_priv; struct TALER_CoinSpendPrivateKeyP coin_priv;
struct TALER_TransferPrivateKeyP trans_priv; struct TALER_TransferPrivateKeyP trans_priv;
struct TALER_TransferPublicKeyP trans_pub; struct TALER_TransferPublicKeyP trans_pub;
struct TALER_EncryptedLinkSecretP secret_enc; struct TALER_EncryptedLinkSecretP secret_enc;
pk = GNUNET_CRYPTO_ecdsa_key_create (); pk = GNUNET_CRYPTO_eddsa_key_create ();
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&secret, &secret,
sizeof (secret)); sizeof (secret));
GNUNET_CRYPTO_ecdsa_key_get_public (pk, GNUNET_CRYPTO_eddsa_key_get_public (pk,
&coin_pub.ecdsa_pub); &coin_pub.eddsa_pub);
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_link_encrypt_secret (&secret, TALER_link_encrypt_secret (&secret,
&coin_pub, &coin_pub,
@ -151,7 +151,7 @@ test_high_level ()
memcmp (&secret, memcmp (&secret,
&secret2, &secret2,
sizeof (secret))); sizeof (secret)));
coin_priv.ecdsa_priv = *pk; coin_priv.eddsa_priv = *pk;
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_link_decrypt_secret2 (&secret_enc, TALER_link_decrypt_secret2 (&secret_enc,
&trans_pub, &trans_pub,

View File

@ -24,6 +24,142 @@
#include "taler_json_lib.h" #include "taler_json_lib.h"
/**
* Test amount conversion from/to JSON.
*
* @return 0 on success
*/
static int
test_amount ()
{
json_t *j;
struct TALER_Amount a1;
struct TALER_Amount a2;
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount ("EUR:4.3",
&a1));
j = TALER_json_from_amount (&a1);
GNUNET_assert (NULL != j);
GNUNET_assert (GNUNET_OK ==
TALER_json_to_amount (j,
&a2));
GNUNET_assert (0 ==
TALER_amount_cmp (&a1,
&a2));
json_decref (j);
return 0;
}
/**
* Test time conversion from/to JSON.
*
* @return 0 on success
*/
static int
test_time ()
{
json_t *j;
struct GNUNET_TIME_Absolute a1;
struct GNUNET_TIME_Absolute a2;
a1 = GNUNET_TIME_absolute_get ();
a1.abs_value_us -= a1.abs_value_us % 1000000; /* round! */
j = TALER_json_from_abs (a1);
GNUNET_assert (NULL != j);
GNUNET_assert (GNUNET_OK ==
TALER_json_to_abs (j,
&a2));
GNUNET_assert (a1.abs_value_us ==
a2.abs_value_us);
json_decref (j);
a1 = GNUNET_TIME_UNIT_FOREVER_ABS;
j = TALER_json_from_abs (a1);
GNUNET_assert (NULL != j);
GNUNET_assert (GNUNET_OK ==
TALER_json_to_abs (j,
&a2));
GNUNET_assert (a1.abs_value_us ==
a2.abs_value_us);
json_decref (j);
return 0;
}
/**
* Test raw (binary) conversion from/to JSON.
*
* @return 0 on success
*/
static int
test_raw ()
{
char blob[256];
char blob2[256];
unsigned int i;
json_t *j;
for (i=0;i<=256;i++)
{
memset (blob, i, i);
j = TALER_json_from_data (blob, i);
GNUNET_assert (NULL != j);
GNUNET_assert (GNUNET_OK ==
TALER_json_to_data (j,
blob2,
i));
GNUNET_assert (0 ==
memcmp (blob,
blob2,
i));
}
return 0;
}
/**
* Test rsa conversions from/to JSON.
*
* @return 0 on success
*/
static int
test_rsa ()
{
struct GNUNET_CRYPTO_rsa_PublicKey *pub;
struct GNUNET_CRYPTO_rsa_PublicKey *pub2;
struct GNUNET_CRYPTO_rsa_Signature *sig;
struct GNUNET_CRYPTO_rsa_Signature *sig2;
struct GNUNET_CRYPTO_rsa_PrivateKey *priv;
char msg[] = "Hello";
json_t *jp;
json_t *js;
priv = GNUNET_CRYPTO_rsa_private_key_create (1024);
pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
sig = GNUNET_CRYPTO_rsa_sign (priv,
msg,
sizeof (msg));
GNUNET_assert (NULL != (jp = TALER_json_from_rsa_public_key (pub)));
GNUNET_assert (NULL != (js = TALER_json_from_rsa_signature (sig)));
GNUNET_assert (NULL != (pub2 = TALER_json_to_rsa_public_key (jp)));
GNUNET_assert (NULL != (sig2 = TALER_json_to_rsa_signature (js)));
GNUNET_break (0 ==
GNUNET_CRYPTO_rsa_signature_cmp (sig,
sig2));
GNUNET_break (0 ==
GNUNET_CRYPTO_rsa_public_key_cmp (pub,
pub2));
GNUNET_CRYPTO_rsa_signature_free (sig);
GNUNET_CRYPTO_rsa_signature_free (sig2);
GNUNET_CRYPTO_rsa_private_key_free (priv);
GNUNET_CRYPTO_rsa_public_key_free (pub);
GNUNET_CRYPTO_rsa_public_key_free (pub2);
return 0;
}
int int
main(int argc, main(int argc,
const char *const argv[]) const char *const argv[])
@ -31,7 +167,15 @@ main(int argc,
GNUNET_log_setup ("test-json", GNUNET_log_setup ("test-json",
"WARNING", "WARNING",
NULL); NULL);
/* FIXME: implement test... */ if (0 != test_amount ())
return 1;
if (0 != test_time ())
return 1;
if (0 != test_raw ())
return 1;
if (0 != test_rsa ())
return 1;
/* FIXME: test EdDSA signature conversion... */
return 0; return 0;
} }

View File

@ -24,7 +24,8 @@
#include "taler_util.h" #include "taler_util.h"
#include "taler_json_lib.h" #include "taler_json_lib.h"
static const char * const json_wire_str = /* Valid SEPA data */
static const char * const valid_wire_str =
"{ \"type\":\"SEPA\", \ "{ \"type\":\"SEPA\", \
\"IBAN\":\"DE67830654080004822650\", \ \"IBAN\":\"DE67830654080004822650\", \
\"name\":\"GNUnet e.V.\", \ \"name\":\"GNUnet e.V.\", \
@ -33,7 +34,40 @@ static const char * const json_wire_str =
\"r\":123456789, \ \"r\":123456789, \
\"address\": \"foobar\"}"; \"address\": \"foobar\"}";
int main(int argc, const char *const argv[]) /* IBAN has wrong country code */
static const char * const invalid_wire_str =
"{ \"type\":\"SEPA\", \
\"IBAN\":\"XX67830654080004822650\", \
\"name\":\"GNUnet e.V.\", \
\"bic\":\"GENODEF1SLR\", \
\"edate\":\"1449930207000\", \
\"r\":123456789, \
\"address\": \"foobar\"}";
/* IBAN has wrong checksum */
static const char * const invalid_wire_str2 =
"{ \"type\":\"SEPA\", \
\"IBAN\":\"DE67830654080004822651\", \
\"name\":\"GNUnet e.V.\", \
\"bic\":\"GENODEF1SLR\", \
\"edate\":\"1449930207000\", \
\"r\":123456789, \
\"address\": \"foobar\"}";
/* Unsupported wireformat type */
static const char * const unsupported_wire_str =
"{ \"type\":\"unsupported\", \
\"IBAN\":\"DE67830654080004822650\", \
\"name\":\"GNUnet e.V.\", \
\"bic\":\"GENODEF1SLR\", \
\"edate\":\"1449930207000\", \
\"r\":123456789, \
\"address\": \"foobar\"}";
int
main(int argc,
const char *const argv[])
{ {
json_t *wire; json_t *wire;
json_error_t error; json_error_t error;
@ -41,13 +75,18 @@ int main(int argc, const char *const argv[])
GNUNET_log_setup ("test-json-validations", "WARNING", NULL); GNUNET_log_setup ("test-json-validations", "WARNING", NULL);
(void) memset(&error, 0, sizeof(error)); (void) memset(&error, 0, sizeof(error));
wire = json_loads (json_wire_str, 0, &error); GNUNET_assert (NULL != (wire = json_loads (unsupported_wire_str, 0, NULL)));
if (NULL == wire) GNUNET_assert (1 != TALER_json_validate_wireformat ("unsupported", wire));
{ json_decref (wire);
TALER_json_warn (error); GNUNET_assert (NULL != (wire = json_loads (invalid_wire_str, 0, NULL)));
return 2; GNUNET_assert (1 != TALER_json_validate_wireformat ("SEPA", wire));
} json_decref (wire);
GNUNET_assert (NULL != (wire = json_loads (invalid_wire_str2, 0, NULL)));
GNUNET_assert (1 != TALER_json_validate_wireformat ("SEPA", wire));
json_decref (wire);
GNUNET_assert (NULL != (wire = json_loads (valid_wire_str, 0, &error)));
ret = TALER_json_validate_wireformat ("SEPA", wire); ret = TALER_json_validate_wireformat ("SEPA", wire);
json_decref (wire);
if (1 == ret) if (1 == ret)
return 0; return 0;
return 1; return 1;

View File

@ -22,7 +22,6 @@
#include "platform.h" #include "platform.h"
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include "taler_util.h" #include "taler_util.h"
#include "taler_json_lib.h"
/** /**
* Shorthand for exit jumps. * Shorthand for exit jumps.
@ -298,10 +297,11 @@ validate_iban (const char *iban)
dividend += remainder * (pow (10, nread)); dividend += remainder * (pow (10, nread));
remainder = dividend % 97; remainder = dividend % 97;
} }
EXITIF (1 != remainder); if (1 == remainder)
{
GNUNET_free (nbuf); GNUNET_free (nbuf);
return GNUNET_YES; return GNUNET_YES;
}
EXITIF_exit: EXITIF_exit:
GNUNET_free (nbuf); GNUNET_free (nbuf);
return GNUNET_NO; return GNUNET_NO;
@ -346,7 +346,13 @@ validate_sepa (const json_t *wire)
"r", &r, "r", &r,
"address", &address)); "address", &address));
EXITIF (0 != strcmp (type, "SEPA")); EXITIF (0 != strcmp (type, "SEPA"));
EXITIF (1 != validate_iban (iban)); if (1 != validate_iban (iban))
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"IBAN `%s' invalid\n",
iban);
return GNUNET_NO;
}
return GNUNET_YES; return GNUNET_YES;
EXITIF_exit: EXITIF_exit:
return GNUNET_NO; return GNUNET_NO;
@ -394,7 +400,7 @@ TALER_json_validate_wireformat (const char *type,
if (0 == strcasecmp (format_handlers[i].type, if (0 == strcasecmp (format_handlers[i].type,
type)) type))
return format_handlers[i].handler (wire); return format_handlers[i].handler (wire);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Wireformat `%s' not supported\n", "Wireformat `%s' not supported\n",
type); type);
return GNUNET_NO; return GNUNET_NO;