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:
parent
d4506f8a04
commit
ae917eeee0
@ -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
|
||||
|
@ -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 */
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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_ */
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -6,8 +6,7 @@ lib_LTLIBRARIES = \
|
||||
libtalerutil_la_SOURCES = \
|
||||
util.c \
|
||||
json.c \
|
||||
db.c \
|
||||
rsa.c
|
||||
db.c
|
||||
|
||||
libtalerutil_la_LIBADD = \
|
||||
-lgnunetutil \
|
||||
|
928
src/util/rsa.c
928
src/util/rsa.c
@ -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 */
|
Loading…
Reference in New Issue
Block a user