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_json_lib.h \
taler_mint_service.h \
taler_rsa.h \
taler_signatures.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
#include <gnunet/gnunet_util_lib.h>
#include "taler_rsa.h"
/**
* Purpose for signing public keys signed
@ -113,17 +111,12 @@
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
{
/**
* Signature over the rest of the message
* by the withdraw public key.
*/
struct GNUNET_CRYPTO_EddsaSignature sig;
/**
* Purpose must be #TALER_SIGNATURE_WITHDRAW.
@ -131,24 +124,20 @@ struct TALER_WithdrawRequest
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;
/**
* Denomination public key for the coin that is withdrawn.
* FIXME: change to the hash of the public key (so this
* is fixed-size).
* Hash of the denomination public key for the coin that is withdrawn.
*/
struct TALER_RSA_PublicKeyBinaryEncoded denomination_pub;
struct GNUNET_HashCode h_denomination_pub;
/**
* Purpose containing coin's blinded public key.
*
* FIXME: this should be explicitly a variable-size field with the
* (blinded) message to be signed by the Mint.
* Hash of 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 expire_withdraw;
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 fee_withdraw;
struct TALER_AmountNBO fee_deposit;
@ -238,4 +228,3 @@ struct RefreshMeltConfirmSignRequestBody
GNUNET_NETWORK_STRUCT_END
#endif

View File

@ -29,7 +29,6 @@
#include <gnunet/gnunet_common.h>
#include <libpq-fe.h>
#include "taler_util.h"
#include "taler_rsa.h"
#include "taler_signatures.h"
#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
* not available.
*/
struct TALER_RSA_PrivateKey *denom_priv;
struct GNUNET_CRYPTO_rsa_PrivateKey *denom_priv;
struct TALER_MINT_DenomKeyIssue issue;
};
@ -75,26 +74,43 @@ struct TALER_CoinPublicInfo
/*
* 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.
*/
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 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;
/**
* Signature confirming the withdrawl, matching @e reserve_pub,
* @e denom_pub and @e h_blind.
*/
struct GNUNET_CRYPTO_EddsaSignature reserve_sig;
};
@ -127,7 +143,7 @@ struct RefreshCommitLink
struct LinkData
{
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 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 newcoin_index;
char link_enc[sizeof (struct LinkData)];
@ -177,17 +203,17 @@ struct Deposit
/* FIXME: should be TALER_CoinPublicInfo */
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
* #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;

View File

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

View File

@ -54,25 +54,44 @@ static char *TALER_MINT_db_connection_cfg_str;
if (cond) { GNUNET_break (0); goto EXITIF_exit; } \
} 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
TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn,
struct TALER_RSA_BlindedSignaturePurpose *blind_ev,
const struct GNUNET_HashCode *h_blind,
struct CollectableBlindcoin *collectable)
{
PGresult *result;
struct TALER_DB_QueryParam params[] = {
TALER_DB_QUERY_PARAM_PTR (blind_ev),
TALER_DB_QUERY_PARAM_PTR (h_blind),
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))
{
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);
return GNUNET_SYSERR;
}
if (0 == PQntuples (result))
{
PQclear (result);
@ -80,7 +99,7 @@ TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn,
}
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("reserve_sig", &collectable->reserve_sig),
TALER_DB_RESULT_SPEC("reserve_pub", &collectable->reserve_pub),
@ -93,43 +112,66 @@ TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn,
PQclear (result);
return GNUNET_SYSERR;
}
(void) memcpy (&collectable->ev, blind_ev, sizeof (struct TALER_RSA_BlindedSignaturePurpose));
PQclear (result);
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
TALER_MINT_DB_insert_collectable_blindcoin (PGconn *db_conn,
const struct GNUNET_HashCode *h_blind,
const struct CollectableBlindcoin *collectable)
{
PGresult *result;
struct TALER_DB_QueryParam params[] = {
TALER_DB_QUERY_PARAM_PTR (&collectable->ev),
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);
char *sig_buf;
size_t sig_buf_size;
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));
PQclear (result);
return GNUNET_SYSERR;
}
struct TALER_DB_QueryParam params[] = {
TALER_DB_QUERY_PARAM_PTR (&h_blind),
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)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Insert failed (updated '%s' tupes instead of '1')\n",
PQcmdTuples (result));
PQclear (result);
return GNUNET_SYSERR;
}
result = TALER_DB_exec_prepared (db_conn,
"insert_collectable_blindcoins",
params);
if (PGRES_COMMAND_OK != PQresultStatus (result))
{
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;
}
@ -730,7 +772,7 @@ int
TALER_MINT_DB_insert_refresh_order (PGconn *db_conn,
uint16_t newcoin_index,
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);
struct TALER_DB_QueryParam params[] = {
@ -1267,7 +1309,7 @@ int
TALER_MINT_DB_get_refresh_order (PGconn *db_conn,
uint16_t newcoin_index,
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);
@ -1315,7 +1357,7 @@ int
TALER_MINT_DB_insert_refresh_collectable (PGconn *db_conn,
uint16_t newcoin_index,
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);
struct TALER_DB_QueryParam params[] = {
@ -1343,7 +1385,7 @@ int
TALER_MINT_DB_get_refresh_collectable (PGconn *db_conn,
uint16_t newcoin_index,
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);
@ -1394,7 +1436,7 @@ TALER_MINT_DB_insert_refresh_melt (PGconn *db_conn,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
uint16_t oldcoin_index,
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);
struct TALER_DB_QueryParam params[] = {
@ -1499,8 +1541,8 @@ TALER_db_get_link (PGconn *db_conn,
for (i = 0; i < PQntuples (result); i++)
{
struct LinkDataEnc link_data_enc;
struct TALER_RSA_PublicKeyBinaryEncoded denom_pub;
struct TALER_RSA_Signature ev_sig;
struct GNUNET_CRYPTO_rsa__PublicKey *denom_pub;
struct GNUNET_CRYPTO_rsa_Signature *sig;
struct TALER_DB_ResultSpec rs[] = {
TALER_DB_RESULT_SPEC("link_vector_enc", &link_data_enc),
TALER_DB_RESULT_SPEC("denom_pub", &denom_pub),

View File

@ -27,7 +27,6 @@
#include <microhttpd.h>
#include <gnunet/gnunet_util_lib.h>
#include "taler_util.h"
#include "taler_rsa.h"
#include "taler-mint-httpd_db.h"
#include "mint.h"
@ -35,13 +34,40 @@
int
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
TALER_MINT_DB_get_collectable_blindcoin (PGconn *db_conn,
struct TALER_RSA_BlindedSignaturePurpose *blind_ev,
const struct GNUNET_HashCode *h_blind,
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
TALER_MINT_DB_insert_collectable_blindcoin (PGconn *db_conn,
const struct GNUNET_HashCode *h_blind,
const struct CollectableBlindcoin *collectable);
@ -62,6 +88,15 @@ TALER_MINT_DB_get_reserve (PGconn *db_conn,
const struct GNUNET_CRYPTO_EddsaPublicKey *reserve_pub,
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
TALER_MINT_DB_update_reserve (PGconn *db_conn,
const struct Reserve *reserve,
@ -72,7 +107,7 @@ int
TALER_MINT_DB_insert_refresh_order (PGconn *db_conn,
uint16_t newcoin_index,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub);
const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub);
int
TALER_MINT_DB_get_refresh_session (PGconn *db_conn,
@ -123,19 +158,22 @@ int
TALER_MINT_DB_get_refresh_order (PGconn *db_conn,
uint16_t newcoin_index,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub);
struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub);
int
TALER_MINT_DB_insert_refresh_collectable (PGconn *db_conn,
uint16_t newcoin_index,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
const struct TALER_RSA_Signature *ev_sig);
const struct GNUNET_CRYPTO_rsa_Signature *ev_sig);
int
TALER_MINT_DB_get_refresh_collectable (PGconn *db_conn,
uint16_t newcoin_index,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
struct TALER_RSA_Signature *ev_sig);
struct GNUNET_CRYPTO_rsa_Signature *ev_sig);
int
TALER_MINT_DB_set_reveal_ok (PGconn *db_conn,
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,
uint16_t oldcoin_index,
const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub);
const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub);
int
@ -158,8 +196,8 @@ TALER_MINT_DB_get_refresh_melt (PGconn *db_conn,
typedef
int (*LinkIterator) (void *cls,
const struct LinkDataEnc *link_data_enc,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub,
const struct TALER_RSA_Signature *ev_sig);
const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub,
const struct GNUNET_CRYPTO_rsa_Signature *ev_sig);
int
TALER_db_get_link (PGconn *db_conn,

View File

@ -29,7 +29,6 @@
#include <pthread.h>
#include "mint.h"
#include "taler_signatures.h"
#include "taler_rsa.h"
#include "taler_json_lib.h"
#include "taler-mint-httpd_parsing.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)
{
GNUNET_break (0);
GNUNET_break (0);
/* 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.
*
* @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
*/
int
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;
struct Reserve reserve;
struct Reserve db_reserve;
struct MintKeyState *key_state;
struct CollectableBlindcoin collectable;
struct TALER_MINT_DenomKeyIssuePriv *dki;
struct TALER_RSA_Signature ev_sig;
struct GNUNET_CRYPTO_rsa_Signature *sig;
struct TALER_Amount amount_required;
/* FIXME: the fact that we do this here is a sign that we
need to have different versions of this struct for
the different places it is used! */
struct TALER_WithdrawRequest wsrd = *wsrd_ro;
struct GNUNET_HashCode h_blind;
int res;
GNUNET_CRYPTO_hash (blinded_msg,
blinded_msg_len,
&h_blind);
if (NULL == (db_conn = TALER_MINT_DB_get_connection ()))
{
GNUNET_break (0);
return TALER_MINT_reply_internal_db_error (connection);
}
res = TALER_MINT_DB_get_collectable_blindcoin (db_conn,
&wsrd.coin_envelope,
&h_blind,
&collectable);
if (GNUNET_SYSERR == res)
{
// FIXME: return 'internal error'
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 */
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);
res = TALER_MINT_DB_get_reserve (db_conn,
&wsrd.reserve_pub,
&reserve);
reserve,
&db_reserve);
if (GNUNET_SYSERR == res)
{
// FIXME: return 'internal error'
GNUNET_break (0);
return MHD_NO;
return TALER_MINT_reply_internal_db_error (connection);
}
if (GNUNET_NO == res)
return TALER_MINT_reply_json_pack (connection,
@ -279,26 +288,9 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,
"error",
"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 ();
dki = TALER_MINT_get_denom_key (key_state,
&wsrd.denomination_pub);
denomination_pub);
TALER_MINT_key_state_release (key_state);
if (NULL == dki)
return TALER_MINT_reply_json_pack (connection,
@ -307,52 +299,54 @@ TALER_MINT_db_execute_withdraw_sign (struct MHD_Connection *connection,
"error",
"Denomination not found");
amount_required = TALER_amount_ntoh (dki->issue.value);
amount_required = TALER_amount_add (amount_required,
amount_required = TALER_amount_add (TALER_amount_ntoh (dki->issue.value),
TALER_amount_ntoh (dki->issue.fee_withdraw));
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,
MHD_HTTP_PAYMENT_REQUIRED,
"{s:s}",
"error",
"Insufficient funds");
if (GNUNET_OK !=
TALER_RSA_sign (dki->denom_priv,
&wsrd.coin_envelope,
sizeof (struct TALER_RSA_BlindedSignaturePurpose),
&ev_sig))
db_reserve.balance = TALER_amount_hton
(TALER_amount_subtract (TALER_amount_ntoh (db_reserve.balance),
amount_required));
sig = GNUNET_CRYPTO_rsa_sign (dki->denom_priv,
blinded_msg,
blinded_msg_len);
if (NULL == sig)
{
// FIXME: return 'internal error'
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),
amount_required));
/* transaction start */
if (GNUNET_OK !=
TALER_MINT_DB_update_reserve (db_conn,
&reserve,
&db_reserve,
GNUNET_YES))
{
// FIXME: return 'internal error'
GNUNET_break (0);
return MHD_NO;
return TALER_MINT_reply_internal_db_error (connection);
}
collectable.ev = wsrd.coin_envelope;
collectable.ev_sig = ev_sig;
collectable.sig = sig;
collectable.reserve_pub = wsrd.reserve_pub;
collectable.reserve_sig = wsrd.sig;
if (GNUNET_OK !=
TALER_MINT_DB_insert_collectable_blindcoin (db_conn,
&h_blind,
&collectable))
{
// FIXME: return 'internal error'
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,
&collectable);
}
@ -378,7 +372,7 @@ refresh_accept_denoms (struct MHD_Connection *connection,
const struct MintKeyState *key_state,
const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
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)
{
unsigned int i;
@ -554,7 +548,7 @@ int
TALER_MINT_db_execute_refresh_melt (struct MHD_Connection *connection,
const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
unsigned int num_new_denoms,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pubs,
const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pubs,
unsigned int coin_count,
const struct TALER_CoinPublicInfo *coin_public_infos)
{
@ -821,10 +815,10 @@ helper_refresh_reveal_send_response (struct MHD_Connection *connection,
{
int res;
unsigned int newcoin_index;
struct TALER_RSA_Signature *sigs;
struct GNUNET_CRYPTO_rsa_Signature **sigs;
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++)
{
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 LinkData link_data;
struct TALER_RSA_BlindedSignaturePurpose *coin_ev_check;
// struct BlindedSignaturePurpose *coin_ev_check;
struct GNUNET_CRYPTO_EcdsaPublicKey coin_pub;
struct TALER_RSA_BlindingKey *bkey;
struct TALER_RSA_PublicKeyBinaryEncoded denom_pub;
struct GNUNET_CRYPTO_rsa_BlindingKey *bkey;
struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
char *buf;
size_t buf_len;
bkey = NULL;
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);
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");
// FIXME: return error code!
@ -1024,26 +1021,31 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
// FIXME: return error code!
return MHD_NO;
}
if (NULL == (coin_ev_check =
TALER_RSA_message_blind (&coin_pub,
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
if (NULL == (buf_len =
GNUNET_CRYPTO_rsa_blind (&h_msg,
bkey,
&denom_pub)))
denom_pub,
&buf)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "blind failed\n");
// FIXME: return error code!
return MHD_NO;
}
if (0 != memcmp (&coin_ev_check,
&commit_coin.coin_ev,
sizeof (struct TALER_RSA_BlindedSignaturePurpose)))
if ( (buf_len != commit_coin.coin_ev_size) ||
(0 != memcmp (buf,
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);
// FIXME: return error code!
GNUNET_free (buf);
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++)
{
struct RefreshCommitCoin commit_coin;
struct TALER_RSA_PublicKeyBinaryEncoded denom_pub;
struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
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,
refresh_session_pub,
@ -1091,11 +1093,10 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
// FIXME: return error code!
return MHD_NO;
}
if (GNUNET_OK !=
TALER_RSA_sign (dki->denom_priv,
&commit_coin.coin_ev,
sizeof (struct TALER_RSA_BlindedSignaturePurpose),
&ev_sig))
ev_sig = GNUNET_CRYPTO_rsa_sign (dki->denom_priv,
commit_coin.coin_ev,
commit_coin.coin_ev_len);
if (NULL == ev_sig)
{
GNUNET_break (0);
// FIXME: return error code!
@ -1144,25 +1145,33 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
static int
link_iter (void *cls,
const struct LinkDataEnc *link_data_enc,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pub,
const struct TALER_RSA_Signature *ev_sig)
const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub,
const struct GNUNET_CRYPTO_rsa_Signature *ev_sig)
{
json_t *list = cls;
json_t *obj = json_object ();
char *buf;
size_t buf_len;
json_array_append_new (list, obj);
json_object_set_new (obj, "link_enc",
TALER_JSON_from_data (link_data_enc,
sizeof (struct LinkDataEnc)));
TALER_JSON_from_data (link_data_enc,
sizeof (struct LinkDataEnc)));
buf_len = GNUNET_CRYPTO_rsa_public_key_encode (denom_pub,
&buf);
json_object_set_new (obj, "denom_pub",
TALER_JSON_from_data (denom_pub,
sizeof (struct TALER_RSA_PublicKeyBinaryEncoded)));
TALER_JSON_from_data (buf,
buf_len));
GNUNET_free (buf);
buf_len = GNUNET_CRYPTO_rsa_signature_encode (ev_sig,
&buf);
json_object_set_new (obj, "ev_sig",
TALER_JSON_from_data (ev_sig,
sizeof (struct TALER_RSA_Signature)));
TALER_JSON_from_data (buf,
buf_len));
GNUNET_free (buf_len);
return GNUNET_OK;
}

View File

@ -25,7 +25,6 @@
#include <microhttpd.h>
#include <gnunet/gnunet_util_lib.h>
#include "taler_util.h"
#include "taler_rsa.h"
#include "taler-mint-httpd_keys.h"
#include "mint.h"
@ -62,12 +61,20 @@ TALER_MINT_db_execute_withdraw_status (struct MHD_Connection *connection,
* Execute a /withdraw/sign.
*
* @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
*/
int
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,
const struct GNUNET_CRYPTO_EddsaPublicKey *refresh_session_pub,
unsigned int num_new_denoms,
const struct TALER_RSA_PublicKeyBinaryEncoded *denom_pubs,
const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pubs,
unsigned int coin_count,
const struct TALER_CoinPublicInfo *coin_public_infos);

View File

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

View File

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

View File

@ -107,7 +107,7 @@ TALER_MINT_key_state_acquire (void);
*/
struct TALER_MINT_DenomKeyIssuePriv *
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 coin_public_info the coin public info to check for validity
* @return GNUNET_YES if the coin is valid,
* GNUNET_NO if it is invalid
* GNUNET_SYSERROR if an internal error occured
* @return #GNUNET_YES if the coin is valid,
* #GNUNET_NO if it is invalid
* #GNUNET_SYSERROR if an internal error occured
*/
int
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
* 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
TALER_MINT_key_reload_loop (void);

View File

@ -553,22 +553,29 @@ TALER_MINT_parse_json_data (struct MHD_Connection *connection,
{
unsigned int i;
int ret;
void *ptr;
ret = GNUNET_YES;
for (i=0; NULL != spec[i].field_name; i++)
{
if (0 == spec[i].destination_size_in)
{
ptr = NULL;
parse_variable_json_data (connection, root,
spec[i].field_name,
(void **) spec[i].destination,
&ptr,
&spec[i].destination_size_out,
&ret);
spec[i].destination = ptr;
}
else
{
parse_fixed_json_data (connection, root,
spec[i].field_name,
spec[i].destination,
spec[i].destination_size_in,
&ret);
}
}
if (GNUNET_YES != ret)
TALER_MINT_release_parsed_data (spec);
@ -641,4 +648,63 @@ TALER_MINT_mhd_request_arg_data (struct MHD_Connection *connection,
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 */

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.
*
* @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.
@ -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
* invalid.
@ -241,6 +240,28 @@ TALER_MINT_mhd_request_arg_data (struct MHD_Connection *connection,
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_ */

View File

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

View File

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

View File

@ -209,7 +209,7 @@ TALER_MINT_reply_refresh_melt_success (struct MHD_Connection *connection,
int
TALER_MINT_reply_refresh_reveal_success (struct MHD_Connection *connection,
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_db.h"
#include "taler_signatures.h"
#include "taler_rsa.h"
#include "taler_json_lib.h"
#include "taler-mint-httpd_parsing.h"
#include "taler-mint-httpd_keys.h"
@ -94,6 +93,12 @@ TALER_MINT_handler_withdraw_sign (struct RequestHandler *rh,
{
struct TALER_WithdrawRequest wsrd;
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,
"reserve_pub",
@ -105,33 +110,66 @@ TALER_MINT_handler_withdraw_sign (struct RequestHandler *rh,
return MHD_YES; /* invalid request */
/* FIXME: handle variable-size signing keys! */
res = TALER_MINT_mhd_request_arg_data (connection,
"denom_pub",
&wsrd.denomination_pub,
sizeof (struct TALER_RSA_PublicKeyBinaryEncoded));
res = TALER_MINT_mhd_request_var_arg_data (connection,
"denom_pub",
&denomination_pub_data,
&denomination_pub_data_size);
if (GNUNET_SYSERR == res)
return MHD_NO; /* internal error */
if (GNUNET_NO == res)
return MHD_YES; /* invalid request */
res = TALER_MINT_mhd_request_arg_data (connection,
"coin_ev",
&wsrd.coin_envelope,
sizeof (struct TALER_RSA_Signature));
res = TALER_MINT_mhd_request_var_arg_data (connection,
"coin_ev",
&blinded_msg,
&blinded_msg_len);
if (GNUNET_SYSERR == res)
return MHD_NO; /* internal error */
if (GNUNET_NO == res)
return MHD_YES; /* invalid request */
res = TALER_MINT_mhd_request_arg_data (connection,
"reserve_sig",
&wsrd.sig,
&signature,
sizeof (struct GNUNET_CRYPTO_EddsaSignature));
if (GNUNET_SYSERR == res)
return MHD_NO; /* internal error */
if (GNUNET_NO == res)
return MHD_YES; /* invalid request */
return TALER_MINT_db_execute_withdraw_sign (connection,
&wsrd);
/* verify signature! */
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 */

View File

@ -105,7 +105,7 @@ static struct GNUNET_CRYPTO_EddsaPublicKey *master_pub;
static struct GNUNET_TIME_Absolute lookahead_sign_stamp;
int
static int
config_get_denom (const char *section, const char *option, struct TALER_Amount *denom)
{
char *str;
@ -117,7 +117,7 @@ config_get_denom (const char *section, const char *option, struct TALER_Amount *
}
char *
static char *
get_signkey_dir ()
{
char *dir;
@ -128,7 +128,7 @@ get_signkey_dir ()
}
char *
static char *
get_signkey_file (struct GNUNET_TIME_Absolute start)
{
char *dir;
@ -140,13 +140,12 @@ get_signkey_file (struct GNUNET_TIME_Absolute start)
}
/**
* Hash the data defining the coin type.
* Exclude information that may not be the same for all
* instances of the coin type (i.e. the anchor, overlap).
*/
void
static void
hash_coin_type (const struct CoinTypeParams *p, struct GNUNET_HashCode *hash)
{
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[out] anchor the timestamp where the first new key should be generated
*/
void
static void
get_anchor (const char *dir,
struct GNUNET_TIME_Relative duration,
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
}
static void
create_signkey_issue_priv (struct GNUNET_TIME_Absolute start,
struct GNUNET_TIME_Relative duration,
@ -327,7 +327,7 @@ check_signkey_valid (const char *signkey_filename)
}
int
static int
mint_keys_update_signkeys ()
{
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)
{
const char *dir;
@ -434,8 +434,8 @@ static void
create_denomkey_issue (struct CoinTypeParams *params,
struct TALER_MINT_DenomKeyIssuePriv *dki)
{
GNUNET_assert (NULL != (dki->denom_priv = TALER_RSA_key_create ()));
TALER_RSA_key_get_public (dki->denom_priv, &dki->issue.denom_pub);
GNUNET_assert (NULL != (dki->denom_priv = GNUNET_CRYPTO_rsa_private_key_create ()));
dki->issue.denom_pub = GNUNET_CRYPTO_rsa_private_key_get_get_public (dki->denom_priv);
dki->issue.master = *master_pub;
dki->issue.start = GNUNET_TIME_absolute_hton (params->anchor);
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)
{
struct CoinTypeParams p;
@ -496,7 +496,7 @@ mint_keys_update_cointype (const char *coin_alias)
printf ("Target path: %s\n", dkf);
create_denomkey_issue (&p, &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)
{
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 ()
{
char *coin_types;
@ -659,4 +659,3 @@ main (int argc, char *const *argv)
return 1;
return 0;
}

View File

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

View File

@ -6,8 +6,7 @@ lib_LTLIBRARIES = \
libtalerutil_la_SOURCES = \
util.c \
json.c \
db.c \
rsa.c
db.c
libtalerutil_la_LIBADD = \
-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 */