intermediary commit, breaking the build by starting to move towards variable-size GNUnet signatures instead of fixed-size signatures; much broken now

This commit is contained in:
Christian Grothoff 2015-01-26 12:22:26 +01:00
parent d4506f8a04
commit ae917eeee0
23 changed files with 568 additions and 1583 deletions

View File

@ -5,6 +5,5 @@ talerinclude_HEADERS = \
taler_db_lib.h \ taler_db_lib.h \
taler_json_lib.h \ taler_json_lib.h \
taler_mint_service.h \ taler_mint_service.h \
taler_rsa.h \
taler_signatures.h \ taler_signatures.h \
taler_util.h taler_util.h

View File

@ -1,360 +0,0 @@
/* NOTE: this is obsolete logic, we should migrate to the
GNUNET_CRYPTO_rsa-API as soon as possible */
/*
This file is part of TALER
(C) 2014 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 include/taler_rsa.h
* @brief RSA key management utilities. Some code is taken from gnunet-0.9.5a
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
*
* Authors of the gnunet code:
* Christian Grothoff
* Krista Bennett
* Gerd Knorr <kraxel@bytesex.org>
* Ioana Patrascu
* Tzvetan Horozov
*/
#ifndef TALER_RSA_H
#define TALER_RSA_H
#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_crypto_lib.h>
/**
* Length of an RSA KEY (n,e,len), 2048 bit (=256 octests) key n, 2 byte e
*/
#define TALER_RSA_KEY_LENGTH 258
/**
* @brief Length of RSA encrypted data (2048 bit)
*
* We currently do not handle encryption of data
* that can not be done in a single call to the
* RSA methods (read: large chunks of data).
* We should never need that, as we can use
* the GNUNET_CRYPTO_hash for larger pieces of data for signing,
* and for encryption, we only need to encode sessionkeys!
*/
#define TALER_RSA_DATA_ENCODING_LENGTH 256
/**
* The private information of an RSA key pair.
*/
struct TALER_RSA_PrivateKey;
GNUNET_NETWORK_STRUCT_BEGIN
/**
* GNUnet mandates a certain format for the encoding
* of private RSA key information that is provided
* by the RSA implementations. This format is used
* to serialize a private RSA key (typically when
* writing it to disk).
*/
struct TALER_RSA_PrivateKeyBinaryEncoded
{
/**
* Total size of the structure, in bytes, in big-endian!
*/
uint16_t len GNUNET_PACKED;
uint16_t sizen GNUNET_PACKED; /* in big-endian! */
uint16_t sizee GNUNET_PACKED; /* in big-endian! */
uint16_t sized GNUNET_PACKED; /* in big-endian! */
uint16_t sizep GNUNET_PACKED; /* in big-endian! */
uint16_t sizeq GNUNET_PACKED; /* in big-endian! */
uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */
uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */
/* followed by the actual values */
};
GNUNET_NETWORK_STRUCT_END
/**
* @brief an RSA signature
*/
struct TALER_RSA_Signature
{
unsigned char sig[TALER_RSA_DATA_ENCODING_LENGTH];
};
GNUNET_NETWORK_STRUCT_BEGIN
/**
* @brief header of what an RSA signature signs
* this must be followed by "size - 8" bytes of
* the actual signed data
*/
struct TALER_RSA_SignaturePurpose
{
/**
* How many bytes does this signature sign?
* (including this purpose header); in network
* byte order (!).
*/
uint32_t size GNUNET_PACKED;
/**
* What does this signature vouch for? This
* must contain a GNUNET_SIGNATURE_PURPOSE_XXX
* constant (from gnunet_signatures.h). In
* network byte order!
*/
uint32_t purpose GNUNET_PACKED;
};
struct TALER_RSA_BlindedSignaturePurpose
{
unsigned char data[TALER_RSA_DATA_ENCODING_LENGTH];
};
/**
* @brief A public key.
*/
struct TALER_RSA_PublicKeyBinaryEncoded
{
/**
* In big-endian, must be GNUNET_CRYPTO_RSA_KEY_LENGTH+4
*/
uint16_t len GNUNET_PACKED;
/**
* Size of n in key; in big-endian!
*/
uint16_t sizen GNUNET_PACKED;
/**
* The key itself, contains n followed by e.
*/
unsigned char key[TALER_RSA_KEY_LENGTH];
/**
* Padding (must be 0)
*/
uint16_t padding GNUNET_PACKED;
};
GNUNET_NETWORK_STRUCT_END
/**
* Create a new private key. Caller must free return value.
*
* @return fresh private key
*/
struct TALER_RSA_PrivateKey *
TALER_RSA_key_create ();
/**
* Free memory occupied by the private key.
*
* @param key pointer to the memory to free
*/
void
TALER_RSA_key_free (struct TALER_RSA_PrivateKey *key);
/**
* Encode the private key in a format suitable for
* storing it into a file.
* @return encoding of the private key
*/
struct TALER_RSA_PrivateKeyBinaryEncoded *
TALER_RSA_encode_key (const struct TALER_RSA_PrivateKey *hostkey);
/**
* Extract the public key of the given private key.
*
* @param priv the private key
* @param pub where to write the public key
*/
void
TALER_RSA_key_get_public (const struct TALER_RSA_PrivateKey *priv,
struct TALER_RSA_PublicKeyBinaryEncoded *pub);
/**
* Decode the private key from the data-format back
* to the "normal", internal format.
*
* @param buf the buffer where the private key data is stored
* @param len the length of the data in 'buffer'
* @return NULL on error
*/
struct TALER_RSA_PrivateKey *
TALER_RSA_decode_key (const char *buf, uint16_t len);
/**
* Convert a public key to a string.
*
* @param pub key to convert
* @return string representing 'pub'
*/
char *
TALER_RSA_public_key_to_string (const struct TALER_RSA_PublicKeyBinaryEncoded *pub);
/**
* Convert a string representing a public key to a public key.
*
* @param enc encoded public key
* @param enclen number of bytes in enc (without 0-terminator)
* @param pub where to store the public key
* @return GNUNET_OK on success
*/
int
TALER_RSA_public_key_from_string (const char *enc,
size_t enclen,
struct TALER_RSA_PublicKeyBinaryEncoded *pub);
/**
* Sign a given block.h
*
* @param key private key to use for the signing
* @param msg the message
* @param size the size of the message
* @param sig where to write the signature
* @return GNUNET_SYSERR on error, GNUNET_OK on success
*/
int
TALER_RSA_sign (const struct TALER_RSA_PrivateKey *key,
const void *msg,
size_t size,
struct TALER_RSA_Signature *sig);
/**
* Verify signature with the given hash.
*
* @param hash the hash code to verify against the signature
* @param sig signature that is being validated
* @param publicKey public key of the signer
* @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid
*/
int
TALER_RSA_hash_verify (const struct GNUNET_HashCode *hash,
const struct TALER_RSA_Signature *sig,
const struct TALER_RSA_PublicKeyBinaryEncoded *publicKey);
/**
* Verify signature on the given message
*
* @param msg the message
* @param size the size of the message
* @param sig signature that is being validated
* @param publicKey public key of the signer
* @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid
*/
int
TALER_RSA_verify (const void *msg, size_t size,
const struct TALER_RSA_Signature *sig,
const struct TALER_RSA_PublicKeyBinaryEncoded *publicKey);
/**
* Key used to blind a message
*/
struct TALER_RSA_BlindingKey;
/**
* Create a blinding key
*
* @return the newly created blinding key
*/
struct TALER_RSA_BlindingKey *
TALER_RSA_blinding_key_create ();
/**
* Destroy a blinding key
*
* @param bkey the blinding key to destroy
*/
void
TALER_RSA_blinding_key_destroy (struct TALER_RSA_BlindingKey *bkey);
/**
* Binary encoding for TALER_RSA_BlindingKey
*/
struct TALER_RSA_BlindingKeyBinaryEncoded
{
unsigned char data[TALER_RSA_DATA_ENCODING_LENGTH];
};
/**
* Encode a blinding key
*
* @param bkey the blinding key to encode
* @param bkey_enc where to store the encoded binary key
* @return #GNUNET_OK upon successful encoding; #GNUNET_SYSERR upon failure
*/
int
TALER_RSA_blinding_key_encode (struct TALER_RSA_BlindingKey *bkey,
struct TALER_RSA_BlindingKeyBinaryEncoded *bkey_enc);
/**
* Decode a blinding key from its encoded form
*
* @param bkey_enc the encoded blinding key
* @return the decoded blinding key; NULL upon error
*/
struct TALER_RSA_BlindingKey *
TALER_RSA_blinding_key_decode (struct TALER_RSA_BlindingKeyBinaryEncoded *bkey_enc);
/**
* Blinds the given message with the given blinding key
*
* @param msg the message
* @param size the size of the message
* @param bkey the blinding key
* @param pkey the public key of the signer
* @return the blinding signature purpose; NULL upon any error
*/
struct TALER_RSA_BlindedSignaturePurpose *
TALER_RSA_message_blind (const void *msg, size_t size,
struct TALER_RSA_BlindingKey *bkey,
struct TALER_RSA_PublicKeyBinaryEncoded *pkey);
/**
* Unblind a signature made on blinding signature purpose. The signature
* purpose should have been generated with TALER_RSA_message_blind() function.
*
* @param sig the signature made on the blinded signature purpose
* @param bkey the blinding key used to blind the signature purpose
* @param pkey the public key of the signer
* @return GNUNET_SYSERR upon error; GNUNET_OK upon success.
*/
int
TALER_RSA_unblind (struct TALER_RSA_Signature *sig,
struct TALER_RSA_BlindingKey *bkey,
struct TALER_RSA_PublicKeyBinaryEncoded *pkey);
#endif /* TALER_RSA_H */
/* end of include/taler_rsa.h */

View File

@ -29,8 +29,6 @@
#define TALER_SIGNATURES_H #define TALER_SIGNATURES_H
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include "taler_rsa.h"
/** /**
* Purpose for signing public keys signed * Purpose for signing public keys signed
@ -113,17 +111,12 @@
GNUNET_NETWORK_STRUCT_BEGIN GNUNET_NETWORK_STRUCT_BEGIN
/** /**
* Request to withdraw coins from a reserve. * Format used for to generate the signature on a request to withdraw
* coins from a reserve.
*/ */
struct TALER_WithdrawRequest struct TALER_WithdrawRequest
{ {
/**
* Signature over the rest of the message
* by the withdraw public key.
*/
struct GNUNET_CRYPTO_EddsaSignature sig;
/** /**
* Purpose must be #TALER_SIGNATURE_WITHDRAW. * Purpose must be #TALER_SIGNATURE_WITHDRAW.
@ -131,24 +124,20 @@ struct TALER_WithdrawRequest
struct GNUNET_CRYPTO_EccSignaturePurpose purpose; struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
/** /**
* Reserve public key. * Reserve public key (which reserve to withdraw from). This is
* the public key which must match the signature.
*/ */
struct GNUNET_CRYPTO_EddsaPublicKey reserve_pub; struct GNUNET_CRYPTO_EddsaPublicKey reserve_pub;
/** /**
* Denomination public key for the coin that is withdrawn. * Hash of the denomination public key for the coin that is withdrawn.
* FIXME: change to the hash of the public key (so this
* is fixed-size).
*/ */
struct TALER_RSA_PublicKeyBinaryEncoded denomination_pub; struct GNUNET_HashCode h_denomination_pub;
/** /**
* Purpose containing coin's blinded public key. * Hash of the (blinded) message to be signed by the Mint.
*
* FIXME: this should be explicitly a variable-size field with the
* (blinded) message to be signed by the Mint.
*/ */
struct TALER_RSA_BlindedSignaturePurpose coin_envelope; struct GNUNET_HashCode h_coin_envelope;
}; };
@ -178,7 +167,8 @@ struct TALER_MINT_DenomKeyIssue
struct GNUNET_TIME_AbsoluteNBO start; struct GNUNET_TIME_AbsoluteNBO start;
struct GNUNET_TIME_AbsoluteNBO expire_withdraw; struct GNUNET_TIME_AbsoluteNBO expire_withdraw;
struct GNUNET_TIME_AbsoluteNBO expire_spend; struct GNUNET_TIME_AbsoluteNBO expire_spend;
struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; // FIXME: does not work like this:
struct GNUNET_CRYPTO_rsa_PublicKey * denom_pub;
struct TALER_AmountNBO value; struct TALER_AmountNBO value;
struct TALER_AmountNBO fee_withdraw; struct TALER_AmountNBO fee_withdraw;
struct TALER_AmountNBO fee_deposit; struct TALER_AmountNBO fee_deposit;
@ -238,4 +228,3 @@ struct RefreshMeltConfirmSignRequestBody
GNUNET_NETWORK_STRUCT_END GNUNET_NETWORK_STRUCT_END
#endif #endif

View File

@ -29,7 +29,6 @@
#include <gnunet/gnunet_common.h> #include <gnunet/gnunet_common.h>
#include <libpq-fe.h> #include <libpq-fe.h>
#include "taler_util.h" #include "taler_util.h"
#include "taler_rsa.h"
#include "taler_signatures.h" #include "taler_signatures.h"
#define DIR_SIGNKEYS "signkeys" #define DIR_SIGNKEYS "signkeys"
@ -55,7 +54,7 @@ struct TALER_MINT_DenomKeyIssuePriv
* The private key of the denomination. Will be NULL if the private key is * The private key of the denomination. Will be NULL if the private key is
* not available. * not available.
*/ */
struct TALER_RSA_PrivateKey *denom_priv; struct GNUNET_CRYPTO_rsa_PrivateKey *denom_priv;
struct TALER_MINT_DenomKeyIssue issue; struct TALER_MINT_DenomKeyIssue issue;
}; };
@ -75,26 +74,43 @@ struct TALER_CoinPublicInfo
/* /*
* The public key signifying the coin's denomination. * The public key signifying the coin's denomination.
*/ */
struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
/** /**
* Signature over coin_pub by denom_pub. * Signature over coin_pub by denom_pub.
*/ */
struct TALER_RSA_Signature denom_sig; struct GNUNET_CRYPTO_rsa_Signature *denom_sig;
}; };
/**
* Information we keep for a withdrawn coin to reproduce
* the /withdraw operation if needed, and to have proof
* that a reserve was drained by this amount.
*/
struct CollectableBlindcoin struct CollectableBlindcoin
{ {
struct TALER_RSA_BlindedSignaturePurpose ev;
struct TALER_RSA_Signature ev_sig; /**
struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; * Our signature over the (blinded) coin.
*/
struct GNUNET_CRYPTO_rsa_Signature *sig;
/**
* Denomination key (which coin was generated).
*/
struct GNUNET_CRYPOT_rsa_PublicKey *denom_pub;
/**
* Public key of the reserve that was drained.
*/
struct GNUNET_CRYPTO_EddsaPublicKey reserve_pub; struct GNUNET_CRYPTO_EddsaPublicKey reserve_pub;
/**
* Signature confirming the withdrawl, matching @e reserve_pub,
* @e denom_pub and @e h_blind.
*/
struct GNUNET_CRYPTO_EddsaSignature reserve_sig; struct GNUNET_CRYPTO_EddsaSignature reserve_sig;
}; };
@ -127,7 +143,7 @@ struct RefreshCommitLink
struct LinkData struct LinkData
{ {
struct GNUNET_CRYPTO_EcdsaPrivateKey coin_priv; struct GNUNET_CRYPTO_EcdsaPrivateKey coin_priv;
struct TALER_RSA_BlindingKeyBinaryEncoded bkey_enc; struct GNUNET_CRYPTO_rsa_BlindingKey *bkey_enc;
}; };
@ -149,7 +165,17 @@ GNUNET_NETWORK_STRUCT_END
struct RefreshCommitCoin struct RefreshCommitCoin
{ {
struct GNUNET_CRYPTO_EddsaPublicKey session_pub; struct GNUNET_CRYPTO_EddsaPublicKey session_pub;
struct TALER_RSA_BlindedSignaturePurpose coin_ev;
/**
* Blinded message to be signed (in envelope).
*/
char *coin_ev;
/**
* Number of bytes in @e coin_ev.
*/
size_t coin_ev_size;
uint16_t cnc_index; uint16_t cnc_index;
uint16_t newcoin_index; uint16_t newcoin_index;
char link_enc[sizeof (struct LinkData)]; char link_enc[sizeof (struct LinkData)];
@ -177,17 +203,17 @@ struct Deposit
/* FIXME: should be TALER_CoinPublicInfo */ /* FIXME: should be TALER_CoinPublicInfo */
struct GNUNET_CRYPTO_EddsaPublicKey coin_pub; struct GNUNET_CRYPTO_EddsaPublicKey coin_pub;
struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
struct TALER_RSA_Signature coin_sig; struct GNUNET_CRYPTO_rsa_Signature *coin_sig;
struct TALER_RSA_Signature ubsig; struct GNUNET_CRYPTO_rsa_Signature *ubsig; // ???
/** /**
* Type of the deposit (also purpose of the signature). Either * Type of the deposit (also purpose of the signature). Either
* #TALER_SIGNATURE_DEPOSIT or #TALER_SIGNATURE_INCREMENTAL_DEPOSIT. * #TALER_SIGNATURE_DEPOSIT or #TALER_SIGNATURE_INCREMENTAL_DEPOSIT.
*/ */
struct TALER_RSA_SignaturePurpose purpose; // struct TALER_RSA_SignaturePurpose purpose; // FIXME: bad type!
uint64_t transaction_id; uint64_t transaction_id;

View File

@ -93,7 +93,7 @@ TALER_MINT_read_denom_key (const char *filename,
uint64_t size; uint64_t size;
size_t offset; size_t offset;
void *data; void *data;
struct TALER_RSA_PrivateKey *priv; struct GNUNET_CRYPTO_rsa_PrivateKey *priv;
int ret; int ret;
ret = GNUNET_SYSERR; ret = GNUNET_SYSERR;
@ -115,7 +115,8 @@ TALER_MINT_read_denom_key (const char *filename,
data, data,
size)) size))
goto cleanup; goto cleanup;
if (NULL == (priv = TALER_RSA_decode_key (data + offset, size - offset))) if (NULL == (priv = GNUNET_CRYPTO_rsa_private_key_decode (data + offset,
size - offset)))
goto cleanup; goto cleanup;
dki->denom_priv = priv; dki->denom_priv = priv;
memcpy (&dki->issue.signature, data, offset); memcpy (&dki->issue.signature, data, offset);
@ -138,22 +139,22 @@ int
TALER_MINT_write_denom_key (const char *filename, TALER_MINT_write_denom_key (const char *filename,
const struct TALER_MINT_DenomKeyIssuePriv *dki) const struct TALER_MINT_DenomKeyIssuePriv *dki)
{ {
struct TALER_RSA_PrivateKeyBinaryEncoded *priv_enc; char *priv_enc;
size_t priv_enc_size;
struct GNUNET_DISK_FileHandle *fh; struct GNUNET_DISK_FileHandle *fh;
ssize_t wrote; ssize_t wrote;
size_t wsize; size_t wsize;
int ret; int ret;
fh = NULL; fh = NULL;
priv_enc = NULL; priv_enc_size = GNUNET_CRYPTO_rsa_private_key_encode (dki->denom_priv,
&priv_enc);
ret = GNUNET_SYSERR; ret = GNUNET_SYSERR;
if (NULL == (fh = GNUNET_DISK_file_open if (NULL == (fh = GNUNET_DISK_file_open
(filename, (filename,
GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE,
GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE))) GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE)))
goto cleanup; goto cleanup;
if (NULL == (priv_enc = TALER_RSA_encode_key (dki->denom_priv)))
goto cleanup;
wsize = sizeof (struct TALER_MINT_DenomKeyIssuePriv) wsize = sizeof (struct TALER_MINT_DenomKeyIssuePriv)
- offsetof (struct TALER_MINT_DenomKeyIssuePriv, issue.signature); - offsetof (struct TALER_MINT_DenomKeyIssuePriv, issue.signature);
if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh, if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh,
@ -162,12 +163,11 @@ TALER_MINT_write_denom_key (const char *filename,
goto cleanup; goto cleanup;
if (wrote != wsize) if (wrote != wsize)
goto cleanup; goto cleanup;
wsize = ntohs (priv_enc->len);
if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh, if (GNUNET_SYSERR == (wrote = GNUNET_DISK_file_write (fh,
priv_enc, priv_enc,
wsize))) priv_enc_size)))
goto cleanup; goto cleanup;
if (wrote != wsize) if (wrote != priv_enc_size)
goto cleanup; goto cleanup;
ret = GNUNET_OK; ret = GNUNET_OK;
cleanup: cleanup:

View File

@ -54,25 +54,44 @@ static char *TALER_MINT_db_connection_cfg_str;
if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ if (cond) { GNUNET_break (0); goto EXITIF_exit; } \
} while (0) } while (0)
/**
* Locate the response for a /withdraw request under the
* key of the hash of the blinded message.
*
* @param db_conn database connection to use
* @param h_blind hash of the blinded message
* @param collectable corresponding collectable coin (blind signature)
* if a coin is found
* @return #GNUNET_SYSERR on internal error
* #GNUNET_NO if the collectable was not found
* #GNUNET_YES on success
*/
int int
TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn, TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn,
struct TALER_RSA_BlindedSignaturePurpose *blind_ev, const struct GNUNET_HashCode *h_blind,
struct CollectableBlindcoin *collectable) struct CollectableBlindcoin *collectable)
{ {
PGresult *result; PGresult *result;
struct TALER_DB_QueryParam params[] = { struct TALER_DB_QueryParam params[] = {
TALER_DB_QUERY_PARAM_PTR (blind_ev), TALER_DB_QUERY_PARAM_PTR (h_blind),
TALER_DB_QUERY_PARAM_END TALER_DB_QUERY_PARAM_END
}; };
result = TALER_DB_exec_prepared (db_conn, "get_collectable_blindcoins", params); char *sig_buf;
size_t sig_buf_size;
result = TALER_DB_exec_prepared (db_conn,
"get_collectable_blindcoins",
params);
if (PGRES_TUPLES_OK != PQresultStatus (result)) if (PGRES_TUPLES_OK != PQresultStatus (result))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Query failed: %s\n", PQresultErrorMessage (result)); GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Query failed: %s\n",
PQresultErrorMessage (result));
PQclear (result); PQclear (result);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
if (0 == PQntuples (result)) if (0 == PQntuples (result))
{ {
PQclear (result); PQclear (result);
@ -80,7 +99,7 @@ TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn,
} }
struct TALER_DB_ResultSpec rs[] = { struct TALER_DB_ResultSpec rs[] = {
TALER_DB_RESULT_SPEC("blind_ev_sig", &collectable->ev_sig), TALER_DB_RESULT_SPEC_VAR("blind_sig", &sig_buf, &sig_buf_size),
TALER_DB_RESULT_SPEC("denom_pub", &collectable->denom_pub), TALER_DB_RESULT_SPEC("denom_pub", &collectable->denom_pub),
TALER_DB_RESULT_SPEC("reserve_sig", &collectable->reserve_sig), TALER_DB_RESULT_SPEC("reserve_sig", &collectable->reserve_sig),
TALER_DB_RESULT_SPEC("reserve_pub", &collectable->reserve_pub), TALER_DB_RESULT_SPEC("reserve_pub", &collectable->reserve_pub),
@ -93,43 +112,66 @@ TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn,
PQclear (result); PQclear (result);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
(void) memcpy (&collectable->ev, blind_ev, sizeof (struct TALER_RSA_BlindedSignaturePurpose));
PQclear (result); PQclear (result);
return GNUNET_OK; return GNUNET_OK;
} }
/**
* Store collectable bit coin under the corresponding
* hash of the blinded message.
*
* @param db_conn database connection to use
* @param h_blind hash of the blinded message
* @param collectable corresponding collectable coin (blind signature)
* if a coin is found
* @return #GNUNET_SYSERR on internal error
* #GNUNET_NO if the collectable was not found
* #GNUNET_YES on success
*/
int int
TALER_MINT_DB_insert_collectable_blindcoin (PGconn *db_conn, TALER_MINT_DB_insert_collectable_blindcoin (PGconn *db_conn,
const struct GNUNET_HashCode *h_blind,
const struct CollectableBlindcoin *collectable) const struct CollectableBlindcoin *collectable)
{ {
PGresult *result; PGresult *result;
struct TALER_DB_QueryParam params[] = { char *sig_buf;
TALER_DB_QUERY_PARAM_PTR (&collectable->ev), size_t sig_buf_size;
TALER_DB_QUERY_PARAM_PTR (&collectable->ev_sig),
TALER_DB_QUERY_PARAM_PTR (&collectable->denom_pub),
TALER_DB_QUERY_PARAM_PTR (&collectable->reserve_pub),
TALER_DB_QUERY_PARAM_PTR (&collectable->reserve_sig),
TALER_DB_QUERY_PARAM_END
};
result = TALER_DB_exec_prepared (db_conn, "insert_collectable_blindcoins", params);
if (PGRES_COMMAND_OK != PQresultStatus (result)) sig_buf_size = GNUNET_CRYPTO_rsa_signature_encode (collectable->sig,
&sig_buf);
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Query failed: %s\n", PQresultErrorMessage (result)); struct TALER_DB_QueryParam params[] = {
PQclear (result); TALER_DB_QUERY_PARAM_PTR (&h_blind),
return GNUNET_SYSERR; TALER_DB_QUERY_PARAM_PTR_SIZED (sig_buf, sig_buf_size),
} TALER_DB_QUERY_PARAM_PTR (&collectable->denom_pub),
TALER_DB_QUERY_PARAM_PTR (&collectable->reserve_pub),
TALER_DB_QUERY_PARAM_PTR (&collectable->reserve_sig),
TALER_DB_QUERY_PARAM_END
};
if (0 != strcmp ("1", PQcmdTuples (result))) result = TALER_DB_exec_prepared (db_conn,
{ "insert_collectable_blindcoins",
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Insert failed (updated '%s' tupes instead of '1')\n", params);
PQcmdTuples (result)); if (PGRES_COMMAND_OK != PQresultStatus (result))
PQclear (result); {
return GNUNET_SYSERR; GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
} "Query failed: %s\n",
PQresultErrorMessage (result));
PQclear (result);
return GNUNET_SYSERR;
}
PQclear (result); if (0 != strcmp ("1", PQcmdTuples (result)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Insert failed (updated '%s' tupes instead of '1')\n",
PQcmdTuples (result));
PQclear (result);
return GNUNET_SYSERR;
}
PQclear (result);
}
return GNUNET_OK; return GNUNET_OK;
} }
@ -730,7 +772,7 @@ int
TALER_MINT_DB_insert_refresh_order (PGconn *db_conn, TALER_MINT_DB_insert_refresh_order (PGconn *db_conn,
uint16_t newcoin_index, uint16_t newcoin_index,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub) const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub)
{ {
uint16_t newcoin_index_nbo = htons (newcoin_index); uint16_t newcoin_index_nbo = htons (newcoin_index);
struct TALER_DB_QueryParam params[] = { struct TALER_DB_QueryParam params[] = {
@ -1267,7 +1309,7 @@ int
TALER_MINT_DB_get_refresh_order (PGconn *db_conn, TALER_MINT_DB_get_refresh_order (PGconn *db_conn,
uint16_t newcoin_index, uint16_t newcoin_index,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub) struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub)
{ {
uint16_t newcoin_index_nbo = htons (newcoin_index); uint16_t newcoin_index_nbo = htons (newcoin_index);
@ -1315,7 +1357,7 @@ int
TALER_MINT_DB_insert_refresh_collectable (PGconn *db_conn, TALER_MINT_DB_insert_refresh_collectable (PGconn *db_conn,
uint16_t newcoin_index, uint16_t newcoin_index,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
const struct TALER_RSA_Signature *ev_sig) const struct GNUNET_CRYPTO_rsa_Signature *ev_sig)
{ {
uint16_t newcoin_index_nbo = htons (newcoin_index); uint16_t newcoin_index_nbo = htons (newcoin_index);
struct TALER_DB_QueryParam params[] = { struct TALER_DB_QueryParam params[] = {
@ -1343,7 +1385,7 @@ int
TALER_MINT_DB_get_refresh_collectable (PGconn *db_conn, TALER_MINT_DB_get_refresh_collectable (PGconn *db_conn,
uint16_t newcoin_index, uint16_t newcoin_index,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
struct TALER_RSA_Signature *ev_sig) struct GNUNET_CRYPTO_rsa_Signature *ev_sig)
{ {
uint16_t newcoin_index_nbo = htons (newcoin_index); uint16_t newcoin_index_nbo = htons (newcoin_index);
@ -1394,7 +1436,7 @@ TALER_MINT_DB_insert_refresh_melt (PGconn *db_conn,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
uint16_t oldcoin_index, uint16_t oldcoin_index,
const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub, const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub) const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub)
{ {
uint16_t oldcoin_index_nbo = htons (oldcoin_index); uint16_t oldcoin_index_nbo = htons (oldcoin_index);
struct TALER_DB_QueryParam params[] = { struct TALER_DB_QueryParam params[] = {
@ -1499,8 +1541,8 @@ TALER_db_get_link (PGconn *db_conn,
for (i = 0; i < PQntuples (result); i++) for (i = 0; i < PQntuples (result); i++)
{ {
struct LinkDataEnc link_data_enc; struct LinkDataEnc link_data_enc;
struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; struct GNUNET_CRYPTO_rsa__PublicKey *denom_pub;
struct TALER_RSA_Signature ev_sig; struct GNUNET_CRYPTO_rsa_Signature *sig;
struct TALER_DB_ResultSpec rs[] = { struct TALER_DB_ResultSpec rs[] = {
TALER_DB_RESULT_SPEC("link_vector_enc", &link_data_enc), TALER_DB_RESULT_SPEC("link_vector_enc", &link_data_enc),
TALER_DB_RESULT_SPEC("denom_pub", &denom_pub), TALER_DB_RESULT_SPEC("denom_pub", &denom_pub),

View File

@ -27,7 +27,6 @@
#include <microhttpd.h> #include <microhttpd.h>
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include "taler_util.h" #include "taler_util.h"
#include "taler_rsa.h"
#include "taler-mint-httpd_db.h" #include "taler-mint-httpd_db.h"
#include "mint.h" #include "mint.h"
@ -35,13 +34,40 @@
int int
TALER_MINT_DB_prepare (PGconn *db_conn); TALER_MINT_DB_prepare (PGconn *db_conn);
/**
* Locate the response for a /withdraw request under the
* key of the hash of the blinded message.
*
* @param db_conn database connection to use
* @param h_blind hash of the blinded message
* @param collectable corresponding collectable coin (blind signature)
* if a coin is found
* @return #GNUNET_SYSERR on internal error
* #GNUNET_NO if the collectable was not found
* #GNUNET_YES on success
*/
int int
TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn, TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn,
struct TALER_RSA_BlindedSignaturePurpose *blind_ev, const struct GNUNET_HashCode *h_blind,
struct CollectableBlindcoin *collectable); struct CollectableBlindcoin *collectable);
/**
* Store collectable bit coin under the corresponding
* hash of the blinded message.
*
* @param db_conn database connection to use
* @param h_blind hash of the blinded message
* @param collectable corresponding collectable coin (blind signature)
* if a coin is found
* @return #GNUNET_SYSERR on internal error
* #GNUNET_NO if the collectable was not found
* #GNUNET_YES on success
*/
int int
TALER_MINT_DB_insert_collectable_blindcoin (PGconn *db_conn, TALER_MINT_DB_insert_collectable_blindcoin (PGconn *db_conn,
const struct GNUNET_HashCode *h_blind,
const struct CollectableBlindcoin *collectable); const struct CollectableBlindcoin *collectable);
@ -62,6 +88,15 @@ TALER_MINT_DB_get_reserve (PGconn *db_conn,
const struct GNUNET_CRYPTO_EddsaPublicKey *reserve_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *reserve_pub,
struct Reserve *reserve_res); struct Reserve *reserve_res);
/**
* Update information about a reserve.
*
* @param db_conn
* @param reserve current reserve status
* @param fresh FIXME
* @return #GNUNET_OK on success
*/
int int
TALER_MINT_DB_update_reserve (PGconn *db_conn, TALER_MINT_DB_update_reserve (PGconn *db_conn,
const struct Reserve *reserve, const struct Reserve *reserve,
@ -72,7 +107,7 @@ int
TALER_MINT_DB_insert_refresh_order (PGconn *db_conn, TALER_MINT_DB_insert_refresh_order (PGconn *db_conn,
uint16_t newcoin_index, uint16_t newcoin_index,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub); const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub);
int int
TALER_MINT_DB_get_refresh_session (PGconn *db_conn, TALER_MINT_DB_get_refresh_session (PGconn *db_conn,
@ -123,19 +158,22 @@ int
TALER_MINT_DB_get_refresh_order (PGconn *db_conn, TALER_MINT_DB_get_refresh_order (PGconn *db_conn,
uint16_t newcoin_index, uint16_t newcoin_index,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub); struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub);
int int
TALER_MINT_DB_insert_refresh_collectable (PGconn *db_conn, TALER_MINT_DB_insert_refresh_collectable (PGconn *db_conn,
uint16_t newcoin_index, uint16_t newcoin_index,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
const struct TALER_RSA_Signature *ev_sig); const struct GNUNET_CRYPTO_rsa_Signature *ev_sig);
int int
TALER_MINT_DB_get_refresh_collectable (PGconn *db_conn, TALER_MINT_DB_get_refresh_collectable (PGconn *db_conn,
uint16_t newcoin_index, uint16_t newcoin_index,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
struct TALER_RSA_Signature *ev_sig); struct GNUNET_CRYPTO_rsa_Signature *ev_sig);
int int
TALER_MINT_DB_set_reveal_ok (PGconn *db_conn, TALER_MINT_DB_set_reveal_ok (PGconn *db_conn,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub); const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub);
@ -145,7 +183,7 @@ TALER_MINT_DB_insert_refresh_melt (PGconn *db_conn,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
uint16_t oldcoin_index, uint16_t oldcoin_index,
const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub, const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub); const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub);
int int
@ -158,8 +196,8 @@ TALER_MINT_DB_get_refresh_melt (PGconn *db_conn,
typedef typedef
int (*LinkIterator) (void *cls, int (*LinkIterator) (void *cls,
const struct LinkDataEnc *link_data_enc, const struct LinkDataEnc *link_data_enc,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub, const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub,
const struct TALER_RSA_Signature *ev_sig); const struct GNUNET_CRYPTO_rsa_Signature *ev_sig);
int int
TALER_db_get_link (PGconn *db_conn, TALER_db_get_link (PGconn *db_conn,

View File

@ -29,7 +29,6 @@
#include <pthread.h> #include <pthread.h>
#include "mint.h" #include "mint.h"
#include "taler_signatures.h" #include "taler_signatures.h"
#include "taler_rsa.h"
#include "taler_json_lib.h" #include "taler_json_lib.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"

View File

@ -83,9 +83,9 @@ TALER_MINT_db_execute_deposit (struct MHD_Connection *connection,
if (GNUNET_SYSERR == res) if (GNUNET_SYSERR == res)
{ {
GNUNET_break (0); GNUNET_break (0);
/* FIXME: return error message to client via MHD! */ /* FIXME: return error message to client via MHD! */
return MHD_NO; return MHD_NO;
} }
{ {
@ -221,56 +221,65 @@ TALER_MINT_db_execute_withdraw_status (struct MHD_Connection *connection,
* Execute a /withdraw/sign. * Execute a /withdraw/sign.
* *
* @param connection the MHD connection to handle * @param connection the MHD connection to handle
* @param wsrd_ro details about the withdraw request * @param reserve public key of the reserve
* @param denomination_pub public key of the denomination requested
* @param blinded_msg blinded message to be signed
* @param blinded_msg_len number of bytes in @a blinded_msg
* @param signature signature over the withdraw request, to be stored in DB
* @return MHD result code * @return MHD result code
*/ */
int int
TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection, TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,
const struct TALER_WithdrawRequest *wsrd_ro) const struct GNUNET_CRYPTO_EddsaPublicKey *reserve,
const struct GNUNET_CRYPTO_rsa_PublicKey *denomination_pub,
const char *blinded_msg,
size_t blinded_msg_len,
const struct GNUNET_CRYPTO_EddsaSignature *signature)
{ {
PGconn *db_conn; PGconn *db_conn;
struct Reserve reserve; struct Reserve db_reserve;
struct MintKeyState *key_state; struct MintKeyState *key_state;
struct CollectableBlindcoin collectable; struct CollectableBlindcoin collectable;
struct TALER_MINT_DenomKeyIssuePriv *dki; struct TALER_MINT_DenomKeyIssuePriv *dki;
struct TALER_RSA_Signature ev_sig; struct GNUNET_CRYPTO_rsa_Signature *sig;
struct TALER_Amount amount_required; struct TALER_Amount amount_required;
/* FIXME: the fact that we do this here is a sign that we struct GNUNET_HashCode h_blind;
need to have different versions of this struct for
the different places it is used! */
struct TALER_WithdrawRequest wsrd = *wsrd_ro;
int res; int res;
GNUNET_CRYPTO_hash (blinded_msg,
blinded_msg_len,
&h_blind);
if (NULL == (db_conn = TALER_MINT_DB_get_connection ())) if (NULL == (db_conn = TALER_MINT_DB_get_connection ()))
{ {
GNUNET_break (0); GNUNET_break (0);
return TALER_MINT_reply_internal_db_error (connection); return TALER_MINT_reply_internal_db_error (connection);
} }
res = TALER_MINT_DB_get_collectable_blindcoin (db_conn, res = TALER_MINT_DB_get_collectable_blindcoin (db_conn,
&wsrd.coin_envelope, &h_blind,
&collectable); &collectable);
if (GNUNET_SYSERR == res) if (GNUNET_SYSERR == res)
{ {
// FIXME: return 'internal error'
GNUNET_break (0); GNUNET_break (0);
return MHD_NO; return TALER_MINT_reply_internal_db_error (connection);
} }
/* Don't sign again if we have already signed the coin */ /* Don't sign again if we have already signed the coin */
if (GNUNET_YES == res) if (GNUNET_YES == res)
return TALER_MINT_reply_withdraw_sign_success (connection, {
&collectable); res = TALER_MINT_reply_withdraw_sign_success (connection,
&collectable);
GNUNET_CRYPTO_rsa_signature_free (collectable.sig);
return res;
}
GNUNET_assert (GNUNET_NO == res); GNUNET_assert (GNUNET_NO == res);
res = TALER_MINT_DB_get_reserve (db_conn, res = TALER_MINT_DB_get_reserve (db_conn,
&wsrd.reserve_pub, reserve,
&reserve); &db_reserve);
if (GNUNET_SYSERR == res) if (GNUNET_SYSERR == res)
{ {
// FIXME: return 'internal error'
GNUNET_break (0); GNUNET_break (0);
return MHD_NO; return TALER_MINT_reply_internal_db_error (connection);
} }
if (GNUNET_NO == res) if (GNUNET_NO == res)
return TALER_MINT_reply_json_pack (connection, return TALER_MINT_reply_json_pack (connection,
@ -279,26 +288,9 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,
"error", "error",
"Reserve not found"); "Reserve not found");
// fill out all the missing info in the request before
// we can check the signature on the request
wsrd.purpose.purpose = htonl (TALER_SIGNATURE_WITHDRAW);
wsrd.purpose.size = htonl (sizeof (struct TALER_WithdrawRequest) -
offsetof (struct TALER_WithdrawRequest, purpose));
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WITHDRAW,
&wsrd.purpose,
&wsrd.sig,
&wsrd.reserve_pub))
return TALER_MINT_reply_json_pack (connection,
MHD_HTTP_UNAUTHORIZED,
"{s:s}",
"error", "Invalid Signature");
key_state = TALER_MINT_key_state_acquire (); key_state = TALER_MINT_key_state_acquire ();
dki = TALER_MINT_get_denom_key (key_state, dki = TALER_MINT_get_denom_key (key_state,
&wsrd.denomination_pub); denomination_pub);
TALER_MINT_key_state_release (key_state); TALER_MINT_key_state_release (key_state);
if (NULL == dki) if (NULL == dki)
return TALER_MINT_reply_json_pack (connection, return TALER_MINT_reply_json_pack (connection,
@ -307,52 +299,54 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,
"error", "error",
"Denomination not found"); "Denomination not found");
amount_required = TALER_amount_ntoh (dki->issue.value); amount_required = TALER_amount_add (TALER_amount_ntoh (dki->issue.value),
amount_required = TALER_amount_add (amount_required,
TALER_amount_ntoh (dki->issue.fee_withdraw)); TALER_amount_ntoh (dki->issue.fee_withdraw));
if (0 < TALER_amount_cmp (amount_required, if (0 < TALER_amount_cmp (amount_required,
TALER_amount_ntoh (reserve.balance))) TALER_amount_ntoh (db_reserve.balance)))
return TALER_MINT_reply_json_pack (connection, return TALER_MINT_reply_json_pack (connection,
MHD_HTTP_PAYMENT_REQUIRED, MHD_HTTP_PAYMENT_REQUIRED,
"{s:s}", "{s:s}",
"error", "error",
"Insufficient funds"); "Insufficient funds");
if (GNUNET_OK !=
TALER_RSA_sign (dki->denom_priv, db_reserve.balance = TALER_amount_hton
&wsrd.coin_envelope, (TALER_amount_subtract (TALER_amount_ntoh (db_reserve.balance),
sizeof (struct TALER_RSA_BlindedSignaturePurpose), amount_required));
&ev_sig))
sig = GNUNET_CRYPTO_rsa_sign (dki->denom_priv,
blinded_msg,
blinded_msg_len);
if (NULL == sig)
{ {
// FIXME: return 'internal error'
GNUNET_break (0); GNUNET_break (0);
return MHD_NO; return TALER_MINT_reply_internal_error (connection,
"Internal error");
} }
reserve.balance = TALER_amount_hton (TALER_amount_subtract (TALER_amount_ntoh (reserve.balance), /* transaction start */
amount_required));
if (GNUNET_OK != if (GNUNET_OK !=
TALER_MINT_DB_update_reserve (db_conn, TALER_MINT_DB_update_reserve (db_conn,
&reserve, &db_reserve,
GNUNET_YES)) GNUNET_YES))
{ {
// FIXME: return 'internal error'
GNUNET_break (0); GNUNET_break (0);
return MHD_NO; return TALER_MINT_reply_internal_db_error (connection);
} }
collectable.ev = wsrd.coin_envelope; collectable.ev = wsrd.coin_envelope;
collectable.ev_sig = ev_sig; collectable.sig = sig;
collectable.reserve_pub = wsrd.reserve_pub; collectable.reserve_pub = wsrd.reserve_pub;
collectable.reserve_sig = wsrd.sig; collectable.reserve_sig = wsrd.sig;
if (GNUNET_OK != if (GNUNET_OK !=
TALER_MINT_DB_insert_collectable_blindcoin (db_conn, TALER_MINT_DB_insert_collectable_blindcoin (db_conn,
&h_blind,
&collectable)) &collectable))
{ {
// FIXME: return 'internal error'
GNUNET_break (0); GNUNET_break (0);
return GNUNET_NO;; GNUNET_CRYPTO_rsa_signature_free (sig);
return TALER_MINT_reply_internal_db_error (connection);
} }
/* transaction end */
GNUNET_CRYPTO_rsa_signature_free (sig);
return TALER_MINT_reply_withdraw_sign_success (connection, return TALER_MINT_reply_withdraw_sign_success (connection,
&collectable); &collectable);
} }
@ -378,7 +372,7 @@ refresh_accept_denoms (struct MHD_Connection *connection,
const struct MintKeyState *key_state, const struct MintKeyState *key_state,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
unsigned int denom_pubs_count, unsigned int denom_pubs_count,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pubs, const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pubs,
struct TALER_Amount *r_amount) struct TALER_Amount *r_amount)
{ {
unsigned int i; unsigned int i;
@ -554,7 +548,7 @@ int
TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection, TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
unsigned int num_new_denoms, unsigned int num_new_denoms,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pubs, const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pubs,
unsigned int coin_count, unsigned int coin_count,
const struct TALER_CoinPublicInfo *coin_public_infos) const struct TALER_CoinPublicInfo *coin_public_infos)
{ {
@ -821,10 +815,10 @@ helper_refresh_reveal_send_response (struct MHD_Connection *connection,
{ {
int res; int res;
unsigned int newcoin_index; unsigned int newcoin_index;
struct TALER_RSA_Signature *sigs; struct GNUNET_CRYPTO_rsa_Signature **sigs;
sigs = GNUNET_malloc (refresh_session->num_newcoins * sigs = GNUNET_malloc (refresh_session->num_newcoins *
sizeof (struct TALER_RSA_Signature)); sizeof (struct GNUNET_CRYPTO_rsa_Signature *));
for (newcoin_index = 0; newcoin_index < refresh_session->num_newcoins; newcoin_index++) for (newcoin_index = 0; newcoin_index < refresh_session->num_newcoins; newcoin_index++)
{ {
res = TALER_MINT_DB_get_refresh_collectable (db_conn, res = TALER_MINT_DB_get_refresh_collectable (db_conn,
@ -984,10 +978,12 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
{ {
struct RefreshCommitCoin commit_coin; struct RefreshCommitCoin commit_coin;
struct LinkData link_data; struct LinkData link_data;
struct TALER_RSA_BlindedSignaturePurpose *coin_ev_check; // struct BlindedSignaturePurpose *coin_ev_check;
struct GNUNET_CRYPTO_EcdsaPublicKey coin_pub; struct GNUNET_CRYPTO_EcdsaPublicKey coin_pub;
struct TALER_RSA_BlindingKey *bkey; struct GNUNET_CRYPTO_rsa_BlindingKey *bkey;
struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
char *buf;
size_t buf_len;
bkey = NULL; bkey = NULL;
res = TALER_MINT_DB_get_refresh_commit_coin (db_conn, res = TALER_MINT_DB_get_refresh_commit_coin (db_conn,
@ -1011,7 +1007,8 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
} }
GNUNET_CRYPTO_ecdsa_key_get_public (&link_data.coin_priv, &coin_pub); GNUNET_CRYPTO_ecdsa_key_get_public (&link_data.coin_priv, &coin_pub);
if (NULL == (bkey = TALER_RSA_blinding_key_decode (&link_data.bkey_enc))) if (NULL == (bkey = GNUNET_CRYPTO_rsa_blinding_key_decode (link_data.bkey_enc,
link_data.bkey_enc_size)))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid blinding key\n"); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid blinding key\n");
// FIXME: return error code! // FIXME: return error code!
@ -1024,26 +1021,31 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
// FIXME: return error code! // FIXME: return error code!
return MHD_NO; return MHD_NO;
} }
if (NULL == (coin_ev_check = if (NULL == (buf_len =
TALER_RSA_message_blind (&coin_pub, GNUNET_CRYPTO_rsa_blind (&h_msg,
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
bkey, bkey,
&denom_pub))) denom_pub,
&buf)))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "blind failed\n"); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "blind failed\n");
// FIXME: return error code! // FIXME: return error code!
return MHD_NO; return MHD_NO;
} }
if (0 != memcmp (&coin_ev_check, if ( (buf_len != commit_coin.coin_ev_size) ||
&commit_coin.coin_ev, (0 != memcmp (buf,
sizeof (struct TALER_RSA_BlindedSignaturePurpose))) commit_coin.coin_ev,
buf_len)) )
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "blind envelope does not match for kappa=%d, old=%d\n", GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"blind envelope does not match for kappa=%d, old=%d\n",
(int) (i+off), (int) j); (int) (i+off), (int) j);
// FIXME: return error code! // FIXME: return error code!
GNUNET_free (buf);
return MHD_NO; return MHD_NO;
} }
GNUNET_free (buf);
} }
} }
@ -1058,9 +1060,9 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
for (j = 0; j < refresh_session.num_newcoins; j++) for (j = 0; j < refresh_session.num_newcoins; j++)
{ {
struct RefreshCommitCoin commit_coin; struct RefreshCommitCoin commit_coin;
struct TALER_RSA_PublicKeyBinaryEncoded denom_pub; struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
struct TALER_MINT_DenomKeyIssuePriv *dki; struct TALER_MINT_DenomKeyIssuePriv *dki;
struct TALER_RSA_Signature ev_sig; struct GNUNET_CRYPTO_rsa_Signature *ev_sig;
res = TALER_MINT_DB_get_refresh_commit_coin (db_conn, res = TALER_MINT_DB_get_refresh_commit_coin (db_conn,
refresh_session_pub, refresh_session_pub,
@ -1091,11 +1093,10 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
// FIXME: return error code! // FIXME: return error code!
return MHD_NO; return MHD_NO;
} }
if (GNUNET_OK != ev_sig = GNUNET_CRYPTO_rsa_sign (dki->denom_priv,
TALER_RSA_sign (dki->denom_priv, commit_coin.coin_ev,
&commit_coin.coin_ev, commit_coin.coin_ev_len);
sizeof (struct TALER_RSA_BlindedSignaturePurpose), if (NULL == ev_sig)
&ev_sig))
{ {
GNUNET_break (0); GNUNET_break (0);
// FIXME: return error code! // FIXME: return error code!
@ -1144,25 +1145,33 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
static int static int
link_iter (void *cls, link_iter (void *cls,
const struct LinkDataEnc *link_data_enc, const struct LinkDataEnc *link_data_enc,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub, const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub,
const struct TALER_RSA_Signature *ev_sig) const struct GNUNET_CRYPTO_rsa_Signature *ev_sig)
{ {
json_t *list = cls; json_t *list = cls;
json_t *obj = json_object (); json_t *obj = json_object ();
char *buf;
size_t buf_len;
json_array_append_new (list, obj); json_array_append_new (list, obj);
json_object_set_new (obj, "link_enc", json_object_set_new (obj, "link_enc",
TALER_JSON_from_data (link_data_enc, TALER_JSON_from_data (link_data_enc,
sizeof (struct LinkDataEnc))); sizeof (struct LinkDataEnc)));
buf_len = GNUNET_CRYPTO_rsa_public_key_encode (denom_pub,
&buf);
json_object_set_new (obj, "denom_pub", json_object_set_new (obj, "denom_pub",
TALER_JSON_from_data (denom_pub, TALER_JSON_from_data (buf,
sizeof (struct TALER_RSA_PublicKeyBinaryEncoded))); buf_len));
GNUNET_free (buf);
buf_len = GNUNET_CRYPTO_rsa_signature_encode (ev_sig,
&buf);
json_object_set_new (obj, "ev_sig", json_object_set_new (obj, "ev_sig",
TALER_JSON_from_data (ev_sig, TALER_JSON_from_data (buf,
sizeof (struct TALER_RSA_Signature))); buf_len));
GNUNET_free (buf_len);
return GNUNET_OK; return GNUNET_OK;
} }

View File

@ -25,7 +25,6 @@
#include <microhttpd.h> #include <microhttpd.h>
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include "taler_util.h" #include "taler_util.h"
#include "taler_rsa.h"
#include "taler-mint-httpd_keys.h" #include "taler-mint-httpd_keys.h"
#include "mint.h" #include "mint.h"
@ -62,12 +61,20 @@ TALER_MINT_db_execute_withdraw_status (struct MHD_Connection *connection,
* Execute a /withdraw/sign. * Execute a /withdraw/sign.
* *
* @param connection the MHD connection to handle * @param connection the MHD connection to handle
* @param wsrd details about the withdraw request * @param reserve public key of the reserve
* @param denomination_pub public key of the denomination requested
* @param blinded_msg blinded message to be signed
* @param blinded_msg_len number of bytes in @a blinded_msg
* @param signature signature over the withdraw request, to be stored in DB
* @return MHD result code * @return MHD result code
*/ */
int int
TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection, TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,
const struct TALER_WithdrawRequest *wsrd); const struct GNUNET_CRYPTO_EddsaPublicKey *reserve,
const struct GNUNET_CRYPTO_rsa_PublicKey *denomination_pub,
const char *blinded_msg,
size_t blinded_msg_len,
const struct GNUNET_CRYPTO_EddsaSignature *signature);
@ -86,7 +93,7 @@ int
TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection, TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub, const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
unsigned int num_new_denoms, unsigned int num_new_denoms,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pubs, const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pubs,
unsigned int coin_count, unsigned int coin_count,
const struct TALER_CoinPublicInfo *coin_public_infos); const struct TALER_CoinPublicInfo *coin_public_infos);

View File

@ -36,7 +36,6 @@
#include "mint.h" #include "mint.h"
#include "mint_db.h" #include "mint_db.h"
#include "taler_signatures.h" #include "taler_signatures.h"
#include "taler_rsa.h"
#include "taler_json_lib.h" #include "taler_json_lib.h"
#include "taler-mint-httpd_parsing.h" #include "taler-mint-httpd_parsing.h"
#include "taler-mint-httpd_keys.h" #include "taler-mint-httpd_keys.h"

View File

@ -32,7 +32,6 @@
#include <pthread.h> #include <pthread.h>
#include "mint.h" #include "mint.h"
#include "taler_signatures.h" #include "taler_signatures.h"
#include "taler_rsa.h"
#include "taler_json_lib.h" #include "taler_json_lib.h"
#include "taler-mint-httpd_parsing.h" #include "taler-mint-httpd_parsing.h"
#include "taler-mint-httpd_keys.h" #include "taler-mint-httpd_keys.h"
@ -66,14 +65,23 @@ static int reload_pipe[2];
static json_t * static json_t *
denom_key_issue_to_json (const struct TALER_MINT_DenomKeyIssue *dki) denom_key_issue_to_json (const struct TALER_MINT_DenomKeyIssue *dki)
{ {
char *buf;
size_t buf_len;
json_t *dk_json = json_object (); json_t *dk_json = json_object ();
json_object_set_new (dk_json, "master_sig", json_object_set_new (dk_json, "master_sig",
TALER_JSON_from_data (&dki->signature, sizeof (struct GNUNET_CRYPTO_EddsaSignature))); TALER_JSON_from_data (&dki->signature, sizeof (struct GNUNET_CRYPTO_EddsaSignature)));
json_object_set_new (dk_json, "stamp_start", TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->start))); json_object_set_new (dk_json, "stamp_start", TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->start)));
json_object_set_new (dk_json, "stamp_expire_withdraw", TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->expire_withdraw))); json_object_set_new (dk_json, "stamp_expire_withdraw", TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->expire_withdraw)));
json_object_set_new (dk_json, "stamp_expire_deposit", TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->expire_spend))); json_object_set_new (dk_json, "stamp_expire_deposit", TALER_JSON_from_abs (GNUNET_TIME_absolute_ntoh (dki->expire_spend)));
buf_len = GNUNET_CRYPTO_rsa_public_key_encode (dki->denom_pub,
&buf);
json_object_set_new (dk_json, "denom_pub", json_object_set_new (dk_json, "denom_pub",
TALER_JSON_from_data (&dki->denom_pub, sizeof (struct TALER_RSA_PublicKeyBinaryEncoded))); TALER_JSON_from_data (buf,
buf_len));
GNUNET_free (buf);
json_object_set_new (dk_json, "value", json_object_set_new (dk_json, "value",
TALER_JSON_from_amount (TALER_amount_ntoh (dki->value))); TALER_JSON_from_amount (TALER_amount_ntoh (dki->value)));
json_object_set_new (dk_json, json_object_set_new (dk_json,
@ -341,14 +349,19 @@ TALER_MINT_key_state_acquire (void)
*/ */
struct TALER_MINT_DenomKeyIssuePriv * struct TALER_MINT_DenomKeyIssuePriv *
TALER_MINT_get_denom_key (const struct MintKeyState *key_state, TALER_MINT_get_denom_key (const struct MintKeyState *key_state,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub) const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub)
{ {
struct TALER_MINT_DenomKeyIssuePriv *issue; struct TALER_MINT_DenomKeyIssuePriv *issue;
struct GNUNET_HashCode hash; struct GNUNET_HashCode hash;
char *buf;
size_t buf_len;
GNUNET_CRYPTO_hash (denom_pub, buf_len = GNUNET_CRYPTO_rsa_public_key_encode (denom_pub,
sizeof (struct TALER_RSA_PublicKeyBinaryEncoded), *buf);
GNUNET_CRYPTO_hash (buf,
buf_len,
&hash); &hash);
GNUNET_free (buf);
issue = GNUNET_CONTAINER_multihashmap_get (key_state->denomkey_map, &hash); issue = GNUNET_CONTAINER_multihashmap_get (key_state->denomkey_map, &hash);
return issue; return issue;
} }
@ -373,10 +386,10 @@ TALER_MINT_test_coin_valid (const struct MintKeyState *key_state,
dki = TALER_MINT_get_denom_key (key_state, &coin_public_info->denom_pub); dki = TALER_MINT_get_denom_key (key_state, &coin_public_info->denom_pub);
if (NULL == dki) if (NULL == dki)
return GNUNET_NO; return GNUNET_NO;
if (GNUNET_OK != TALER_RSA_verify (&coin_public_info->coin_pub, if (GNUNET_OK !=
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), GNUNET_CRYPTO_rsa_verify (&c_hash,
&coin_public_info->denom_sig, coin_public_info->denom_sig,
&dki->issue.denom_pub)) dki->issue.denom_pub))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"coin signature is invalid\n"); "coin signature is invalid\n");

View File

@ -107,7 +107,7 @@ TALER_MINT_key_state_acquire (void);
*/ */
struct TALER_MINT_DenomKeyIssuePriv * struct TALER_MINT_DenomKeyIssuePriv *
TALER_MINT_get_denom_key (const struct MintKeyState *key_state, TALER_MINT_get_denom_key (const struct MintKeyState *key_state,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub); const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub);
/** /**
@ -116,9 +116,9 @@ TALER_MINT_get_denom_key (const struct MintKeyState *key_state,
* *
* @param key_state the key state to use for checking the coin's validity * @param key_state the key state to use for checking the coin's validity
* @param coin_public_info the coin public info to check for validity * @param coin_public_info the coin public info to check for validity
* @return GNUNET_YES if the coin is valid, * @return #GNUNET_YES if the coin is valid,
* GNUNET_NO if it is invalid * #GNUNET_NO if it is invalid
* GNUNET_SYSERROR if an internal error occured * #GNUNET_SYSERROR if an internal error occured
*/ */
int int
TALER_MINT_test_coin_valid (const struct MintKeyState *key_state, TALER_MINT_test_coin_valid (const struct MintKeyState *key_state,
@ -129,7 +129,7 @@ TALER_MINT_test_coin_valid (const struct MintKeyState *key_state,
* Read signals from a pipe in a loop, and reload keys from disk if * Read signals from a pipe in a loop, and reload keys from disk if
* SIGUSR1 is read from the pipe. * SIGUSR1 is read from the pipe.
* *
* @return GNUNET_OK if we terminated normally, GNUNET_SYSERR on error * @return #GNUNET_OK if we terminated normally, #GNUNET_SYSERR on error
*/ */
int int
TALER_MINT_key_reload_loop (void); TALER_MINT_key_reload_loop (void);

View File

@ -553,22 +553,29 @@ TALER_MINT_parse_json_data (struct MHD_Connection *connection,
{ {
unsigned int i; unsigned int i;
int ret; int ret;
void *ptr;
ret = GNUNET_YES; ret = GNUNET_YES;
for (i=0; NULL != spec[i].field_name; i++) for (i=0; NULL != spec[i].field_name; i++)
{ {
if (0 == spec[i].destination_size_in) if (0 == spec[i].destination_size_in)
{
ptr = NULL;
parse_variable_json_data (connection, root, parse_variable_json_data (connection, root,
spec[i].field_name, spec[i].field_name,
(void **) spec[i].destination, &ptr,
&spec[i].destination_size_out, &spec[i].destination_size_out,
&ret); &ret);
spec[i].destination = ptr;
}
else else
{
parse_fixed_json_data (connection, root, parse_fixed_json_data (connection, root,
spec[i].field_name, spec[i].field_name,
spec[i].destination, spec[i].destination,
spec[i].destination_size_in, spec[i].destination_size_in,
&ret); &ret);
}
} }
if (GNUNET_YES != ret) if (GNUNET_YES != ret)
TALER_MINT_release_parsed_data (spec); TALER_MINT_release_parsed_data (spec);
@ -641,4 +648,63 @@ TALER_MINT_mhd_request_arg_data (struct MHD_Connection *connection,
return GNUNET_OK; return GNUNET_OK;
} }
/**
* Extraxt variable-size base32crockford encoded data from request.
*
* Queues an error response to the connection if the parameter is missing
* or the encoding is invalid.
*
* @param connection the MHD connection
* @param param_name the name of the parameter with the key
* @param[out] out_data pointer to allocate buffer and store the result
* @param[out] out_size set to the size of the buffer allocated in @a out_data
* @return
* #GNUNET_YES if the the argument is present
* #GNUNET_NO if the argument is absent or malformed
* #GNUNET_SYSERR on internal error (error response could not be sent)
*/
int
TALER_MINT_mhd_request_var_arg_data (struct MHD_Connection *connection,
const char *param_name,
void **out_data,
size_t *out_size)
{
const char *str;
size_t slen;
size_t olen;
void *out;
str = MHD_lookup_connection_value (connection,
MHD_GET_ARGUMENT_KIND,
param_name);
if (NULL == str)
{
return (MHD_NO ==
TALER_MINT_reply_arg_missing (connection, param_name))
? GNUNET_SYSERR : GNUNET_NO;
}
slen = strlen (str);
olen = (slen * 5) / 8;
out = GNUNET_malloc (olen);
if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (str,
strlen (str),
out,
olen))
{
GNUNET_free (out);
*out_size = 0;
return (MHD_NO ==
TALER_MINT_reply_arg_invalid (connection, param_name))
? GNUNET_SYSERR : GNUNET_NO;
}
*out_data = out;
*out_size = olen;
return GNUNET_OK;
}
/* end of taler-mint-httpd_parsing.c */ /* end of taler-mint-httpd_parsing.c */

View File

@ -209,9 +209,8 @@ TALER_MINT_release_parsed_data (struct GNUNET_MINT_ParseFieldSpec *spec);
* Generate line in parser specification for variable-size value. * Generate line in parser specification for variable-size value.
* *
* @param field name of the field * @param field name of the field
* @param value where to store the value
*/ */
#define TALER_MINT_PARSE_VARIABLE(field,value) { field, &value, 0, 0 } #define TALER_MINT_PARSE_VARIABLE(field) { field, NULL, 0, 0 }
/** /**
* Generate line in parser specification indicating the end of the spec. * Generate line in parser specification indicating the end of the spec.
@ -220,7 +219,7 @@ TALER_MINT_release_parsed_data (struct GNUNET_MINT_ParseFieldSpec *spec);
/** /**
* Extraxt base32crockford encoded data from request. * Extraxt fixed-size base32crockford encoded data from request.
* *
* Queues an error response to the connection if the parameter is missing or * Queues an error response to the connection if the parameter is missing or
* invalid. * invalid.
@ -241,6 +240,28 @@ TALER_MINT_mhd_request_arg_data (struct MHD_Connection *connection,
size_t out_size); size_t out_size);
/**
* Extraxt variable-size base32crockford encoded data from request.
*
* Queues an error response to the connection if the parameter is missing
* or the encoding is invalid.
*
* @param connection the MHD connection
* @param param_name the name of the parameter with the key
* @param[out] out_data pointer to allocate buffer and store the result
* @param[out] out_size set to the size of the buffer allocated in @a out_data
* @return
* #GNUNET_YES if the the argument is present
* #GNUNET_NO if the argument is absent or malformed
* #GNUNET_SYSERR on internal error (error response could not be sent)
*/
int
TALER_MINT_mhd_request_var_arg_data (struct MHD_Connection *connection,
const char *param_name,
void **out_data,
size_t *out_size);
#endif /* TALER_MICROHTTPD_LIB_H_ */ #endif /* TALER_MICROHTTPD_LIB_H_ */

View File

@ -34,7 +34,6 @@
#include "mint.h" #include "mint.h"
#include "mint_db.h" #include "mint_db.h"
#include "taler_signatures.h" #include "taler_signatures.h"
#include "taler_rsa.h"
#include "taler_json_lib.h" #include "taler_json_lib.h"
#include "taler-mint-httpd_parsing.h" #include "taler-mint-httpd_parsing.h"
#include "taler-mint-httpd_keys.h" #include "taler-mint-httpd_keys.h"
@ -94,7 +93,7 @@ check_confirm_signature (struct MHD_Connection *connection,
* @param connection the connection to send error responses to * @param connection the connection to send error responses to
* @param root the JSON object to extract the coin info from * @param root the JSON object to extract the coin info from
* @return #GNUNET_YES if coin public info in JSON was valid * @return #GNUNET_YES if coin public info in JSON was valid
* #GNUNET_NO otherwise * #GNUNET_NO JSON was invalid, response was generated
* #GNUNET_SYSERR on internal error * #GNUNET_SYSERR on internal error
*/ */
static int static int
@ -103,33 +102,38 @@ request_json_require_coin_public_info (struct MHD_Connection *connection,
struct TALER_CoinPublicInfo *r_public_info) struct TALER_CoinPublicInfo *r_public_info)
{ {
int ret; int ret;
struct GNUNET_CRYPTO_rsa_Signature *sig;
struct GNUNET_CRYPTO_rsa_PublicKey *pk;
struct GNUNET_MINT_ParseFieldSpec spec[] =
{
TALER_MINT_PARSE_FIXED("coin_pub", &r_public_info->coin_pub),
TALER_MINT_PARSE_VARIABLE("denom_sig"),
TALER_MINT_PARSE_VARIABLE("denom_pub"),
TALER_MINT_PARSE_END
};
GNUNET_assert (NULL != root); ret = TALER_MINT_parse_json_data (connection,
root,
ret = GNUNET_MINT_parse_navigate_json (connection, root, spec);
JNAV_FIELD, "coin_pub",
JNAV_RET_DATA,
&r_public_info->coin_pub,
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
if (GNUNET_OK != ret) if (GNUNET_OK != ret)
return ret; return ret;
sig = GNUNET_CRYPTO_rsa_signature_decode (spec[1].destination,
ret = GNUNET_MINT_parse_navigate_json (connection, root, spec[1].destination_size_out);
JNAV_FIELD, "denom_sig", pk = GNUNET_CRYPTO_rsa_public_key_decode (spec[2].destination,
JNAV_RET_DATA, spec[2].destination_size_out);
&r_public_info->denom_sig, TALER_MINT_release_parsed_data (spec);
sizeof (struct TALER_RSA_Signature)); if ( (NULL == pk) ||
if (GNUNET_OK != ret) (NULL == sig) )
return ret; {
if (NULL != sig)
ret = GNUNET_MINT_parse_navigate_json (connection, root, GNUNET_CRYPTO_rsa_signature_free (sig);
JNAV_FIELD, "denom_pub", if (NULL != pk)
JNAV_RET_DATA, GNUNET_CRYPTO_rsa_public_key_free (pk);
&r_public_info->denom_pub, // FIXME: send error reply...
sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)); return GNUNET_NO;
if (GNUNET_OK != ret) }
return ret; r_public_info->denom_sig = sig;
r_public_info->denom_pub = pk;
return GNUNET_OK; return GNUNET_OK;
} }
@ -247,7 +251,7 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
json_t *new_denoms; json_t *new_denoms;
unsigned int num_new_denoms; unsigned int num_new_denoms;
unsigned int i; unsigned int i;
struct TALER_RSA_PublicKeyBinaryEncoded *denom_pubs; struct GNUNET_CRYPTO_rsa_PublicKey *denom_pubs;
json_t *melt_coins; json_t *melt_coins;
struct TALER_CoinPublicInfo *coin_public_infos; struct TALER_CoinPublicInfo *coin_public_infos;
unsigned int coin_count; unsigned int coin_count;
@ -256,6 +260,8 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
struct MintKeyState *key_state; struct MintKeyState *key_state;
struct RefreshMeltSignatureBody body; struct RefreshMeltSignatureBody body;
json_t *melt_sig_json; json_t *melt_sig_json;
char *buf;
size_t buf_size;
res = TALER_MINT_parse_post_json (connection, res = TALER_MINT_parse_post_json (connection,
connection_cls, connection_cls,
@ -291,23 +297,31 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
return res; return res;
num_new_denoms = json_array_size (new_denoms); num_new_denoms = json_array_size (new_denoms);
denom_pubs = GNUNET_malloc (num_new_denoms * denom_pubs = GNUNET_malloc (num_new_denoms *
sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)); sizeof (struct GNUNET_CRYPTO_rsa_PublicKey *));
for (i=0;i<num_new_denoms;i++) for (i=0;i<num_new_denoms;i++)
{ {
res = GNUNET_MINT_parse_navigate_json (connection, root, res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "new_denoms", JNAV_FIELD, "new_denoms",
JNAV_INDEX, (int) i, JNAV_INDEX, (int) i,
JNAV_RET_DATA, JNAV_RET_DATA_VAR,
&denom_pubs[i], &buf,
sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)); &buf_size);
if (GNUNET_OK != res) if (GNUNET_OK != res)
{ {
GNUNET_free (denom_pubs); GNUNET_free (denom_pubs);
/* FIXME: proper cleanup! */ /* FIXME: proper cleanup! */
return res; return res;
} }
denom_pubs[i] = GNUNET_CRYPTO_rsa_public_key_decode (buf, buf_size);
GNUNET_free (buf);
if (NULL == denom_pubs[i])
{
GNUNET_free (denom_pubs);
/* FIXME: proper cleanup! */
/* FIXME: generate error reply */
return GNUNET_SYSERR;
}
} }
res = GNUNET_MINT_parse_navigate_json (connection, root, res = GNUNET_MINT_parse_navigate_json (connection, root,
@ -377,9 +391,14 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
/* check that signature from the session public key is ok */ /* check that signature from the session public key is ok */
hash_context = GNUNET_CRYPTO_hash_context_start (); hash_context = GNUNET_CRYPTO_hash_context_start ();
for (i = 0; i < num_new_denoms; i++) for (i = 0; i < num_new_denoms; i++)
{
buf_size = GNUNET_CRYPTO_rsa_public_key_encode (denom_pubs[i],
&buf);
GNUNET_CRYPTO_hash_context_read (hash_context, GNUNET_CRYPTO_hash_context_read (hash_context,
&denom_pubs[i], buf,
sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)); buf_size);
GNUNET_free (buf);
}
for (i = 0; i < coin_count; i++) for (i = 0; i < coin_count; i++)
GNUNET_CRYPTO_hash_context_read (hash_context, GNUNET_CRYPTO_hash_context_read (hash_context,
&coin_public_infos[i].coin_pub, &coin_public_infos[i].coin_pub,
@ -526,9 +545,9 @@ TALER_MINT_handler_refresh_commit (struct RequestHandler *rh,
JNAV_FIELD, "coin_evs", JNAV_FIELD, "coin_evs",
JNAV_INDEX, (int) i, JNAV_INDEX, (int) i,
JNAV_INDEX, (int) j, JNAV_INDEX, (int) j,
JNAV_RET_DATA, JNAV_RET_DATA_VAR,
commit_coin[i][j].coin_ev, &commit_coin[i][j].coin_ev,
sizeof (struct TALER_RSA_BlindedSignaturePurpose)); &commit_coin[i][j].coin_ev_size);
if (GNUNET_OK != res) if (GNUNET_OK != res)
{ {
@ -539,8 +558,8 @@ TALER_MINT_handler_refresh_commit (struct RequestHandler *rh,
} }
GNUNET_CRYPTO_hash_context_read (hash_context, GNUNET_CRYPTO_hash_context_read (hash_context,
&commit_coin[i][j].coin_ev, commit_coin[i][j].coin_ev,
sizeof (struct TALER_RSA_BlindedSignaturePurpose)); commit_coin[i][j].coin_ev_size);
res = GNUNET_MINT_parse_navigate_json (connection, root, res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "link_encs", JNAV_FIELD, "link_encs",

View File

@ -295,10 +295,15 @@ TALER_MINT_reply_withdraw_sign_success (struct MHD_Connection *connection,
const struct CollectableBlindcoin *collectable) const struct CollectableBlindcoin *collectable)
{ {
json_t *root = json_object (); json_t *root = json_object ();
size_t sig_buf_size;
char *sig_buf;
sig_buf_size = GNUNET_CRYPTO_rsa_signature_encode (collectable->sig,
&sig_buf);
json_object_set_new (root, "ev_sig", json_object_set_new (root, "ev_sig",
TALER_JSON_from_data (&collectable->ev_sig, TALER_JSON_from_data (sig_buf,
sizeof (struct TALER_RSA_Signature))); sig_buf_size));
GNUNET_free (sig_buf);
return TALER_MINT_reply_json (connection, return TALER_MINT_reply_json (connection,
root, root,
MHD_HTTP_OK); MHD_HTTP_OK);
@ -388,19 +393,26 @@ TALER_MINT_reply_refresh_commit_success (struct MHD_Connection *connection,
int int
TALER_MINT_reply_refresh_reveal_success (struct MHD_Connection *connection, TALER_MINT_reply_refresh_reveal_success (struct MHD_Connection *connection,
unsigned int num_newcoins, unsigned int num_newcoins,
const struct TALER_RSA_Signature *sigs) const struct GNUNET_CRYPTO_rsa_Signature *sigs)
{ {
int newcoin_index; int newcoin_index;
json_t *root; json_t *root;
json_t *list; json_t *list;
char *buf;
size_t buf_size;
root = json_object (); root = json_object ();
list = json_array (); list = json_array ();
json_object_set_new (root, "ev_sigs", list); json_object_set_new (root, "ev_sigs", list);
for (newcoin_index = 0; newcoin_index < num_newcoins; newcoin_index++) for (newcoin_index = 0; newcoin_index < num_newcoins; newcoin_index++)
{
buf_size = GNUNET_CRYPTO_rsa_signature_encode (&sigs[newcoin_index],
&buf);
json_array_append_new (list, json_array_append_new (list,
TALER_JSON_from_data (&sigs[newcoin_index], TALER_JSON_from_data (buf,
sizeof (struct TALER_RSA_Signature))); buf_size));
GNUNET_free (buf);
}
return TALER_MINT_reply_json (connection, return TALER_MINT_reply_json (connection,
root, root,
MHD_HTTP_OK); MHD_HTTP_OK);

View File

@ -209,7 +209,7 @@ TALER_MINT_reply_refresh_melt_success (struct MHD_Connection *connection,
int int
TALER_MINT_reply_refresh_reveal_success (struct MHD_Connection *connection, TALER_MINT_reply_refresh_reveal_success (struct MHD_Connection *connection,
unsigned int num_newcoins, unsigned int num_newcoins,
const struct TALER_RSA_Signature *sigs); const struct GNUNET_CRYPTO_rsa_Signature *sigs);

View File

@ -32,7 +32,6 @@
#include "mint.h" #include "mint.h"
#include "mint_db.h" #include "mint_db.h"
#include "taler_signatures.h" #include "taler_signatures.h"
#include "taler_rsa.h"
#include "taler_json_lib.h" #include "taler_json_lib.h"
#include "taler-mint-httpd_parsing.h" #include "taler-mint-httpd_parsing.h"
#include "taler-mint-httpd_keys.h" #include "taler-mint-httpd_keys.h"
@ -94,6 +93,12 @@ TALER_MINT_handler_withdraw_sign (struct RequestHandler *rh,
{ {
struct TALER_WithdrawRequest wsrd; struct TALER_WithdrawRequest wsrd;
int res; int res;
const struct GNUNET_CRYPTO_rsa_PublicKey *denomination_pub;
char *denomination_pub_data;
size_t denomination_pub_data_size;
char *blinded_msg;
size_t blinded_msg_len;
const struct GNUNET_CRYPTO_EddsaSignature signature;
res = TALER_MINT_mhd_request_arg_data (connection, res = TALER_MINT_mhd_request_arg_data (connection,
"reserve_pub", "reserve_pub",
@ -105,33 +110,66 @@ TALER_MINT_handler_withdraw_sign (struct RequestHandler *rh,
return MHD_YES; /* invalid request */ return MHD_YES; /* invalid request */
/* FIXME: handle variable-size signing keys! */ /* FIXME: handle variable-size signing keys! */
res = TALER_MINT_mhd_request_arg_data (connection, res = TALER_MINT_mhd_request_var_arg_data (connection,
"denom_pub", "denom_pub",
&wsrd.denomination_pub, &denomination_pub_data,
sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)); &denomination_pub_data_size);
if (GNUNET_SYSERR == res) if (GNUNET_SYSERR == res)
return MHD_NO; /* internal error */ return MHD_NO; /* internal error */
if (GNUNET_NO == res) if (GNUNET_NO == res)
return MHD_YES; /* invalid request */ return MHD_YES; /* invalid request */
res = TALER_MINT_mhd_request_arg_data (connection, res = TALER_MINT_mhd_request_var_arg_data (connection,
"coin_ev", "coin_ev",
&wsrd.coin_envelope, &blinded_msg,
sizeof (struct TALER_RSA_Signature)); &blinded_msg_len);
if (GNUNET_SYSERR == res) if (GNUNET_SYSERR == res)
return MHD_NO; /* internal error */ return MHD_NO; /* internal error */
if (GNUNET_NO == res) if (GNUNET_NO == res)
return MHD_YES; /* invalid request */ return MHD_YES; /* invalid request */
res = TALER_MINT_mhd_request_arg_data (connection, res = TALER_MINT_mhd_request_arg_data (connection,
"reserve_sig", "reserve_sig",
&wsrd.sig, &signature,
sizeof (struct GNUNET_CRYPTO_EddsaSignature)); sizeof (struct GNUNET_CRYPTO_EddsaSignature));
if (GNUNET_SYSERR == res) if (GNUNET_SYSERR == res)
return MHD_NO; /* internal error */ return MHD_NO; /* internal error */
if (GNUNET_NO == res) if (GNUNET_NO == res)
return MHD_YES; /* invalid request */ return MHD_YES; /* invalid request */
return TALER_MINT_db_execute_withdraw_sign (connection, /* verify signature! */
&wsrd); wsrd.purpose.size = htonl (sizeof (struct TALER_WithdrawRequest));
wsrd.purpose.type = htonl (TALER_SIGNATURE_WITHDRAW);
GNUNET_CRYPTO_hash (denomination_pub_data,
denomination_pub_data_size,
&wsrd.h_denomination_pub);
GNUNET_CRYPTO_hash (blinded_msg,
blinded_msg_len,
&wsrd.h_coin_envelope);
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WITHDRAW,
&wsrd.purpose,
&signature,
&wsrd.reserve_pub))
{
return 42; // FIXME: generate error reply
}
denomination_pub = GNUNET_CRYPTO_rsa_private_key_decode (denomination_pub_data,
denomination_pub_data_size);
if (NULL == denomination_pub)
{
GNUNET_free (denomination_pub_data);
GNUNET_free (blinded_msg);
return 42; // FIXME: generate error reply
}
res = TALER_MINT_db_execute_withdraw_sign (connection,
&wsrd.reserve_pub,
denomination_pub,
blinded_msg,
blinded_msg_len,
&signature);
GNUNET_free (denomination_pub_data);
GNUNET_free (blinded_msg);
GNUNET_CRYPTO_rsa_public_key_free (denomination_pub);
return res;
} }
/* end of taler-mint-httpd_withdraw.c */ /* end of taler-mint-httpd_withdraw.c */

View File

@ -105,7 +105,7 @@ static struct GNUNET_CRYPTO_EddsaPublicKey *master_pub;
static struct GNUNET_TIME_Absolute lookahead_sign_stamp; static struct GNUNET_TIME_Absolute lookahead_sign_stamp;
int static int
config_get_denom (const char *section, const char *option, struct TALER_Amount *denom) config_get_denom (const char *section, const char *option, struct TALER_Amount *denom)
{ {
char *str; char *str;
@ -117,7 +117,7 @@ config_get_denom (const char *section, const char *option, struct TALER_Amount *
} }
char * static char *
get_signkey_dir () get_signkey_dir ()
{ {
char *dir; char *dir;
@ -128,7 +128,7 @@ get_signkey_dir ()
} }
char * static char *
get_signkey_file (struct GNUNET_TIME_Absolute start) get_signkey_file (struct GNUNET_TIME_Absolute start)
{ {
char *dir; char *dir;
@ -140,13 +140,12 @@ get_signkey_file (struct GNUNET_TIME_Absolute start)
} }
/** /**
* Hash the data defining the coin type. * Hash the data defining the coin type.
* Exclude information that may not be the same for all * Exclude information that may not be the same for all
* instances of the coin type (i.e. the anchor, overlap). * instances of the coin type (i.e. the anchor, overlap).
*/ */
void static void
hash_coin_type (const struct CoinTypeParams *p, struct GNUNET_HashCode *hash) hash_coin_type (const struct CoinTypeParams *p, struct GNUNET_HashCode *hash)
{ {
struct CoinTypeNBO p_nbo; struct CoinTypeNBO p_nbo;
@ -254,7 +253,7 @@ get_anchor_iter (void *cls,
* @param overlap what's the overlap between the keys validity period? * @param overlap what's the overlap between the keys validity period?
* @param[out] anchor the timestamp where the first new key should be generated * @param[out] anchor the timestamp where the first new key should be generated
*/ */
void static void
get_anchor (const char *dir, get_anchor (const char *dir,
struct GNUNET_TIME_Relative duration, struct GNUNET_TIME_Relative duration,
struct GNUNET_TIME_Relative overlap, struct GNUNET_TIME_Relative overlap,
@ -291,6 +290,7 @@ get_anchor (const char *dir,
// anchor is now the stamp where we need to create a new key // anchor is now the stamp where we need to create a new key
} }
static void static void
create_signkey_issue_priv (struct GNUNET_TIME_Absolute start, create_signkey_issue_priv (struct GNUNET_TIME_Absolute start,
struct GNUNET_TIME_Relative duration, struct GNUNET_TIME_Relative duration,
@ -327,7 +327,7 @@ check_signkey_valid (const char *signkey_filename)
} }
int static int
mint_keys_update_signkeys () mint_keys_update_signkeys ()
{ {
struct GNUNET_TIME_Relative signkey_duration; struct GNUNET_TIME_Relative signkey_duration;
@ -377,7 +377,7 @@ mint_keys_update_signkeys ()
} }
int static int
get_cointype_params (const char *ct, struct CoinTypeParams *params) get_cointype_params (const char *ct, struct CoinTypeParams *params)
{ {
const char *dir; const char *dir;
@ -434,8 +434,8 @@ static void
create_denomkey_issue (struct CoinTypeParams *params, create_denomkey_issue (struct CoinTypeParams *params,
struct TALER_MINT_DenomKeyIssuePriv *dki) struct TALER_MINT_DenomKeyIssuePriv *dki)
{ {
GNUNET_assert (NULL != (dki->denom_priv = TALER_RSA_key_create ())); GNUNET_assert (NULL != (dki->denom_priv = GNUNET_CRYPTO_rsa_private_key_create ()));
TALER_RSA_key_get_public (dki->denom_priv, &dki->issue.denom_pub); dki->issue.denom_pub = GNUNET_CRYPTO_rsa_private_key_get_get_public (dki->denom_priv);
dki->issue.master = *master_pub; dki->issue.master = *master_pub;
dki->issue.start = GNUNET_TIME_absolute_hton (params->anchor); dki->issue.start = GNUNET_TIME_absolute_hton (params->anchor);
dki->issue.expire_withdraw = dki->issue.expire_withdraw =
@ -470,7 +470,7 @@ check_cointype_valid (const char *filename, struct CoinTypeParams *params)
} }
int static int
mint_keys_update_cointype (const char *coin_alias) mint_keys_update_cointype (const char *coin_alias)
{ {
struct CoinTypeParams p; struct CoinTypeParams p;
@ -496,7 +496,7 @@ mint_keys_update_cointype (const char *coin_alias)
printf ("Target path: %s\n", dkf); printf ("Target path: %s\n", dkf);
create_denomkey_issue (&p, &denomkey_issue); create_denomkey_issue (&p, &denomkey_issue);
ret = TALER_MINT_write_denom_key (dkf, &denomkey_issue); ret = TALER_MINT_write_denom_key (dkf, &denomkey_issue);
TALER_RSA_key_free (denomkey_issue.denom_priv); GNUNET_CRYPTO_rsa_private_key_free (denomkey_issue.denom_priv);
if (GNUNET_OK != ret) if (GNUNET_OK != ret)
{ {
fprintf (stderr, "Can't write to file '%s'\n", dkf); fprintf (stderr, "Can't write to file '%s'\n", dkf);
@ -514,7 +514,7 @@ mint_keys_update_cointype (const char *coin_alias)
} }
int static int
mint_keys_update_denomkeys () mint_keys_update_denomkeys ()
{ {
char *coin_types; char *coin_types;
@ -659,4 +659,3 @@ main (int argc, char *const *argv)
return 1; return 1;
return 0; return 0;
} }

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_rsa.h"
#include "mint.h" #include "mint.h"
#define EXITIF(cond) \ #define EXITIF(cond) \
@ -34,9 +33,11 @@ int
main (int argc, const char *const argv[]) main (int argc, const char *const argv[])
{ {
struct TALER_MINT_DenomKeyIssuePriv dki; struct TALER_MINT_DenomKeyIssuePriv dki;
struct TALER_RSA_PrivateKeyBinaryEncoded *enc; char *enc;
size_t enc_size;
struct TALER_MINT_DenomKeyIssuePriv dki_read; struct TALER_MINT_DenomKeyIssuePriv dki_read;
struct TALER_RSA_PrivateKeyBinaryEncoded *enc_read; char *enc_read;
size_t enc_read_size;
char *tmpfile; char *tmpfile;
int ret; int ret;
@ -51,20 +52,17 @@ main (int argc, const char *const argv[])
&dki.issue.signature, &dki.issue.signature,
sizeof (dki) - offsetof (struct TALER_MINT_DenomKeyIssue, sizeof (dki) - offsetof (struct TALER_MINT_DenomKeyIssue,
signature)); signature));
dki.denom_priv = TALER_RSA_key_create (); dki.denom_priv = GNUNET_CRYPTO_rsa_private_key_create ();
EXITIF (NULL == (enc = TALER_RSA_encode_key (dki.denom_priv))); enc_size = GNUNET_CRYPTO_rsa_private_key_encode (dki.denom_priv, &enc);
EXITIF (NULL == (tmpfile = GNUNET_DISK_mktemp ("test_mint_common"))); EXITIF (NULL == (tmpfile = GNUNET_DISK_mktemp ("test_mint_common")));
EXITIF (GNUNET_OK != TALER_MINT_write_denom_key (tmpfile, &dki)); EXITIF (GNUNET_OK != TALER_MINT_write_denom_key (tmpfile, &dki));
EXITIF (GNUNET_OK != TALER_MINT_read_denom_key (tmpfile, &dki_read)); EXITIF (GNUNET_OK != TALER_MINT_read_denom_key (tmpfile, &dki_read));
EXITIF (NULL == (enc_read = TALER_RSA_encode_key (dki_read.denom_priv))); enc_read_size = GNUNET_CRYPTO_rsa_privae_key_encode (dki_read.denom_priv,
EXITIF (enc->len != enc_read->len); &enc_read);
EXITIF (enc_size != enc_read_size);
EXITIF (0 != memcmp (enc, EXITIF (0 != memcmp (enc,
enc_read, enc_read,
ntohs(enc->len))); enc_size));
EXITIF (0 != memcmp (&dki.issue.signature,
&dki_read.issue.signature,
sizeof (dki) - offsetof (struct TALER_MINT_DenomKeyIssue,
signature)));
ret = 0; ret = 0;
EXITIF_exit: EXITIF_exit:
@ -76,8 +74,8 @@ main (int argc, const char *const argv[])
} }
GNUNET_free_non_null (enc_read); GNUNET_free_non_null (enc_read);
if (NULL != dki.denom_priv) if (NULL != dki.denom_priv)
TALER_RSA_key_free (dki.denom_priv); GNUNET_CRYPTO_rsa_private_key_free (dki.denom_priv);
if (NULL != dki_read.denom_priv) if (NULL != dki_read.denom_priv)
TALER_RSA_key_free (dki_read.denom_priv); GNUNET_CRYPOT_rsa_private_key_free (dki_read.denom_priv);
return ret; return ret;
} }

View File

@ -6,8 +6,7 @@ lib_LTLIBRARIES = \
libtalerutil_la_SOURCES = \ libtalerutil_la_SOURCES = \
util.c \ util.c \
json.c \ json.c \
db.c \ db.c
rsa.c
libtalerutil_la_LIBADD = \ libtalerutil_la_LIBADD = \
-lgnunetutil \ -lgnunetutil \

View File

@ -1,928 +0,0 @@
/* NOTE: this is obsolete logic, we should migrate to the
GNUNET_CRYPTO_rsa-API as soon as possible */
/*
This file is part of TALER
(C) 2014 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 util/rsa.c
* @brief RSA key management utilities. Most of the code here is taken from
* gnunet-0.9.5a
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
*
* Authors of the gnunet code:
* Christian Grothoff
* Krista Bennett
* Gerd Knorr <kraxel@bytesex.org>
* Ioana Patrascu
* Tzvetan Horozov
*/
#include "platform.h"
#include "gcrypt.h"
#include "gnunet/gnunet_util_lib.h"
#include "taler_rsa.h"
#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
/**
* Log an error message at log-level 'level' that indicates
* a failure of the command 'cmd' with the message given
* by gcry_strerror(rc).
*/
#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0)
/**
* Shorthand to cleanup non null mpi data types
*/
#define mpi_release_non_null(mpi) \
if (NULL != mpi) gcry_mpi_release (mpi);
/**
* The private information of an RSA key pair.
* NOTE: this must match the definition in crypto_ksk.c and gnunet-rsa.c!
*/
struct TALER_RSA_PrivateKey
{
/**
* Libgcrypt S-expression for the ECC key.
*/
gcry_sexp_t sexp;
};
/**
* Extract values from an S-expression.
*
* @param array where to store the result(s)
* @param sexp S-expression to parse
* @param topname top-level name in the S-expression that is of interest
* @param elems names of the elements to extract
* @return 0 on success
*/
static int
key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname,
const char *elems)
{
gcry_sexp_t list;
gcry_sexp_t l2;
const char *s;
unsigned int i;
unsigned int idx;
if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
return 1;
l2 = gcry_sexp_cadr (list);
gcry_sexp_release (list);
list = l2;
if (! list)
return 2;
idx = 0;
for (s = elems; *s; s++, idx++)
{
if (! (l2 = gcry_sexp_find_token (list, s, 1)))
{
for (i = 0; i < idx; i++)
{
gcry_free (array[i]);
array[i] = NULL;
}
gcry_sexp_release (list);
return 3; /* required parameter not found */
}
array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
gcry_sexp_release (l2);
if (! array[idx])
{
for (i = 0; i < idx; i++)
{
gcry_free (array[i]);
array[i] = NULL;
}
gcry_sexp_release (list);
return 4; /* required parameter is invalid */
}
}
gcry_sexp_release (list);
return 0;
}
/**
* If target != size, move target bytes to the
* end of the size-sized buffer and zero out the
* first target-size bytes.
*
* @param buf original buffer
* @param size number of bytes in the buffer
* @param target target size of the buffer
*/
static void
adjust (unsigned char *buf, size_t size, size_t target)
{
if (size < target)
{
memmove (&buf[target - size], buf, size);
memset (buf, 0, target - size);
}
}
/**
* Create a new private key. Caller must free return value.
*
* @return fresh private key
*/
struct TALER_RSA_PrivateKey *
TALER_RSA_key_create ()
{
struct TALER_RSA_PrivateKey *ret;
gcry_sexp_t s_key;
gcry_sexp_t s_keyparam;
GNUNET_assert (0 ==
gcry_sexp_build (&s_keyparam, NULL,
"(genkey(rsa(nbits %d)(rsa-use-e 3:257)))",
2048));
GNUNET_assert (0 == gcry_pk_genkey (&s_key, s_keyparam));
gcry_sexp_release (s_keyparam);
#if EXTRA_CHECKS
GNUNET_assert (0 == gcry_pk_testkey (s_key));
#endif
ret = GNUNET_malloc (sizeof (struct TALER_RSA_PrivateKey));
ret->sexp = s_key;
return ret;
}
/**
* Free memory occupied by the private key.
*
* @param key pointer to the memory to free
*/
void
TALER_RSA_key_free (struct TALER_RSA_PrivateKey *key)
{
gcry_sexp_release (key->sexp);
GNUNET_free (key);
}
/**
* Encode the private key in a format suitable for
* storing it into a file.
* @return encoding of the private key
*/
struct TALER_RSA_PrivateKeyBinaryEncoded *
TALER_RSA_encode_key (const struct TALER_RSA_PrivateKey *hostkey)
{
struct TALER_RSA_PrivateKeyBinaryEncoded *retval;
gcry_mpi_t pkv[6];
void *pbu[6];
size_t sizes[6];
int rc;
int i;
int size;
#if EXTRA_CHECKS
if (gcry_pk_testkey (hostkey->sexp))
{
GNUNET_break (0);
return NULL;
}
#endif
memset (pkv, 0, sizeof (gcry_mpi_t) * 6);
rc = key_from_sexp (pkv, hostkey->sexp, "private-key", "nedpqu");
if (rc)
rc = key_from_sexp (pkv, hostkey->sexp, "rsa", "nedpqu");
if (rc)
rc = key_from_sexp (pkv, hostkey->sexp, "private-key", "nedpq");
if (rc)
rc = key_from_sexp (pkv, hostkey->sexp, "rsa", "nedpq");
if (rc)
rc = key_from_sexp (pkv, hostkey->sexp, "private-key", "ned");
if (rc)
rc = key_from_sexp (pkv, hostkey->sexp, "rsa", "ned");
GNUNET_assert (0 == rc);
size = sizeof (struct TALER_RSA_PrivateKeyBinaryEncoded);
for (i = 0; i < 6; i++)
{
if (NULL != pkv[i])
{
GNUNET_assert (0 ==
gcry_mpi_aprint (GCRYMPI_FMT_USG,
(unsigned char **) &pbu[i], &sizes[i],
pkv[i]));
size += sizes[i];
}
else
{
pbu[i] = NULL;
sizes[i] = 0;
}
}
GNUNET_assert (size < 65536);
retval = GNUNET_malloc (size);
retval->len = htons (size);
i = 0;
retval->sizen = htons (sizes[0]);
memcpy (&((char *) (&retval[1]))[i], pbu[0], sizes[0]);
i += sizes[0];
retval->sizee = htons (sizes[1]);
memcpy (&((char *) (&retval[1]))[i], pbu[1], sizes[1]);
i += sizes[1];
retval->sized = htons (sizes[2]);
memcpy (&((char *) (&retval[1]))[i], pbu[2], sizes[2]);
i += sizes[2];
/* swap p and q! */
retval->sizep = htons (sizes[4]);
memcpy (&((char *) (&retval[1]))[i], pbu[4], sizes[4]);
i += sizes[4];
retval->sizeq = htons (sizes[3]);
memcpy (&((char *) (&retval[1]))[i], pbu[3], sizes[3]);
i += sizes[3];
retval->sizedmp1 = htons (0);
retval->sizedmq1 = htons (0);
memcpy (&((char *) (&retval[1]))[i], pbu[5], sizes[5]);
for (i = 0; i < 6; i++)
{
if (pkv[i] != NULL)
gcry_mpi_release (pkv[i]);
if (pbu[i] != NULL)
free (pbu[i]);
}
return retval;
}
/**
* Extract the public key of the given private key.
*
* @param priv the private key
* @param pub where to write the public key
*/
void
TALER_RSA_key_get_public (const struct TALER_RSA_PrivateKey *priv,
struct TALER_RSA_PublicKeyBinaryEncoded *pub)
{
gcry_mpi_t skey[2];
size_t size;
int rc;
rc = key_from_sexp (skey, priv->sexp, "public-key", "ne");
if (0 != rc)
rc = key_from_sexp (skey, priv->sexp, "private-key", "ne");
if (0 != rc)
rc = key_from_sexp (skey, priv->sexp, "rsa", "ne");
GNUNET_assert (0 == rc);
pub->len =
htons (sizeof (struct TALER_RSA_PublicKeyBinaryEncoded) -
sizeof (pub->padding));
pub->sizen = htons (TALER_RSA_DATA_ENCODING_LENGTH);
pub->padding = 0;
size = TALER_RSA_DATA_ENCODING_LENGTH;
GNUNET_assert (0 ==
gcry_mpi_print (GCRYMPI_FMT_USG, &pub->key[0], size, &size,
skey[0]));
adjust (&pub->key[0], size, TALER_RSA_DATA_ENCODING_LENGTH);
size = TALER_RSA_KEY_LENGTH - TALER_RSA_DATA_ENCODING_LENGTH;
GNUNET_assert (0 ==
gcry_mpi_print (GCRYMPI_FMT_USG,
&pub->key
[TALER_RSA_DATA_ENCODING_LENGTH], size,
&size, skey[1]));
adjust (&pub->key[TALER_RSA_DATA_ENCODING_LENGTH], size,
TALER_RSA_KEY_LENGTH -
TALER_RSA_DATA_ENCODING_LENGTH);
gcry_mpi_release (skey[0]);
gcry_mpi_release (skey[1]);
}
/**
* Decode the private key from the data-format back
* to the "normal", internal format.
*
* @param buf the buffer where the private key data is stored
* @param len the length of the data in 'buffer'
* @return NULL on error
*/
struct TALER_RSA_PrivateKey *
TALER_RSA_decode_key (const char *buf, uint16_t len)
{
struct TALER_RSA_PrivateKey *ret;
const struct TALER_RSA_PrivateKeyBinaryEncoded *encoding =
(const struct TALER_RSA_PrivateKeyBinaryEncoded *) buf;
gcry_sexp_t res;
gcry_mpi_t n;
gcry_mpi_t e;
gcry_mpi_t d;
gcry_mpi_t p;
gcry_mpi_t q;
gcry_mpi_t u;
int rc;
size_t size;
size_t pos;
uint16_t enc_len;
size_t erroff;
enc_len = ntohs (encoding->len);
if (len != enc_len)
return NULL;
pos = 0;
size = ntohs (encoding->sizen);
rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG,
&((const unsigned char *) (&encoding[1]))[pos], size,
&size);
pos += ntohs (encoding->sizen);
if (0 != rc)
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
return NULL;
}
size = ntohs (encoding->sizee);
rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG,
&((const unsigned char *) (&encoding[1]))[pos], size,
&size);
pos += ntohs (encoding->sizee);
if (0 != rc)
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
gcry_mpi_release (n);
return NULL;
}
size = ntohs (encoding->sized);
rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG,
&((const unsigned char *) (&encoding[1]))[pos], size,
&size);
pos += ntohs (encoding->sized);
if (0 != rc)
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
gcry_mpi_release (n);
gcry_mpi_release (e);
return NULL;
}
/* swap p and q! */
size = ntohs (encoding->sizep);
if (size > 0)
{
rc = gcry_mpi_scan (&q, GCRYMPI_FMT_USG,
&((const unsigned char *) (&encoding[1]))[pos], size,
&size);
pos += ntohs (encoding->sizep);
if (0 != rc)
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
gcry_mpi_release (n);
gcry_mpi_release (e);
gcry_mpi_release (d);
return NULL;
}
}
else
q = NULL;
size = ntohs (encoding->sizeq);
if (size > 0)
{
rc = gcry_mpi_scan (&p, GCRYMPI_FMT_USG,
&((const unsigned char *) (&encoding[1]))[pos], size,
&size);
pos += ntohs (encoding->sizeq);
if (0 != rc)
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
gcry_mpi_release (n);
gcry_mpi_release (e);
gcry_mpi_release (d);
if (NULL != q)
gcry_mpi_release (q);
return NULL;
}
}
else
p = NULL;
pos += ntohs (encoding->sizedmp1);
pos += ntohs (encoding->sizedmq1);
size =
ntohs (encoding->len) - sizeof (struct TALER_RSA_PrivateKeyBinaryEncoded) - pos;
if (size > 0)
{
rc = gcry_mpi_scan (&u, GCRYMPI_FMT_USG,
&((const unsigned char *) (&encoding[1]))[pos], size,
&size);
if (0 != rc)
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
gcry_mpi_release (n);
gcry_mpi_release (e);
gcry_mpi_release (d);
if (NULL != p)
gcry_mpi_release (p);
if (NULL != q)
gcry_mpi_release (q);
return NULL;
}
}
else
u = NULL;
if ((NULL != p) && (NULL != q) && (NULL != u))
{
rc = gcry_sexp_build (&res, &erroff,
"(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
n, e, d, p, q, u);
}
else
{
if ((NULL != p) && (NULL != q))
{
rc = gcry_sexp_build (&res, &erroff,
"(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
n, e, d, p, q);
}
else
{
rc = gcry_sexp_build (&res, &erroff,
"(private-key(rsa(n %m)(e %m)(d %m)))", n, e, d);
}
}
gcry_mpi_release (n);
gcry_mpi_release (e);
gcry_mpi_release (d);
if (NULL != p)
gcry_mpi_release (p);
if (NULL != q)
gcry_mpi_release (q);
if (NULL != u)
gcry_mpi_release (u);
if (0 != rc)
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
if (0 != (rc = gcry_pk_testkey (res)))
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
return NULL;
}
ret = GNUNET_malloc (sizeof (struct TALER_RSA_PrivateKey));
ret->sexp = res;
return ret;
}
/**
* Convert a public key to a string.
*
* @param pub key to convert
* @return string representing 'pub'
*/
char *
TALER_RSA_public_key_to_string (const struct TALER_RSA_PublicKeyBinaryEncoded *pub)
{
char *pubkeybuf;
size_t keylen = (sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)) * 8;
char *end;
if (keylen % 5 > 0)
keylen += 5 - keylen % 5;
keylen /= 5;
pubkeybuf = GNUNET_malloc (keylen + 1);
end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
sizeof (struct TALER_RSA_PublicKeyBinaryEncoded),
pubkeybuf,
keylen);
if (NULL == end)
{
GNUNET_free (pubkeybuf);
return NULL;
}
*end = '\0';
return pubkeybuf;
}
/**
* Convert a string representing a public key to a public key.
*
* @param enc encoded public key
* @param enclen number of bytes in enc (without 0-terminator)
* @param pub where to store the public key
* @return GNUNET_OK on success
*/
int
TALER_RSA_public_key_from_string (const char *enc,
size_t enclen,
struct TALER_RSA_PublicKeyBinaryEncoded *pub)
{
size_t keylen = (sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)) * 8;
if (keylen % 5 > 0)
keylen += 5 - keylen % 5;
keylen /= 5;
if (enclen != keylen)
return GNUNET_SYSERR;
if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen,
(unsigned char*) pub,
sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)))
return GNUNET_SYSERR;
if ( (ntohs (pub->len) != sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)) ||
(ntohs (pub->padding) != 0) ||
(ntohs (pub->sizen) != TALER_RSA_DATA_ENCODING_LENGTH) )
return GNUNET_SYSERR;
return GNUNET_OK;
}
/**
* Convert the data specified in the given purpose argument to an
* S-expression suitable for signature operations.
*
* @param ptr pointer to the data to convert
* @param size the size of the data
* @return converted s-expression
*/
static gcry_sexp_t
data_to_sexp (const void *ptr, size_t size)
{
gcry_mpi_t value;
gcry_sexp_t data;
value = NULL;
data = NULL;
GNUNET_assert (0 == gcry_mpi_scan (&value, GCRYMPI_FMT_USG, ptr, size, NULL));
GNUNET_assert (0 == gcry_sexp_build (&data, NULL, "(data (flags raw) (value %M))", value));
gcry_mpi_release (value);
return data;
}
/**
* Sign the given hash block.
*
* @param key private key to use for the signing
* @param hash the block containing the hash of the message to sign
* @param hash_size the size of the hash block
* @param sig where to write the signature
* @return GNUNET_SYSERR on error, GNUNET_OK on success
*/
int
TALER_RSA_sign (const struct TALER_RSA_PrivateKey *key,
const void *hash,
size_t hash_size,
struct TALER_RSA_Signature *sig)
{
gcry_sexp_t result;
gcry_sexp_t data;
size_t ssize;
gcry_mpi_t rval;
data = data_to_sexp (hash, hash_size);
GNUNET_assert (0 == gcry_pk_sign (&result, data, key->sexp));
gcry_sexp_release (data);
GNUNET_assert (0 == key_from_sexp (&rval, result, "rsa", "s"));
gcry_sexp_release (result);
ssize = sizeof (struct TALER_RSA_Signature);
GNUNET_assert (0 ==
gcry_mpi_print (GCRYMPI_FMT_USG, (unsigned char *) sig, ssize,
&ssize, rval));
gcry_mpi_release (rval);
adjust (sig->sig, ssize, sizeof (struct TALER_RSA_Signature));
return GNUNET_OK;
}
/**
* Convert the given public key from the network format to the
* S-expression that can be used by libgcrypt.
*
* @param publicKey public key to decode
* @return NULL on error
*/
static gcry_sexp_t
decode_public_key (const struct TALER_RSA_PublicKeyBinaryEncoded *publicKey)
{
gcry_sexp_t result;
gcry_mpi_t n;
gcry_mpi_t e;
size_t size;
size_t erroff;
int rc;
if ((ntohs (publicKey->sizen) != TALER_RSA_DATA_ENCODING_LENGTH) ||
(ntohs (publicKey->len) !=
sizeof (struct TALER_RSA_PublicKeyBinaryEncoded) -
sizeof (publicKey->padding)))
{
GNUNET_break (0);
return NULL;
}
size = TALER_RSA_DATA_ENCODING_LENGTH;
if (0 != (rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG, &publicKey->key[0], size, &size)))
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
return NULL;
}
size = TALER_RSA_KEY_LENGTH - TALER_RSA_DATA_ENCODING_LENGTH;
if (0 != (rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG,
&publicKey->key[TALER_RSA_DATA_ENCODING_LENGTH],
size, &size)))
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
gcry_mpi_release (n);
return NULL;
}
rc = gcry_sexp_build (&result, &erroff, "(public-key(rsa(n %m)(e %m)))", n,
e);
gcry_mpi_release (n);
gcry_mpi_release (e);
if (0 != rc)
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); /* erroff gives more info */
return NULL;
}
return result;
}
/**
* Verify signature with the given hash.
*
* @param hash the hash code to verify against the signature
* @param sig signature that is being validated
* @param publicKey public key of the signer
* @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid
*/
int
TALER_RSA_hash_verify (const struct GNUNET_HashCode *hash,
const struct TALER_RSA_Signature *sig,
const struct TALER_RSA_PublicKeyBinaryEncoded *publicKey)
{
gcry_sexp_t data;
gcry_sexp_t sigdata;
size_t size;
gcry_mpi_t val;
gcry_sexp_t psexp;
size_t erroff;
int rc;
size = sizeof (struct TALER_RSA_Signature);
GNUNET_assert (0 ==
gcry_mpi_scan (&val, GCRYMPI_FMT_USG,
(const unsigned char *) sig, size, &size));
GNUNET_assert (0 ==
gcry_sexp_build (&sigdata, &erroff, "(sig-val(rsa(s %m)))",
val));
gcry_mpi_release (val);
data = data_to_sexp (hash, sizeof (struct GNUNET_HashCode));
if (! (psexp = decode_public_key (publicKey)))
{
gcry_sexp_release (data);
gcry_sexp_release (sigdata);
return GNUNET_SYSERR;
}
rc = gcry_pk_verify (sigdata, data, psexp);
gcry_sexp_release (psexp);
gcry_sexp_release (data);
gcry_sexp_release (sigdata);
if (rc)
{
LOG (GNUNET_ERROR_TYPE_WARNING,
_("RSA signature verification failed at %s:%d: %s\n"), __FILE__,
__LINE__, gcry_strerror (rc));
return GNUNET_SYSERR;
}
return GNUNET_OK;
}
/**
* Verify signature on the given message
*
* @param msg the message
* @param size the size of the message
* @param sig signature that is being validated
* @param publicKey public key of the signer
* @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid
*/
int
TALER_RSA_verify (const void *msg, size_t size,
const struct TALER_RSA_Signature *sig,
const struct TALER_RSA_PublicKeyBinaryEncoded *publicKey)
{
struct GNUNET_HashCode hash;
GNUNET_CRYPTO_hash (msg, size, &hash);
return TALER_RSA_hash_verify (&hash, sig, publicKey);
}
/**
* The blinding key is equal in length to the RSA modulus
*/
#define TALER_RSA_BLINDING_KEY_LEN TALER_RSA_DATA_ENCODING_LENGTH
struct TALER_RSA_BlindingKey
{
/**
* The blinding factor
*/
gcry_mpi_t r;
};
struct TALER_RSA_BlindingKey *
TALER_RSA_blinding_key_create ()
{
struct TALER_RSA_BlindingKey *blind;
blind = GNUNET_new (struct TALER_RSA_BlindingKey);
blind->r = gcry_mpi_new (TALER_RSA_BLINDING_KEY_LEN * 8);
gcry_mpi_randomize (blind->r, TALER_RSA_BLINDING_KEY_LEN * 8, GCRY_STRONG_RANDOM);
return blind;
}
void
TALER_RSA_blinding_key_destroy (struct TALER_RSA_BlindingKey *bkey)
{
gcry_mpi_release (bkey->r);
GNUNET_free (bkey);
}
struct TALER_RSA_BlindedSignaturePurpose *
TALER_RSA_message_blind (const void *msg, size_t size,
struct TALER_RSA_BlindingKey *bkey,
struct TALER_RSA_PublicKeyBinaryEncoded *pkey)
{
struct TALER_RSA_BlindedSignaturePurpose *bsp;
struct GNUNET_HashCode hash;
gcry_sexp_t psexp;
gcry_mpi_t data;
gcry_mpi_t skey[2];
gcry_mpi_t r_e;
gcry_mpi_t data_r_e;
size_t rsize;
gcry_error_t rc;
int ret;
bsp = NULL;
psexp = NULL;
data = NULL;
skey[0] = skey[1] = NULL;
r_e = NULL;
data_r_e = NULL;
rsize = 0;
rc = 0;
ret = 0;
if (! (psexp = decode_public_key (pkey)))
return NULL;
ret = key_from_sexp (skey, psexp, "public-key", "ne");
if (0 != ret)
ret = key_from_sexp (skey, psexp, "rsa", "ne");
gcry_sexp_release (psexp);
psexp = NULL;
GNUNET_assert (0 == ret);
GNUNET_CRYPTO_hash (msg, size, &hash);
if (0 != (rc=gcry_mpi_scan (&data, GCRYMPI_FMT_USG,
(const unsigned char *) msg, size, &rsize)))
{
LOG_GCRY (GNUNET_ERROR_TYPE_WARNING, "gcry_mpi_scan", rc);
goto cleanup;
}
r_e = gcry_mpi_new (0);
gcry_mpi_powm (r_e, bkey->r,
skey[1], /* e */
skey[0]); /* n */
data_r_e = gcry_mpi_new (0);
gcry_mpi_mulm (data_r_e, data, r_e, skey[0]);
bsp = GNUNET_new (struct TALER_RSA_BlindedSignaturePurpose);
rc = gcry_mpi_print (GCRYMPI_FMT_USG,
(unsigned char *) bsp,
sizeof (struct TALER_RSA_BlindedSignaturePurpose),
&rsize,
data_r_e);
GNUNET_assert (0 == rc);
adjust ((unsigned char *) bsp, rsize,
sizeof (struct TALER_RSA_BlindedSignaturePurpose));
cleanup:
if (NULL != psexp) gcry_sexp_release (psexp);
mpi_release_non_null (skey[0]);
mpi_release_non_null (skey[1]);
mpi_release_non_null (data);
mpi_release_non_null (r_e);
mpi_release_non_null (data_r_e);
return bsp;
}
int
TALER_RSA_unblind (struct TALER_RSA_Signature *sig,
struct TALER_RSA_BlindingKey *bkey,
struct TALER_RSA_PublicKeyBinaryEncoded *pkey)
{
gcry_sexp_t psexp;
gcry_mpi_t skey;
gcry_mpi_t sigval;
gcry_mpi_t r_inv;
gcry_mpi_t ubsig;
size_t rsize;
gcry_error_t rc;
int ret;
psexp = NULL;
skey = NULL;
sigval = NULL;
r_inv = NULL;
ubsig = NULL;
rsize = 0;
rc = 0;
ret = GNUNET_SYSERR;
if (! (psexp = decode_public_key (pkey)))
return GNUNET_SYSERR;
ret = key_from_sexp (&skey, psexp, "public-key", "n");
if (0 != ret)
ret = key_from_sexp (&skey, psexp, "rsa", "n");
gcry_sexp_release (psexp);
psexp = NULL;
if (0 != (rc = gcry_mpi_scan (&sigval, GCRYMPI_FMT_USG,
(const unsigned char *) sig,
sizeof (struct TALER_RSA_Signature),
&rsize)))
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
goto cleanup;
}
r_inv = gcry_mpi_new (0);
GNUNET_assert (1 == gcry_mpi_invm (r_inv, bkey->r, skey)); /* n: skey */
ubsig = gcry_mpi_new (0);
gcry_mpi_mulm (ubsig, sigval, r_inv, skey);
rc = gcry_mpi_print (GCRYMPI_FMT_USG,
(unsigned char *) sig,
sizeof (struct TALER_RSA_Signature),
&rsize,
ubsig);
GNUNET_assert (0 == rc);
adjust ((unsigned char *) sig, rsize, sizeof (struct TALER_RSA_Signature));
ret = GNUNET_OK;
cleanup:
if (NULL != psexp) gcry_sexp_release (psexp);
mpi_release_non_null (skey);
mpi_release_non_null (sigval);
mpi_release_non_null (r_inv);
mpi_release_non_null (ubsig);
return ret;
}
/**
* Encode a blinding key
*
* @param bkey the blinding key to encode
* @param bkey_enc where to store the encoded binary key
* @return #GNUNET_OK upon successful encoding; #GNUNET_SYSERR upon failure
*/
int
TALER_RSA_blinding_key_encode (struct TALER_RSA_BlindingKey *bkey,
struct TALER_RSA_BlindingKeyBinaryEncoded *bkey_enc)
{
GNUNET_abort (); /* FIXME: not implemented */
}
/**
* Decode a blinding key from its encoded form
*
* @param bkey_enc the encoded blinding key
* @return the decoded blinding key; NULL upon error
*/
struct TALER_RSA_BlindingKey *
TALER_RSA_blinding_key_decode (struct TALER_RSA_BlindingKeyBinaryEncoded *bkey_enc)
{
GNUNET_abort (); /* FIXME: not implemented */
}
/* end of util/rsa.c */