mention need to audit randomness of gamma
This commit is contained in:
commit
bf8b9d1435
1
.gitignore
vendored
1
.gitignore
vendored
@ -30,6 +30,7 @@ GTAGS
|
|||||||
src/lib/test_mint_api
|
src/lib/test_mint_api
|
||||||
doc/doxygen/doxygen_sqlite3.db
|
doc/doxygen/doxygen_sqlite3.db
|
||||||
src/mint-lib/test_mint_api
|
src/mint-lib/test_mint_api
|
||||||
|
src/mint-tools/taler-auditor-sign
|
||||||
src/mint-tools/taler-mint-dbinit
|
src/mint-tools/taler-mint-dbinit
|
||||||
src/mint-tools/taler-mint-keycheck
|
src/mint-tools/taler-mint-keycheck
|
||||||
src/mint-tools/taler-mint-keyup
|
src/mint-tools/taler-mint-keyup
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
# Currency supported by the mint (can only be one)
|
# Currency supported by the mint (can only be one)
|
||||||
CURRENCY = EUR
|
CURRENCY = EUR
|
||||||
|
|
||||||
# Wire format supproted by the mint (currently only SEPA is implemented)
|
# Wire format supported by the mint, case-insensitive.
|
||||||
|
# Examples for formats include 'test' for testing and 'sepa' (for EU IBAN).
|
||||||
WIREFORMAT = SEPA
|
WIREFORMAT = SEPA
|
||||||
|
|
||||||
# HTTP port the mint listens to
|
# HTTP port the mint listens to
|
||||||
@ -19,3 +20,9 @@ TESTRUN = YES
|
|||||||
[mintdb-postgres]
|
[mintdb-postgres]
|
||||||
|
|
||||||
DB_CONN_STR = "postgres:///talercheck"
|
DB_CONN_STR = "postgres:///talercheck"
|
||||||
|
|
||||||
|
[mint-wire-sepa]
|
||||||
|
SEPA_RESPONSE_FILE = "sepa.json"
|
||||||
|
|
||||||
|
[mint-wire-test]
|
||||||
|
REDIRECT_URL = "http://test/"
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
SUBDIRS = . doxygen
|
SUBDIRS = . doxygen
|
||||||
|
|
||||||
man_MANS = \
|
man_MANS = \
|
||||||
|
taler-auditor-sign.1 \
|
||||||
taler-mint-dbinit.1 \
|
taler-mint-dbinit.1 \
|
||||||
taler-mint-httpd.1 \
|
taler-mint-httpd.1 \
|
||||||
taler-mint-keyup.1 \
|
taler-mint-keyup.1 \
|
||||||
|
98714
doc/paper/rfc.bib
Normal file
98714
doc/paper/rfc.bib
Normal file
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,13 @@
|
|||||||
year={2008}
|
year={2008}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@InProceedings{apod,
|
||||||
|
author = {Elli Androulaki and Steven Bellovin},
|
||||||
|
title = {APOD: Anonymous Physical Object Delivery},
|
||||||
|
booktitle = {Symposium on Privacy-Enhancing Technologies (PETS)},
|
||||||
|
year = {2009},
|
||||||
|
}
|
||||||
|
|
||||||
@Article{blum1981,
|
@Article{blum1981,
|
||||||
author = {Manuel Blum},
|
author = {Manuel Blum},
|
||||||
title = {Coin Flipping by Telephone},
|
title = {Coin Flipping by Telephone},
|
||||||
@ -12,6 +19,64 @@
|
|||||||
pages = {11-15},
|
pages = {11-15},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Misc{greece2015cash,
|
||||||
|
author = {Reuters},
|
||||||
|
title = {Greek council recommends 60 euro limit on ATM withdrawals from Tuesday},
|
||||||
|
howpublished = {\url{http://www.reuters.com/article/2015/06/28/eurozone-greece-limits-idUSA8N0Z302P20150628}},
|
||||||
|
month = {June},
|
||||||
|
year = {2015},
|
||||||
|
}
|
||||||
|
|
||||||
|
@Misc{france2015cash,
|
||||||
|
author = {Heinz-Peter Bader},
|
||||||
|
title = {France steps up monitoring of cash payments to fight low-cost terrorism},
|
||||||
|
howpublished = {\url{http://www.reuters.com/article/2015/03/18/us-france-security-financing-idUSKBN0ME14720150318}},
|
||||||
|
month = {Mar},
|
||||||
|
year = {2015},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Misc{fatf1997,
|
||||||
|
title = {FATF-IX report on money laundering typologies},
|
||||||
|
howpublished = {\url{http://www.fatf-gafi.org/media/fatf/documents/reports/1996\%201997\%20ENG.pdf}},
|
||||||
|
month = {feb},
|
||||||
|
year = {1998},
|
||||||
|
}
|
||||||
|
|
||||||
|
@TechReport{,
|
||||||
|
author = {},
|
||||||
|
title = {},
|
||||||
|
institution = {},
|
||||||
|
year = {},
|
||||||
|
OPTkey = {},
|
||||||
|
OPTtype = {},
|
||||||
|
OPTnumber = {},
|
||||||
|
OPTaddress = {},
|
||||||
|
OPTmonth = {},
|
||||||
|
OPTnote = {},
|
||||||
|
OPTannote = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@InProceedings{sander1999escrow,
|
||||||
|
author = {Tomas Sander and Amnon Ta-Shma},
|
||||||
|
title = {On Anonymous Electronic Cash and Crime},
|
||||||
|
booktitle = {ISW'99},
|
||||||
|
year = {1999},
|
||||||
|
series = {LNCS 1729},
|
||||||
|
pages = {202--206},
|
||||||
|
}
|
||||||
|
|
||||||
|
@Article{solms1992perfect,
|
||||||
|
author = {Sebastiaan H. von Solms and David Naccache},
|
||||||
|
title = {On blind signatures and perfect crimes},
|
||||||
|
journal = {Computers \& Security},
|
||||||
|
year = {1992},
|
||||||
|
volume = {11},
|
||||||
|
number = {6},
|
||||||
|
pages = {581--583},
|
||||||
|
}
|
||||||
|
|
||||||
@inproceedings{chaum1990untraceable,
|
@inproceedings{chaum1990untraceable,
|
||||||
title={Untraceable electronic cash},
|
title={Untraceable electronic cash},
|
||||||
author={Chaum, David and Fiat, Amos and Naor, Moni},
|
author={Chaum, David and Fiat, Amos and Naor, Moni},
|
||||||
@ -48,6 +113,23 @@
|
|||||||
organization={IEEE}
|
organization={IEEE}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@InProceedings{fc2014murdoch,
|
||||||
|
author = {Stephen Murdoch and Ross Anderson},
|
||||||
|
title = {Security Protocols and Evidence: Where Many Payment Systems Fail},
|
||||||
|
booktitle = {Financial Cryptography and Data Security},
|
||||||
|
year = {2014},
|
||||||
|
}
|
||||||
|
|
||||||
|
@book{ engels1844,
|
||||||
|
author = "Friedrich Engels",
|
||||||
|
title = "{Umrisse zu einer Kritik der National\"okonomie}",
|
||||||
|
year = "1844",
|
||||||
|
publisher = "Ruge and Marx, Paris",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@inproceedings{selby2004analyzing,
|
@inproceedings{selby2004analyzing,
|
||||||
title={Analyzing the Success and Failure of Recent e-Payment Schemes},
|
title={Analyzing the Success and Failure of Recent e-Payment Schemes},
|
||||||
author={Selby, Jack R},
|
author={Selby, Jack R},
|
||||||
@ -91,4 +173,3 @@
|
|||||||
www_pdf_url = {https://www.torproject.org/svn/trunk/doc/design-paper/tor-design.pdf},
|
www_pdf_url = {https://www.torproject.org/svn/trunk/doc/design-paper/tor-design.pdf},
|
||||||
www_section = {Anonymous communication},
|
www_section = {Anonymous communication},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1116
doc/paper/taler.tex
1116
doc/paper/taler.tex
File diff suppressed because it is too large
Load Diff
35
doc/taler-auditor-sign.1
Normal file
35
doc/taler-auditor-sign.1
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
.TH TALER\-AUDITOR\-SIGN 1 "Sep 15, 2015" "GNU Taler"
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
taler\-auditor\-sign \- Sign mint denomination as auditor.
|
||||||
|
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B taler\-auditor\-sign
|
||||||
|
.RI [ options ]
|
||||||
|
.br
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fBtaler\-auditor\-sign\fP is a command line tool to be used by an auditor to sign that he is aware of certain keys being used by a mint. Using this signature, the auditor affirms that he will verify that the mint is properly accounting for those coins.
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
.B
|
||||||
|
.IP "\-a FILE, \-\-auditor-key=FILE"
|
||||||
|
Location of the private EdDSA auditor key. If it does not exist, it will be created.
|
||||||
|
.B
|
||||||
|
.IP "\-h, \-\-help"
|
||||||
|
Print short help on options.
|
||||||
|
.B
|
||||||
|
.IP "\-m KEY, \-\-mint-key=KEY"
|
||||||
|
Public key of the mint in Crockford base32 encoding, for example as generated by gnunet\-ecc \-p.
|
||||||
|
.B
|
||||||
|
.IP "\-r FILE, \-\-mint-request=FILE"
|
||||||
|
File with the mint's denomination key signing request as generated by taler\-mint\-keyup \-o.
|
||||||
|
.B
|
||||||
|
.IP "\-o FILE, \-\-output=FILE"
|
||||||
|
File where the auditor should write the EdDSA signature.
|
||||||
|
|
||||||
|
.SH BUGS
|
||||||
|
Report bugs by using Mantis <https://gnunet.org/bugs/> or by sending electronic mail to <taler@gnu.org>
|
||||||
|
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
\fBtaler\-mint\-keyup\fP(1), \fBgnunet\-ecc\fP(1), \fBtaler.conf\fP(5)
|
@ -13,6 +13,9 @@ taler\-mint\-httpd \- Run Taler mint (with RESTful API)
|
|||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.B
|
.B
|
||||||
|
.IP "\-C, \-\-connection-close"
|
||||||
|
Force each HTTP connection to be closed after each request (useful in combination with \-f to avoid having to wait for nc to time out).
|
||||||
|
.B
|
||||||
.IP "\-d DIRNAME, \-\-mint-dir=DIRNAME"
|
.IP "\-d DIRNAME, \-\-mint-dir=DIRNAME"
|
||||||
Use the configuration and other resources for the mint to operate from DIRNAME.
|
Use the configuration and other resources for the mint to operate from DIRNAME.
|
||||||
.B
|
.B
|
||||||
|
@ -22,6 +22,9 @@ Print short help on options.
|
|||||||
.IP "\-m FILE, \-\-master-key=FILE"
|
.IP "\-m FILE, \-\-master-key=FILE"
|
||||||
Location of the private EdDSA offline master key of the mint.
|
Location of the private EdDSA offline master key of the mint.
|
||||||
.B
|
.B
|
||||||
|
.IP "\-o FILE, \-\-ouptut=FILE"
|
||||||
|
Where to write a denomination key signing request file to be given to the auditor.
|
||||||
|
.B
|
||||||
.IP "\-t TIMESTAMP, \-\-time=TIMESTAMP"
|
.IP "\-t TIMESTAMP, \-\-time=TIMESTAMP"
|
||||||
Operate as if the current time was TIMESTAMP.
|
Operate as if the current time was TIMESTAMP.
|
||||||
.B
|
.B
|
||||||
|
@ -189,6 +189,18 @@ struct TALER_AuditorPublicKeyP
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of the public key used by the auditor.
|
||||||
|
*/
|
||||||
|
struct TALER_AuditorSignatureP
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Taler uses EdDSA signatures for auditors.
|
||||||
|
*/
|
||||||
|
struct GNUNET_CRYPTO_EddsaSignature eddsa_sig;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type of the offline master public keys used by the mint.
|
* @brief Type of the offline master public keys used by the mint.
|
||||||
*/
|
*/
|
||||||
|
@ -167,12 +167,12 @@ TALER_hash_json (json_t *json,
|
|||||||
/**
|
/**
|
||||||
* Check if the given wire format JSON object is correctly formatted
|
* Check if the given wire format JSON object is correctly formatted
|
||||||
*
|
*
|
||||||
* @param type the type of the wire format
|
* @param allowed NULL-terminated array of allowed wire format types
|
||||||
* @param wire the JSON wire format object
|
* @param wire the JSON wire format object
|
||||||
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
|
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TALER_json_validate_wireformat (const char *type,
|
TALER_json_validate_wireformat (const char **allowed,
|
||||||
const json_t *wire);
|
const json_t *wire);
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,6 +149,11 @@ struct TALER_MINT_DenomPublicKey
|
|||||||
*/
|
*/
|
||||||
struct TALER_DenominationPublicKey key;
|
struct TALER_DenominationPublicKey key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hash of the public key.
|
||||||
|
*/
|
||||||
|
struct GNUNET_HashCode h_key;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Timestamp indicating when the denomination key becomes valid
|
* Timestamp indicating when the denomination key becomes valid
|
||||||
*/
|
*/
|
||||||
@ -165,6 +170,15 @@ struct TALER_MINT_DenomPublicKey
|
|||||||
*/
|
*/
|
||||||
struct GNUNET_TIME_Absolute deposit_valid_until;
|
struct GNUNET_TIME_Absolute deposit_valid_until;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When do signatures with this denomination key become invalid?
|
||||||
|
* After this point, these signatures cannot be used in (legal)
|
||||||
|
* disputes anymore, as the Mint is then allowed to destroy its side
|
||||||
|
* of the evidence. @e expire_legal is expected to be significantly
|
||||||
|
* larger than @e expire_spend (by a year or more).
|
||||||
|
*/
|
||||||
|
struct GNUNET_TIME_Absolute expire_legal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value of this denomination
|
* The value of this denomination
|
||||||
*/
|
*/
|
||||||
@ -204,6 +218,8 @@ struct TALER_MINT_AuditorInformation
|
|||||||
* that website. We expect that in practice software is going to
|
* that website. We expect that in practice software is going to
|
||||||
* often ship with an initial list of accepted auditors, just like
|
* often ship with an initial list of accepted auditors, just like
|
||||||
* browsers ship with a CA root store.
|
* browsers ship with a CA root store.
|
||||||
|
*
|
||||||
|
* This field may be NULL. (#3987).
|
||||||
*/
|
*/
|
||||||
const char *auditor_url;
|
const char *auditor_url;
|
||||||
|
|
||||||
@ -218,7 +234,7 @@ struct TALER_MINT_AuditorInformation
|
|||||||
* elements point to the same locations as the entries
|
* elements point to the same locations as the entries
|
||||||
* in the key's main `denom_keys` array.
|
* in the key's main `denom_keys` array.
|
||||||
*/
|
*/
|
||||||
struct TALER_MINT_DenomPublicKey *const*denom_keys;
|
const struct TALER_MINT_DenomPublicKey **denom_keys;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -246,7 +262,7 @@ struct TALER_MINT_Keys
|
|||||||
/**
|
/**
|
||||||
* Array of the keys of the auditors of the mint.
|
* Array of the keys of the auditors of the mint.
|
||||||
*/
|
*/
|
||||||
struct TALER_AuditorPublicKeyP *auditors;
|
struct TALER_MINT_AuditorInformation *auditors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Length of the @e sign_keys array.
|
* Length of the @e sign_keys array.
|
||||||
@ -353,6 +369,100 @@ TALER_MINT_get_denomination_key (const struct TALER_MINT_Keys *keys,
|
|||||||
const struct TALER_DenominationPublicKey *pk);
|
const struct TALER_DenominationPublicKey *pk);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the denomination key details from the mint.
|
||||||
|
*
|
||||||
|
* @param keys the mint's key set
|
||||||
|
* @param hc hash of the public key of the denomination to lookup
|
||||||
|
* @return details about the given denomination key
|
||||||
|
*/
|
||||||
|
const struct TALER_MINT_DenomPublicKey *
|
||||||
|
TALER_MINT_get_denomination_key_by_hash (const struct TALER_MINT_Keys *keys,
|
||||||
|
const struct GNUNET_HashCode *hc);
|
||||||
|
|
||||||
|
|
||||||
|
/* ********************* /wire *********************** */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A Wire format inquiry handle
|
||||||
|
*/
|
||||||
|
struct TALER_MINT_WireHandle;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callbacks of this type are used to serve the result of submitting a
|
||||||
|
* wire format inquiry request to a mint.
|
||||||
|
*
|
||||||
|
* The callback is invoked multiple times, once for each supported @a
|
||||||
|
* method. Finally, it is invoked one more time with cls/0/NULL/NULL
|
||||||
|
* to indicate the end of the iteration. If any request fails to
|
||||||
|
* generate a valid response from the mint, @a http_status will also
|
||||||
|
* be zero and the iteration will also end. Thus, the iteration
|
||||||
|
* always ends with a final call with an @a http_status of 0. If the
|
||||||
|
* @a http_status is already 0 on the first call, then the response to
|
||||||
|
* the /wire request was invalid. Later, clients can tell the
|
||||||
|
* difference between @a http_status of 0 indicating a failed
|
||||||
|
* /wire/method request and a regular end of the iteration by @a
|
||||||
|
* method being non-NULL. If the mint simply correctly asserts that
|
||||||
|
* it does not support any methods, @a method will be NULL but the @a
|
||||||
|
* http_status will be #MHD_HTTP_OK for the first call (followed by a
|
||||||
|
* cls/0/NULL/NULL call to signal the end of the iteration).
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful request;
|
||||||
|
* 0 if the mint's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param method wire format method supported, i.e. "test" or "sepa", or NULL
|
||||||
|
* if already the /wire request failed.
|
||||||
|
* @param obj the received JSON reply, if successful this should be the wire
|
||||||
|
* format details as provided by /wire/METHOD/, or NULL if the
|
||||||
|
* reply was not in JSON format (in this case, the client might
|
||||||
|
* want to do an HTTP request to /wire/METHOD/ with a browser to
|
||||||
|
* provide more information to the user about the @a method).
|
||||||
|
*/
|
||||||
|
typedef void
|
||||||
|
(*TALER_MINT_WireResultCallback) (void *cls,
|
||||||
|
unsigned int http_status,
|
||||||
|
const char *method,
|
||||||
|
json_t *obj);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain information about a mint's wire instructions.
|
||||||
|
* A mint may provide wire instructions for creating
|
||||||
|
* a reserve. The wire instructions also indicate
|
||||||
|
* which wire formats merchants may use with the mint.
|
||||||
|
* This API is typically used by a wallet for wiring
|
||||||
|
* funds, and possibly by a merchant to determine
|
||||||
|
* supported wire formats.
|
||||||
|
*
|
||||||
|
* Note that while we return the (main) response verbatim to the
|
||||||
|
* caller for further processing, we do already verify that the
|
||||||
|
* response is well-formed (i.e. that signatures included in the
|
||||||
|
* response are all valid). If the mint's reply is not well-formed,
|
||||||
|
* we return an HTTP status code of zero to @a cb.
|
||||||
|
*
|
||||||
|
* @param mint the mint handle; the mint must be ready to operate
|
||||||
|
* @param wire_cb the callback to call when a reply for this request is available
|
||||||
|
* @param wire_cb_cls closure for the above callback
|
||||||
|
* @return a handle for this request
|
||||||
|
*/
|
||||||
|
struct TALER_MINT_WireHandle *
|
||||||
|
TALER_MINT_wire (struct TALER_MINT_Handle *mint,
|
||||||
|
TALER_MINT_WireResultCallback wire_cb,
|
||||||
|
void *wire_cb_cls);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel a wire information request. This function cannot be used
|
||||||
|
* on a request handle if a response is already served for it.
|
||||||
|
*
|
||||||
|
* @param wh the wire information request handle
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_MINT_wire_cancel (struct TALER_MINT_WireHandle *wh);
|
||||||
|
|
||||||
|
|
||||||
/* ********************* /deposit *********************** */
|
/* ********************* /deposit *********************** */
|
||||||
|
|
||||||
|
|
||||||
@ -437,13 +547,13 @@ void
|
|||||||
TALER_MINT_deposit_cancel (struct TALER_MINT_DepositHandle *deposit);
|
TALER_MINT_deposit_cancel (struct TALER_MINT_DepositHandle *deposit);
|
||||||
|
|
||||||
|
|
||||||
/* ********************* /withdraw/status *********************** */
|
/* ********************* /reserve/status *********************** */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A /withdraw/status Handle
|
* @brief A /reserve/status Handle
|
||||||
*/
|
*/
|
||||||
struct TALER_MINT_WithdrawStatusHandle;
|
struct TALER_MINT_ReserveStatusHandle;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -513,7 +623,7 @@ struct TALER_MINT_ReserveHistory
|
|||||||
* @param history detailed transaction history, NULL on error
|
* @param history detailed transaction history, NULL on error
|
||||||
*/
|
*/
|
||||||
typedef void
|
typedef void
|
||||||
(*TALER_MINT_WithdrawStatusResultCallback) (void *cls,
|
(*TALER_MINT_ReserveStatusResultCallback) (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
json_t *json,
|
json_t *json,
|
||||||
const struct TALER_Amount *balance,
|
const struct TALER_Amount *balance,
|
||||||
@ -537,10 +647,10 @@ typedef void
|
|||||||
* @return a handle for this request; NULL if the inputs are invalid (i.e.
|
* @return a handle for this request; NULL if the inputs are invalid (i.e.
|
||||||
* signatures fail to verify). In this case, the callback is not called.
|
* signatures fail to verify). In this case, the callback is not called.
|
||||||
*/
|
*/
|
||||||
struct TALER_MINT_WithdrawStatusHandle *
|
struct TALER_MINT_ReserveStatusHandle *
|
||||||
TALER_MINT_withdraw_status (struct TALER_MINT_Handle *mint,
|
TALER_MINT_reserve_status (struct TALER_MINT_Handle *mint,
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
TALER_MINT_WithdrawStatusResultCallback cb,
|
TALER_MINT_ReserveStatusResultCallback cb,
|
||||||
void *cb_cls);
|
void *cb_cls);
|
||||||
|
|
||||||
|
|
||||||
@ -551,16 +661,16 @@ TALER_MINT_withdraw_status (struct TALER_MINT_Handle *mint,
|
|||||||
* @param wsh the withdraw status request handle
|
* @param wsh the withdraw status request handle
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TALER_MINT_withdraw_status_cancel (struct TALER_MINT_WithdrawStatusHandle *wsh);
|
TALER_MINT_reserve_status_cancel (struct TALER_MINT_ReserveStatusHandle *wsh);
|
||||||
|
|
||||||
|
|
||||||
/* ********************* /withdraw/sign *********************** */
|
/* ********************* /reserve/withdraw *********************** */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A /withdraw/sign Handle
|
* @brief A /reserve/withdraw Handle
|
||||||
*/
|
*/
|
||||||
struct TALER_MINT_WithdrawSignHandle;
|
struct TALER_MINT_ReserveWithdrawHandle;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -574,14 +684,14 @@ struct TALER_MINT_WithdrawSignHandle;
|
|||||||
* @param full_response full response from the mint (for logging, in case of errors)
|
* @param full_response full response from the mint (for logging, in case of errors)
|
||||||
*/
|
*/
|
||||||
typedef void
|
typedef void
|
||||||
(*TALER_MINT_WithdrawSignResultCallback) (void *cls,
|
(*TALER_MINT_ReserveWithdrawResultCallback) (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
const struct TALER_DenominationSignature *sig,
|
const struct TALER_DenominationSignature *sig,
|
||||||
json_t *full_response);
|
json_t *full_response);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Withdraw a coin from the mint using a /withdraw/sign request. This
|
* Withdraw a coin from the mint using a /reserve/withdraw request. This
|
||||||
* API is typically used by a wallet. Note that to ensure that no
|
* API is typically used by a wallet. Note that to ensure that no
|
||||||
* money is lost in case of hardware failures, the caller must have
|
* money is lost in case of hardware failures, the caller must have
|
||||||
* committed (most of) the arguments to disk before calling, and be
|
* committed (most of) the arguments to disk before calling, and be
|
||||||
@ -601,13 +711,13 @@ typedef void
|
|||||||
* if the inputs are invalid (i.e. denomination key not with this mint).
|
* if the inputs are invalid (i.e. denomination key not with this mint).
|
||||||
* In this case, the callback is not called.
|
* In this case, the callback is not called.
|
||||||
*/
|
*/
|
||||||
struct TALER_MINT_WithdrawSignHandle *
|
struct TALER_MINT_ReserveWithdrawHandle *
|
||||||
TALER_MINT_withdraw_sign (struct TALER_MINT_Handle *mint,
|
TALER_MINT_reserve_withdraw (struct TALER_MINT_Handle *mint,
|
||||||
const struct TALER_MINT_DenomPublicKey *pk,
|
const struct TALER_MINT_DenomPublicKey *pk,
|
||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||||
const struct TALER_DenominationBlindingKey *blinding_key,
|
const struct TALER_DenominationBlindingKey *blinding_key,
|
||||||
TALER_MINT_WithdrawSignResultCallback res_cb,
|
TALER_MINT_ReserveWithdrawResultCallback res_cb,
|
||||||
void *res_cb_cls);
|
void *res_cb_cls);
|
||||||
|
|
||||||
|
|
||||||
@ -618,7 +728,7 @@ TALER_MINT_withdraw_sign (struct TALER_MINT_Handle *mint,
|
|||||||
* @param sign the withdraw sign request handle
|
* @param sign the withdraw sign request handle
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TALER_MINT_withdraw_sign_cancel (struct TALER_MINT_WithdrawSignHandle *sign);
|
TALER_MINT_reserve_withdraw_cancel (struct TALER_MINT_ReserveWithdrawHandle *sign);
|
||||||
|
|
||||||
|
|
||||||
/* ********************* /refresh/melt+reveal ***************************** */
|
/* ********************* /refresh/melt+reveal ***************************** */
|
||||||
|
@ -37,6 +37,12 @@
|
|||||||
*/
|
*/
|
||||||
#define TALER_MINTDB_DIR_DENOMINATION_KEYS "denomkeys"
|
#define TALER_MINTDB_DIR_DENOMINATION_KEYS "denomkeys"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subdirectory under the mint's base directory which contains
|
||||||
|
* the mint's auditing information.
|
||||||
|
*/
|
||||||
|
#define TALER_MINTDB_DIR_AUDITORS "auditors"
|
||||||
|
|
||||||
|
|
||||||
GNUNET_NETWORK_STRUCT_BEGIN
|
GNUNET_NETWORK_STRUCT_BEGIN
|
||||||
|
|
||||||
@ -123,23 +129,6 @@ typedef int
|
|||||||
const struct TALER_MINTDB_PrivateSigningKeyInformationP *ski);
|
const struct TALER_MINTDB_PrivateSigningKeyInformationP *ski);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Iterator over denomination keys.
|
|
||||||
*
|
|
||||||
* @param cls closure
|
|
||||||
* @param dki the denomination key
|
|
||||||
* @param alias coin alias
|
|
||||||
* @return #GNUNET_OK to continue to iterate,
|
|
||||||
* #GNUNET_NO to stop iteration with no error,
|
|
||||||
* #GNUNET_SYSERR to abort iteration with error!
|
|
||||||
*/
|
|
||||||
typedef int
|
|
||||||
(*TALER_MINTDB_DenominationKeyIterator)(void *cls,
|
|
||||||
const char *alias,
|
|
||||||
const struct TALER_MINTDB_DenominationKeyIssueInformation *dki);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call @a it for each signing key found in the @a mint_base_dir.
|
* Call @a it for each signing key found in the @a mint_base_dir.
|
||||||
*
|
*
|
||||||
@ -158,6 +147,23 @@ TALER_MINTDB_signing_keys_iterate (const char *mint_base_dir,
|
|||||||
void *it_cls);
|
void *it_cls);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Iterator over denomination keys.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param dki the denomination key
|
||||||
|
* @param alias coin alias
|
||||||
|
* @return #GNUNET_OK to continue to iterate,
|
||||||
|
* #GNUNET_NO to stop iteration with no error,
|
||||||
|
* #GNUNET_SYSERR to abort iteration with error!
|
||||||
|
*/
|
||||||
|
typedef int
|
||||||
|
(*TALER_MINTDB_DenominationKeyIterator)(void *cls,
|
||||||
|
const char *alias,
|
||||||
|
const struct TALER_MINTDB_DenominationKeyIssueInformation *dki);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call @a it for each denomination key found in the @a mint_base_dir.
|
* Call @a it for each denomination key found in the @a mint_base_dir.
|
||||||
*
|
*
|
||||||
@ -201,6 +207,67 @@ TALER_MINTDB_denomination_key_read (const char *filename,
|
|||||||
struct TALER_MINTDB_DenominationKeyIssueInformation *dki);
|
struct TALER_MINTDB_DenominationKeyIssueInformation *dki);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Iterator over auditor information.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param apub the auditor's public key
|
||||||
|
* @param mpub the mint's public key (as expected by the auditor)
|
||||||
|
* @param dki_len length of @a asig and @a dki arrays
|
||||||
|
* @param asigs array of the auditor's signatures over the @a dks, of length @a dki_len
|
||||||
|
* @param dki array of denomination coin data signed by the auditor, of length @a dki_len
|
||||||
|
* @return #GNUNET_OK to continue to iterate,
|
||||||
|
* #GNUNET_NO to stop iteration with no error,
|
||||||
|
* #GNUNET_SYSERR to abort iteration with error!
|
||||||
|
*/
|
||||||
|
typedef int
|
||||||
|
(*TALER_MINTDB_AuditorIterator)(void *cls,
|
||||||
|
const struct TALER_AuditorPublicKeyP *apub,
|
||||||
|
const struct TALER_MasterPublicKeyP *mpub,
|
||||||
|
unsigned int dki_len,
|
||||||
|
const struct TALER_AuditorSignatureP *asigs,
|
||||||
|
const struct TALER_DenominationKeyValidityPS *dki);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call @a it with information for each auditor found in the @a mint_base_dir.
|
||||||
|
*
|
||||||
|
* @param mint_base_dir base directory for the mint,
|
||||||
|
* the signing keys must be in the #TALER_MINTDB_DIR_DENOMINATION_KEYS
|
||||||
|
* subdirectory
|
||||||
|
* @param it function to call with auditor information
|
||||||
|
* @param it_cls closure for @a it
|
||||||
|
* @return -1 on error, 0 if no files were found, otherwise
|
||||||
|
* a positive number (however, even with a positive
|
||||||
|
* number it is possible that @a it was never called
|
||||||
|
* as maybe none of the files were well-formed)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TALER_MINTDB_auditor_iterate (const char *mint_base_dir,
|
||||||
|
TALER_MINTDB_AuditorIterator it,
|
||||||
|
void *it_cls);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write auditor information to the given file.
|
||||||
|
*
|
||||||
|
* @param filename the file where to write the auditor information to
|
||||||
|
* @param apub the auditor's public key
|
||||||
|
* @param asigs the auditor's signatures, array of length @a dki_len
|
||||||
|
* @param mpub the mint's public key (as expected by the auditor)
|
||||||
|
* @param dki_len length of @a dki and @a asigs arrays
|
||||||
|
* @param dki array of denomination coin data signed by the auditor
|
||||||
|
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TALER_MINTDB_auditor_write (const char *filename,
|
||||||
|
const struct TALER_AuditorPublicKeyP *apub,
|
||||||
|
const struct TALER_AuditorSignatureP *asigs,
|
||||||
|
const struct TALER_MasterPublicKeyP *mpub,
|
||||||
|
unsigned int dki_len,
|
||||||
|
const struct TALER_DenominationKeyValidityPS *dki);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the plugin.
|
* Initialize the plugin.
|
||||||
*
|
*
|
||||||
|
@ -416,30 +416,6 @@ struct TALER_MINTDB_LinkDataList
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Specification for a /lock operation.
|
|
||||||
*/
|
|
||||||
struct TALER_MINTDB_LockOperation
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Information about the coin that is being locked.
|
|
||||||
*/
|
|
||||||
struct TALER_CoinPublicInfo coin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Signature over the locking operation.
|
|
||||||
*/
|
|
||||||
struct TALER_CoinSpendSignatureP coin_sig;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* How much value is being locked?
|
|
||||||
*/
|
|
||||||
struct TALER_Amount amount;
|
|
||||||
|
|
||||||
// FIXME: more needed...
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enumeration to classify the different types of transactions
|
* @brief Enumeration to classify the different types of transactions
|
||||||
* that can be done with a coin.
|
* that can be done with a coin.
|
||||||
@ -454,12 +430,8 @@ enum TALER_MINTDB_TransactionType
|
|||||||
/**
|
/**
|
||||||
* /refresh/melt operation.
|
* /refresh/melt operation.
|
||||||
*/
|
*/
|
||||||
TALER_MINTDB_TT_REFRESH_MELT = 1,
|
TALER_MINTDB_TT_REFRESH_MELT = 1
|
||||||
|
|
||||||
/**
|
|
||||||
* /lock operation.
|
|
||||||
*/
|
|
||||||
TALER_MINTDB_TT_LOCK = 2
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -495,11 +467,6 @@ struct TALER_MINTDB_TransactionList
|
|||||||
*/
|
*/
|
||||||
struct TALER_MINTDB_RefreshMelt *melt;
|
struct TALER_MINTDB_RefreshMelt *melt;
|
||||||
|
|
||||||
/**
|
|
||||||
* Details if transaction was a /lock operation.
|
|
||||||
*/
|
|
||||||
struct TALER_MINTDB_LockOperation *lock;
|
|
||||||
|
|
||||||
} details;
|
} details;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -549,6 +516,31 @@ struct TALER_MINTDB_MeltCommitment
|
|||||||
struct TALER_MINTDB_Session;
|
struct TALER_MINTDB_Session;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with details about deposits that
|
||||||
|
* have been made, with the goal of executing the
|
||||||
|
* corresponding wire transaction.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param id transaction ID (used as future `min_id` to avoid
|
||||||
|
* iterating over transactions more than once)
|
||||||
|
* @param amount_with_fee amount that was deposited including fee
|
||||||
|
* @param deposit_fee amount the mint gets to keep as transaction fees
|
||||||
|
* @param transaction_id unique transaction ID chosen by the merchant
|
||||||
|
* @param h_contract hash of the contract between merchant and customer
|
||||||
|
* @param wire wire details for the merchant
|
||||||
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
|
*/
|
||||||
|
typedef int
|
||||||
|
(*TALER_MINTDB_DepositIterator)(void *cls,
|
||||||
|
uint64_t id,
|
||||||
|
const struct TALER_Amount *amount_with_fee,
|
||||||
|
const struct TALER_Amount *deposit_fee,
|
||||||
|
uint64_t transaction_id,
|
||||||
|
const struct GNUNET_HashCode *h_contract,
|
||||||
|
const json_t *wire);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called with the session hashes and transfer secret
|
* Function called with the session hashes and transfer secret
|
||||||
* information for a given coin.
|
* information for a given coin.
|
||||||
@ -636,23 +628,24 @@ struct TALER_MINTDB_Plugin
|
|||||||
* Commit a transaction.
|
* Commit a transaction.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion connection to use
|
* @param session connection to use
|
||||||
* @return #GNUNET_OK on success
|
* @return #GNUNET_OK on success, #GNUNET_NO if the transaction
|
||||||
|
* can be retried, #GNUNET_SYSERR on hard failures
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*commit) (void *cls,
|
(*commit) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion);
|
struct TALER_MINTDB_Session *session);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abort/rollback a transaction.
|
* Abort/rollback a transaction.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion connection to use
|
* @param session connection to use
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
(*rollback) (void *cls,
|
(*rollback) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion);
|
struct TALER_MINTDB_Session *session);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -661,7 +654,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* with this key have.
|
* with this key have.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion connection to use
|
* @param session connection to use
|
||||||
* @param denom_pub the public key used for signing coins of this denomination
|
* @param denom_pub the public key used for signing coins of this denomination
|
||||||
* @param issue issuing information with value, fees and other info about the coin
|
* @param issue issuing information with value, fees and other info about the coin
|
||||||
* @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
|
* @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
|
||||||
@ -677,7 +670,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* Fetch information about a denomination key.
|
* Fetch information about a denomination key.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion connection to use
|
* @param session connection to use
|
||||||
* @param denom_pub the public key used for signing coins of this denomination
|
* @param denom_pub the public key used for signing coins of this denomination
|
||||||
* @param[out] issue set to issue information with value, fees and other info about the coin, can be NULL
|
* @param[out] issue set to issue information with value, fees and other info about the coin, can be NULL
|
||||||
* @return #GNUNET_OK on success; #GNUNET_NO if no record was found, #GNUNET_SYSERR on failure
|
* @return #GNUNET_OK on success; #GNUNET_NO if no record was found, #GNUNET_SYSERR on failure
|
||||||
@ -736,7 +729,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* key of the hash of the blinded message.
|
* key of the hash of the blinded message.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection to use
|
* @param session database connection to use
|
||||||
* @param h_blind hash of the blinded coin to be signed (will match
|
* @param h_blind hash of the blinded coin to be signed (will match
|
||||||
* `h_coin_envelope` in the @a collectable to be returned)
|
* `h_coin_envelope` in the @a collectable to be returned)
|
||||||
* @param collectable corresponding collectable coin (blind signature)
|
* @param collectable corresponding collectable coin (blind signature)
|
||||||
@ -747,7 +740,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*get_withdraw_info) (void *cls,
|
(*get_withdraw_info) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct GNUNET_HashCode *h_blind,
|
const struct GNUNET_HashCode *h_blind,
|
||||||
struct TALER_MINTDB_CollectableBlindcoin *collectable);
|
struct TALER_MINTDB_CollectableBlindcoin *collectable);
|
||||||
|
|
||||||
@ -757,7 +750,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* hash of the blinded message.
|
* hash of the blinded message.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection to use
|
* @param session database connection to use
|
||||||
* @param collectable corresponding collectable coin (blind signature)
|
* @param collectable corresponding collectable coin (blind signature)
|
||||||
* if a coin is found
|
* if a coin is found
|
||||||
* @return #GNUNET_SYSERR on internal error
|
* @return #GNUNET_SYSERR on internal error
|
||||||
@ -766,7 +759,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*insert_withdraw_info) (void *cls,
|
(*insert_withdraw_info) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct TALER_MINTDB_CollectableBlindcoin *collectable);
|
const struct TALER_MINTDB_CollectableBlindcoin *collectable);
|
||||||
|
|
||||||
|
|
||||||
@ -775,13 +768,13 @@ struct TALER_MINTDB_Plugin
|
|||||||
* reserve.
|
* reserve.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion connection to use
|
* @param session connection to use
|
||||||
* @param reserve_pub public key of the reserve
|
* @param reserve_pub public key of the reserve
|
||||||
* @return known transaction history (NULL if reserve is unknown)
|
* @return known transaction history (NULL if reserve is unknown)
|
||||||
*/
|
*/
|
||||||
struct TALER_MINTDB_ReserveHistory *
|
struct TALER_MINTDB_ReserveHistory *
|
||||||
(*get_reserve_history) (void *cls,
|
(*get_reserve_history) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub);
|
const struct TALER_ReservePublicKeyP *reserve_pub);
|
||||||
|
|
||||||
|
|
||||||
@ -800,7 +793,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* Check if we have the specified deposit already in the database.
|
* Check if we have the specified deposit already in the database.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection
|
* @param session database connection
|
||||||
* @param deposit deposit to search for
|
* @param deposit deposit to search for
|
||||||
* @return #GNUNET_YES if we know this operation,
|
* @return #GNUNET_YES if we know this operation,
|
||||||
* #GNUNET_NO if this exact deposit is unknown to us,
|
* #GNUNET_NO if this exact deposit is unknown to us,
|
||||||
@ -808,30 +801,53 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*have_deposit) (void *cls,
|
(*have_deposit) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct TALER_MINTDB_Deposit *deposit);
|
const struct TALER_MINTDB_Deposit *deposit);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert information about deposited coin into the
|
* Insert information about deposited coin into the database.
|
||||||
* database.
|
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion connection to the database
|
* @param session connection to the database
|
||||||
* @param deposit deposit information to store
|
* @param deposit deposit information to store
|
||||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*insert_deposit) (void *cls,
|
(*insert_deposit) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct TALER_MINTDB_Deposit *deposit);
|
const struct TALER_MINTDB_Deposit *deposit);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain information about deposits. Iterates over all deposits
|
||||||
|
* above a certain ID. Use a @a min_id of 0 to start at the beginning.
|
||||||
|
* This operation is executed in its own transaction in transaction
|
||||||
|
* mode "REPEATABLE READ", i.e. we should only see valid deposits.
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param session connection to the database
|
||||||
|
* @param min_id deposit to start at
|
||||||
|
* @param limit maximum number of transactions to fetch
|
||||||
|
* @param deposit_cb function to call for each deposit
|
||||||
|
* @param deposit_cb_cls closure for @a deposit_cb
|
||||||
|
* @return number of rows processed, 0 if none exist,
|
||||||
|
* #GNUNET_SYSERR on error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
(*iterate_deposits) (void *cls,
|
||||||
|
struct TALER_MINTDB_Session *session,
|
||||||
|
uint64_t min_id,
|
||||||
|
uint32_t limit,
|
||||||
|
TALER_MINTDB_DepositIterator deposit_cb,
|
||||||
|
void *deposit_cb_cls);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup refresh session data under the given @a session_hash.
|
* Lookup refresh session data under the given @a session_hash.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database handle to use
|
* @param session database handle to use
|
||||||
* @param session_hash hash over the melt to use for the lookup
|
* @param session_hash hash over the melt to use for the lookup
|
||||||
* @param[out] refresh_session where to store the result
|
* @param[out] refresh_session where to store the result
|
||||||
* @return #GNUNET_YES on success,
|
* @return #GNUNET_YES on success,
|
||||||
@ -840,7 +856,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*get_refresh_session) (void *cls,
|
(*get_refresh_session) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
struct TALER_MINTDB_RefreshSession *refresh_session);
|
struct TALER_MINTDB_RefreshSession *refresh_session);
|
||||||
|
|
||||||
@ -849,7 +865,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* Store new refresh session data under the given @a session_hash.
|
* Store new refresh session data under the given @a session_hash.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database handle to use
|
* @param session database handle to use
|
||||||
* @param session_hash hash over the melt to use to locate the session
|
* @param session_hash hash over the melt to use to locate the session
|
||||||
* @param refresh_session session data to store
|
* @param refresh_session session data to store
|
||||||
* @return #GNUNET_YES on success,
|
* @return #GNUNET_YES on success,
|
||||||
@ -857,7 +873,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*create_refresh_session) (void *cls,
|
(*create_refresh_session) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
const struct TALER_MINTDB_RefreshSession *refresh_session);
|
const struct TALER_MINTDB_RefreshSession *refresh_session);
|
||||||
|
|
||||||
@ -866,7 +882,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* Store the given /refresh/melt request in the database.
|
* Store the given /refresh/melt request in the database.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection
|
* @param session database connection
|
||||||
* @param oldcoin_index index of the coin to store
|
* @param oldcoin_index index of the coin to store
|
||||||
* @param melt coin melt operation details to store; includes
|
* @param melt coin melt operation details to store; includes
|
||||||
* the session hash of the melt
|
* the session hash of the melt
|
||||||
@ -875,7 +891,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*insert_refresh_melt) (void *cls,
|
(*insert_refresh_melt) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
uint16_t oldcoin_index,
|
uint16_t oldcoin_index,
|
||||||
const struct TALER_MINTDB_RefreshMelt *melt);
|
const struct TALER_MINTDB_RefreshMelt *melt);
|
||||||
|
|
||||||
@ -884,7 +900,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* Get information about melted coin details from the database.
|
* Get information about melted coin details from the database.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection
|
* @param session database connection
|
||||||
* @param session_hash hash to identify refresh session
|
* @param session_hash hash to identify refresh session
|
||||||
* @param oldcoin_index index of the coin to retrieve
|
* @param oldcoin_index index of the coin to retrieve
|
||||||
* @param melt melt data to fill in, can be NULL
|
* @param melt melt data to fill in, can be NULL
|
||||||
@ -893,7 +909,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*get_refresh_melt) (void *cls,
|
(*get_refresh_melt) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
uint16_t oldcoin_index,
|
uint16_t oldcoin_index,
|
||||||
struct TALER_MINTDB_RefreshMelt *melt);
|
struct TALER_MINTDB_RefreshMelt *melt);
|
||||||
@ -904,7 +920,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* in a given refresh operation.
|
* in a given refresh operation.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection
|
* @param session database connection
|
||||||
* @param session_hash hash to identify refresh session
|
* @param session_hash hash to identify refresh session
|
||||||
* @param num_newcoins number of coins to generate, size of the @a denom_pubs array
|
* @param num_newcoins number of coins to generate, size of the @a denom_pubs array
|
||||||
* @param denom_pubs array denominations of the coins to create
|
* @param denom_pubs array denominations of the coins to create
|
||||||
@ -913,7 +929,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*insert_refresh_order) (void *cls,
|
(*insert_refresh_order) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
uint16_t num_newcoins,
|
uint16_t num_newcoins,
|
||||||
const struct TALER_DenominationPublicKey *denom_pubs);
|
const struct TALER_DenominationPublicKey *denom_pubs);
|
||||||
@ -924,7 +940,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* create in the given refresh operation.
|
* create in the given refresh operation.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection
|
* @param session database connection
|
||||||
* @param session_hash hash to identify refresh session
|
* @param session_hash hash to identify refresh session
|
||||||
* @param num_newcoins size of the @a denom_pubs array
|
* @param num_newcoins size of the @a denom_pubs array
|
||||||
* @param[out] denom_pubs where to write @a num_newcoins denomination keys
|
* @param[out] denom_pubs where to write @a num_newcoins denomination keys
|
||||||
@ -933,7 +949,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*get_refresh_order) (void *cls,
|
(*get_refresh_order) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
uint16_t num_newcoins,
|
uint16_t num_newcoins,
|
||||||
struct TALER_DenominationPublicKey *denom_pubs);
|
struct TALER_DenominationPublicKey *denom_pubs);
|
||||||
@ -944,7 +960,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* for the given refresh session in the database.
|
* for the given refresh session in the database.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection to use
|
* @param session database connection to use
|
||||||
* @param session_hash hash to identify refresh session
|
* @param session_hash hash to identify refresh session
|
||||||
* @param cnc_index cut and choose index (1st dimension), relating to #TALER_CNC_KAPPA
|
* @param cnc_index cut and choose index (1st dimension), relating to #TALER_CNC_KAPPA
|
||||||
* @param num_newcoins coin index size of the @a commit_coins array
|
* @param num_newcoins coin index size of the @a commit_coins array
|
||||||
@ -954,7 +970,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*insert_refresh_commit_coins) (void *cls,
|
(*insert_refresh_commit_coins) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
uint16_t cnc_index,
|
uint16_t cnc_index,
|
||||||
uint16_t num_newcoins,
|
uint16_t num_newcoins,
|
||||||
@ -966,7 +982,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* given coin of the given refresh session from the database.
|
* given coin of the given refresh session from the database.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection to use
|
* @param session database connection to use
|
||||||
* @param session_hash hash to identify refresh session
|
* @param session_hash hash to identify refresh session
|
||||||
* @param cnc_index cut and choose set index (1st dimension)
|
* @param cnc_index cut and choose set index (1st dimension)
|
||||||
* @param num_coins size of the @a commit_coins array
|
* @param num_coins size of the @a commit_coins array
|
||||||
@ -977,7 +993,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*get_refresh_commit_coins) (void *cls,
|
(*get_refresh_commit_coins) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
uint16_t cnc_index,
|
uint16_t cnc_index,
|
||||||
uint16_t num_coins,
|
uint16_t num_coins,
|
||||||
@ -989,7 +1005,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* for the given refresh session.
|
* for the given refresh session.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection to use
|
* @param session database connection to use
|
||||||
* @param session_hash hash to identify refresh session
|
* @param session_hash hash to identify refresh session
|
||||||
* @param cnc_index cut and choose index (1st dimension), relating to #TALER_CNC_KAPPA
|
* @param cnc_index cut and choose index (1st dimension), relating to #TALER_CNC_KAPPA
|
||||||
* @param num_links size of the @a commit_link array
|
* @param num_links size of the @a commit_link array
|
||||||
@ -998,7 +1014,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*insert_refresh_commit_links) (void *cls,
|
(*insert_refresh_commit_links) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
uint16_t cnc_index,
|
uint16_t cnc_index,
|
||||||
uint16_t num_links,
|
uint16_t num_links,
|
||||||
@ -1009,7 +1025,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* for the given refresh session.
|
* for the given refresh session.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection to use
|
* @param session database connection to use
|
||||||
* @param session_hash hash to identify refresh session
|
* @param session_hash hash to identify refresh session
|
||||||
* @param cnc_index cut and choose index (1st dimension)
|
* @param cnc_index cut and choose index (1st dimension)
|
||||||
* @param num_links size of the @a links array to return
|
* @param num_links size of the @a links array to return
|
||||||
@ -1020,7 +1036,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*get_refresh_commit_links) (void *cls,
|
(*get_refresh_commit_links) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
uint16_t cnc_index,
|
uint16_t cnc_index,
|
||||||
uint16_t num_links,
|
uint16_t num_links,
|
||||||
@ -1031,14 +1047,14 @@ struct TALER_MINTDB_Plugin
|
|||||||
* Get all of the information from the given melt commit operation.
|
* Get all of the information from the given melt commit operation.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection to use
|
* @param session database connection to use
|
||||||
* @param session_hash hash to identify refresh session
|
* @param session_hash hash to identify refresh session
|
||||||
* @return NULL if the @a session_hash does not correspond to any known melt
|
* @return NULL if the @a session_hash does not correspond to any known melt
|
||||||
* operation
|
* operation
|
||||||
*/
|
*/
|
||||||
struct TALER_MINTDB_MeltCommitment *
|
struct TALER_MINTDB_MeltCommitment *
|
||||||
(*get_melt_commitment) (void *cls,
|
(*get_melt_commitment) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash);
|
const struct GNUNET_HashCode *session_hash);
|
||||||
|
|
||||||
|
|
||||||
@ -1060,7 +1076,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
* be used to try to obtain the private keys during "/refresh/link".
|
* be used to try to obtain the private keys during "/refresh/link".
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection
|
* @param session database connection
|
||||||
* @param session_hash hash to identify refresh session
|
* @param session_hash hash to identify refresh session
|
||||||
* @param newcoin_index coin index
|
* @param newcoin_index coin index
|
||||||
* @param ev_sig coin signature
|
* @param ev_sig coin signature
|
||||||
@ -1068,7 +1084,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*insert_refresh_out) (void *cls,
|
(*insert_refresh_out) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash,
|
const struct GNUNET_HashCode *session_hash,
|
||||||
uint16_t newcoin_index,
|
uint16_t newcoin_index,
|
||||||
const struct TALER_DenominationSignature *ev_sig);
|
const struct TALER_DenominationSignature *ev_sig);
|
||||||
@ -1079,13 +1095,13 @@ struct TALER_MINTDB_Plugin
|
|||||||
* information, the denomination keys and the signatures.
|
* information, the denomination keys and the signatures.
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection
|
* @param session database connection
|
||||||
* @param session_hash session to get linkage data for
|
* @param session_hash session to get linkage data for
|
||||||
* @return all known link data for the session
|
* @return all known link data for the session
|
||||||
*/
|
*/
|
||||||
struct TALER_MINTDB_LinkDataList *
|
struct TALER_MINTDB_LinkDataList *
|
||||||
(*get_link_data_list) (void *cls,
|
(*get_link_data_list) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct GNUNET_HashCode *session_hash);
|
const struct GNUNET_HashCode *session_hash);
|
||||||
|
|
||||||
|
|
||||||
@ -1108,7 +1124,7 @@ struct TALER_MINTDB_Plugin
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection
|
* @param session database connection
|
||||||
* @param coin_pub public key of the coin
|
* @param coin_pub public key of the coin
|
||||||
* @param tdc function to call for each session the coin was melted into
|
* @param tdc function to call for each session the coin was melted into
|
||||||
* @param tdc_cls closure for @a tdc
|
* @param tdc_cls closure for @a tdc
|
||||||
@ -1118,56 +1134,24 @@ struct TALER_MINTDB_Plugin
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*get_transfer) (void *cls,
|
(*get_transfer) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||||
TALER_MINTDB_TransferDataCallback tdc,
|
TALER_MINTDB_TransferDataCallback tdc,
|
||||||
void *tdc_cls);
|
void *tdc_cls);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test if the given /lock request is known to us.
|
|
||||||
*
|
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
|
||||||
* @param sesssion database connection
|
|
||||||
* @param lock lock operation
|
|
||||||
* @return #GNUNET_YES if known,
|
|
||||||
* #GNUNET_NO if not,
|
|
||||||
* #GNUNET_SYSERR on internal error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
(*have_lock) (void *cls,
|
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
|
||||||
const struct TALER_MINTDB_LockOperation *lock);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store the given /lock request in the database.
|
|
||||||
*
|
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
|
||||||
* @param sesssion database connection
|
|
||||||
* @param lock lock operation
|
|
||||||
* @return #GNUNET_OK on success
|
|
||||||
* #GNUNET_SYSERR on internal error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
(*insert_lock) (void *cls,
|
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
|
||||||
const struct TALER_MINTDB_LockOperation *lock);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compile a list of all (historic) transactions performed
|
* Compile a list of all (historic) transactions performed
|
||||||
* with the given coin (/refresh/melt and /deposit operations).
|
* with the given coin (/refresh/melt and /deposit operations).
|
||||||
*
|
*
|
||||||
* @param cls the @e cls of this struct with the plugin-specific state
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
* @param sesssion database connection
|
* @param session database connection
|
||||||
* @param coin_pub coin to investigate
|
* @param coin_pub coin to investigate
|
||||||
* @return list of transactions, NULL if coin is fresh
|
* @return list of transactions, NULL if coin is fresh
|
||||||
*/
|
*/
|
||||||
struct TALER_MINTDB_TransactionList *
|
struct TALER_MINTDB_TransactionList *
|
||||||
(*get_coin_transactions) (void *cls,
|
(*get_coin_transactions) (void *cls,
|
||||||
struct TALER_MINTDB_Session *sesssion,
|
struct TALER_MINTDB_Session *session,
|
||||||
const struct TALER_CoinSpendPublicKeyP *coin_pub);
|
const struct TALER_CoinSpendPublicKeyP *coin_pub);
|
||||||
|
|
||||||
|
|
||||||
|
@ -653,13 +653,73 @@ struct TALER_MintKeyValidityPS
|
|||||||
struct TALER_MasterPublicKeyP master;
|
struct TALER_MasterPublicKeyP master;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of hash(es) of the mint's denomination keys.
|
* Start time of the validity period for this key.
|
||||||
* Specifically, this is the hash over the
|
|
||||||
* `struct TALER_DenominationKeyValidityPS`, not just
|
|
||||||
* the public key (as the auditor needs to check against
|
|
||||||
* the correct valuations and fee structure).
|
|
||||||
*/
|
*/
|
||||||
/* struct GNUNET_HashCode h_dks; */
|
struct GNUNET_TIME_AbsoluteNBO start;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mint will sign fresh coins between @e start and this time.
|
||||||
|
* @e expire_withdraw will be somewhat larger than @e start to
|
||||||
|
* ensure a sufficiently large anonymity set, while also allowing
|
||||||
|
* the Mint to limit the financial damage in case of a key being
|
||||||
|
* compromised. Thus, mints with low volume are expected to have a
|
||||||
|
* longer withdraw period (@e expire_withdraw - @e start) than mints
|
||||||
|
* with high transaction volume. The period may also differ between
|
||||||
|
* types of coins. A mint may also have a few denomination keys
|
||||||
|
* with the same value with overlapping validity periods, to address
|
||||||
|
* issues such as clock skew.
|
||||||
|
*/
|
||||||
|
struct GNUNET_TIME_AbsoluteNBO expire_withdraw;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Coins signed with the denomination key must be spent or refreshed
|
||||||
|
* between @e start and this expiration time. After this time, the
|
||||||
|
* mint will refuse transactions involving this key as it will
|
||||||
|
* "drop" the table with double-spending information (shortly after)
|
||||||
|
* this time. Note that wallets should refresh coins significantly
|
||||||
|
* before this time to be on the safe side. @e expire_spend must be
|
||||||
|
* significantly larger than @e expire_withdraw (by months or even
|
||||||
|
* years).
|
||||||
|
*/
|
||||||
|
struct GNUNET_TIME_AbsoluteNBO expire_spend;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When do signatures with this denomination key become invalid?
|
||||||
|
* After this point, these signatures cannot be used in (legal)
|
||||||
|
* disputes anymore, as the Mint is then allowed to destroy its side
|
||||||
|
* of the evidence. @e expire_legal is expected to be significantly
|
||||||
|
* larger than @e expire_spend (by a year or more).
|
||||||
|
*/
|
||||||
|
struct GNUNET_TIME_AbsoluteNBO expire_legal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value of the coins signed with this denomination key.
|
||||||
|
*/
|
||||||
|
struct TALER_AmountNBO value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fee the mint charges when a coin of this type is withdrawn.
|
||||||
|
* (can be zero).
|
||||||
|
*/
|
||||||
|
struct TALER_AmountNBO fee_withdraw;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fee the mint charges when a coin of this type is deposited.
|
||||||
|
* (can be zero).
|
||||||
|
*/
|
||||||
|
struct TALER_AmountNBO fee_deposit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fee the mint charges when a coin of this type is refreshed.
|
||||||
|
* (can be zero).
|
||||||
|
*/
|
||||||
|
struct TALER_AmountNBO fee_refresh;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash code of the denomination public key. (Used to avoid having
|
||||||
|
* the variable-size RSA key in this struct.)
|
||||||
|
*/
|
||||||
|
struct GNUNET_HashCode denom_hash GNUNET_PACKED;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,7 +22,8 @@ libtalermint_la_SOURCES = \
|
|||||||
mint_api_deposit.c \
|
mint_api_deposit.c \
|
||||||
mint_api_refresh.c \
|
mint_api_refresh.c \
|
||||||
mint_api_refresh_link.c \
|
mint_api_refresh_link.c \
|
||||||
mint_api_withdraw.c
|
mint_api_reserve.c \
|
||||||
|
mint_api_wire.c
|
||||||
|
|
||||||
libtalermint_la_LIBADD = \
|
libtalermint_la_LIBADD = \
|
||||||
-lgnunetutil \
|
-lgnunetutil \
|
||||||
|
34
src/mint-lib/afl-generate.sh
Normal file
34
src/mint-lib/afl-generate.sh
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# This file is part of TALER
|
||||||
|
# Copyright (C) 2015 GNUnet e.V.
|
||||||
|
#
|
||||||
|
# TALER is free software; you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License along with
|
||||||
|
# TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# This will generate testcases in a directory 'afl-tests', which can then
|
||||||
|
# be moved into src/mint/afl-tests/ to be run during mint-testing.
|
||||||
|
#
|
||||||
|
# This script uses American Fuzzy Loop (AFL) to fuzz the mint to
|
||||||
|
# automatically create tests with good coverage. You must install
|
||||||
|
# AFL and set AFL_HOME to the directory where AFL is installed
|
||||||
|
# before running. Also, a directory "baseline/" should exist with
|
||||||
|
# templates for inputs for AFL to fuzz. These can be generated
|
||||||
|
# by running wireshark on loopback while running 'make check' in
|
||||||
|
# this directory. Save each HTTP request to a new file.
|
||||||
|
#
|
||||||
|
# Note that you want to switch 'TESTRUN = NO' and pre-init the
|
||||||
|
# database before running this, otherwise it will be awfully slow.
|
||||||
|
#
|
||||||
|
# Must be run from this directory.
|
||||||
|
#
|
||||||
|
$AFL_HOME/afl-fuzz -i baseline/ -m 250 -o afl-tests/ -f /tmp/afl-input taler-mint-httpd -f /tmp/afl-input -d test-mint-home/ -C
|
7
src/mint-lib/baseline/admin_add_incoming.req
Normal file
7
src/mint-lib/baseline/admin_add_incoming.req
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
8
src/mint-lib/baseline/deposit.req
Normal file
8
src/mint-lib/baseline/deposit.req
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
POST /deposit HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 1658
|
||||||
|
Expect: 100-continue
|
||||||
|
|
||||||
|
{"ub_sig":"51SPJSSDESGPR80A40M74WV140520818ECG26E9M8S0M6CSH6X334GSN8RW30D9G8MT46CA660W34GSG6MT4AD9K8GT3ECSH6MVK0E2374V38H1M8MR4CDJ66MWK4E1S6MR3GCT28CV32H1Q8N23GCHG70S36C1K8MS3GCSN8RV36D9S710KGD9K6GWKEGJ28GRM4CJ56X1K6DJ18D2KGHA46D13GDA66GVK4GHJ8N13AE9J8RVK6GT184S48E1K6X336G9Q8N142CJ4692M6EA16GRKJD9N6523ADA36X13GG9G70TK6DHN68R36CT18GR4CDSJ6CW3GCT364W46CSR8RV42GJ474SMADSH851K4H9Q8GS42CHS8RV3GCSJ64V46DSN8RSM6HHN6N246D9S6934AH9P6X23JGSH652K0DJ5612KJGA26N242CH35452081918G2J2G0","timestamp":"/Date(1442821652)/","f":{"currency":"EUR","value":5,"fraction":0},"wire":{"type":"TEST","bank":"dest bank","account":42},"coin_pub":"JXWK4NS0H2W4V4BETQ90CCEDADP6QQ3MV3YZ7RV2KXEM8PWXE8Q0","H_wire":"YQED9FDYPKK2QQYB3FS19Y15ZMKBAXJP2C73CXASAF1KM6ZYY723TEJ3HBR6D864A7X5W58G92QJ0A9PFMZNB81ZP9NJAQQCCABM4RG","H_contract":"1CMEEFQ5S4QJGGAMVYFV07XQRHQA311CR2MTRNC5M9KZV6ETDV1SY00WJFEV2CG9BXQTEQPZAF8A54C2HX32TZCN20VBGPFPS2Z16B0","merchant_pub":"C36TEXQXFW00170C2EJ66ZR0000CX9VPZNZG00109NX020000000","denom_pub":"51R7ARKCD5HJTTV5F4G0M818E9SP280A40G2GVH04CR30GT58S2K2HJ16H336C9N8CVK4E9N6H1MADHH61330HHM6N1K8E1H8RVKJH256D1M6E1K8RWKJGSH8S2M6DJ170TK2H266GTK8DSS64RKJDJ26D144DJ474SK0GHQ711MAD9G752M2CJ58S1KJDA570SK2E9G8N23GCJ28S146DHH610K2H1Q8CW3GGA16S146H9G68TKACSQ6914CE1H691K2E9N6RWM8H9P8CWM2H9S8GSK0H9P6D1K6H9G6X0M4C2171144HJ46N334H9J692M4H9M8MR4CCJ46GRKEGA46533CDJ38MV4CH9K892MAH1P8S2K6D9K6N246E256H244G9Q6D346GJ56S23JGHJ690KADHJ8H242H2575132CSM6X1M4G9N6RR48E9H8MVM8E9354520818CMG26C1H60R30C935452081918G2J2G0","transaction_id":1,"refund_deadline":"/Date(0)/","coin_sig":"X16E0DP8C2BJNVNX09G24FFC5GA4W7RN2YXZP9WJTAN9BY6B4GMA39QNYR51XNNEZ3H1J7TP0K9G55JZ8V7WS7CZMD7E64HWYBFWM00"}
|
7
src/mint-lib/baseline/keys.req
Normal file
7
src/mint-lib/baseline/keys.req
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
GET /keys HTTP/1.1
|
||||||
|
User-Agent: Wget/1.16.3 (linux-gnu)
|
||||||
|
Accept: */*
|
||||||
|
Accept-Encoding: identity
|
||||||
|
Host: 127.0.0.1:8081
|
||||||
|
Connection: Keep-Alive
|
||||||
|
|
5
src/mint-lib/baseline/refresh_link.req
Normal file
5
src/mint-lib/baseline/refresh_link.req
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
GET /refresh/link?coin_pub=WQHES0X5XK43VBG1Y8FXR2YEJM04HQVMDTCS07MH691XWADG8QCG HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
|
8
src/mint-lib/baseline/refresh_melt.req
Normal file
8
src/mint-lib/baseline/refresh_melt.req
Normal file
File diff suppressed because one or more lines are too long
7
src/mint-lib/baseline/refresh_reveal.req
Normal file
7
src/mint-lib/baseline/refresh_reveal.req
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
POST /refresh/reveal HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 255
|
||||||
|
|
||||||
|
{"session_hash":"V97SB8T670M9V71D1Q0KVQ4GSJCVQ5AAKTTH9QKT0ZJZZBFNZAV4NA8NMWRRGVPFEBEGB6ANCN9BPQASJ40TM4Y1C49648TJJ07PGSG","transfer_privs":[["EQKJA401A9NJ2YJDFZJ1EV8AYXBHWZB6NT5T0TWSJHVKVDM6W8A0"],["TKDJ4DF3GZVG0DGAB9E3RGBGSTANYB6JVVWXJGPMB2AY4VQNTBA0"]]}
|
4
src/mint-lib/baseline/reserve_status.req
Normal file
4
src/mint-lib/baseline/reserve_status.req
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
GET /reserve/status?reserve_pub=TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0 HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
|
7
src/mint-lib/baseline/reserve_withdraw.req
Normal file
7
src/mint-lib/baseline/reserve_withdraw.req
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
POST /reserve/withdraw HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 919
|
||||||
|
|
||||||
|
{"coin_ev":"Q5X8A8TCBFH7E5BMY7HSB17SHFTM1JPJGV61P2CA7Z9EXG8P2HYS69B31NZESKXHSZHNJ2DQN3CC2AWFNC6V90J577JD3TXBMAY8Y5M9V60KKT73Z1DW24JFSNAK91G1F2WT55ADP1EG7N5F9AY7A7ZJD03MPYSH0RDP7SVZS2KRPA5JRHFR4GDJ59CFNE7A43M95ZKQHQAS8","denom_pub":"51R7ARKCD5HJTTV5F4G0M818E9SP280A40G2GVH04CR30GT58S2K2HJ16H336C9N8CVK4E9N6H1MADHH61330HHM6N1K8E1H8RVKJH256D1M6E1K8RWKJGSH8S2M6DJ170TK2H266GTK8DSS64RKJDJ26D144DJ474SK0GHQ711MAD9G752M2CJ58S1KJDA570SK2E9G8N23GCJ28S146DHH610K2H1Q8CW3GGA16S146H9G68TKACSQ6914CE1H691K2E9N6RWM8H9P8CWM2H9S8GSK0H9P6D1K6H9G6X0M4C2171144HJ46N334H9J692M4H9M8MR4CCJ46GRKEGA46533CDJ38MV4CH9K892MAH1P8S2K6D9K6N246E256H244G9Q6D346GJ56S23JGHJ690KADHJ8H242H2575132CSM6X1M4G9N6RR48E9H8MVM8E9354520818CMG26C1H60R30C935452081918G2J2G0","reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","reserve_sig":"8427B3RTB217124EB1C37ZVJFC08KN17RHGHE9ENZQMQVJ0S11SAX6H8Z06SWCKT06DRQ9DQ8XD786XKQ94T27PYR9GC9EMT1Y02W10"}
|
5
src/mint-lib/baseline/wire.req
Normal file
5
src/mint-lib/baseline/wire.req
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
GET /wire HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
|
5
src/mint-lib/baseline/wire_sepa.req
Normal file
5
src/mint-lib/baseline/wire_sepa.req
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
GET /wire/sepa HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
|
5
src/mint-lib/baseline/wire_test.req
Normal file
5
src/mint-lib/baseline/wire_test.req
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
GET /wire/test HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
|
@ -435,6 +435,29 @@ MAC_download_get_result (struct MAC_DownloadBuffer *db,
|
|||||||
{
|
{
|
||||||
json_t *json;
|
json_t *json;
|
||||||
json_error_t error;
|
json_error_t error;
|
||||||
|
char *ct;
|
||||||
|
|
||||||
|
if ( (CURLE_OK !=
|
||||||
|
curl_easy_getinfo (eh,
|
||||||
|
CURLINFO_CONTENT_TYPE,
|
||||||
|
&ct)) ||
|
||||||
|
(NULL == ct) ||
|
||||||
|
(0 != strcasecmp (ct,
|
||||||
|
"application/json")) )
|
||||||
|
{
|
||||||
|
/* No content type or explicitly not JSON, refuse to parse
|
||||||
|
(but keep response code) */
|
||||||
|
if (CURLE_OK !=
|
||||||
|
curl_easy_getinfo (eh,
|
||||||
|
CURLINFO_RESPONSE_CODE,
|
||||||
|
response_code))
|
||||||
|
{
|
||||||
|
/* unexpected error... */
|
||||||
|
GNUNET_break (0);
|
||||||
|
*response_code = 0;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
json = NULL;
|
json = NULL;
|
||||||
if (0 == db->eno)
|
if (0 == db->eno)
|
||||||
|
@ -325,9 +325,11 @@ parse_json_denomkey (struct TALER_MINT_DenomPublicKey *denom_key,
|
|||||||
&denom_key_issue.denom_hash,
|
&denom_key_issue.denom_hash,
|
||||||
sizeof (struct GNUNET_HashCode));
|
sizeof (struct GNUNET_HashCode));
|
||||||
denom_key->key.rsa_public_key = pk;
|
denom_key->key.rsa_public_key = pk;
|
||||||
|
denom_key->h_key = denom_key_issue.denom_hash;
|
||||||
denom_key->valid_from = valid_from;
|
denom_key->valid_from = valid_from;
|
||||||
denom_key->withdraw_valid_until = withdraw_valid_until;
|
denom_key->withdraw_valid_until = withdraw_valid_until;
|
||||||
denom_key->deposit_valid_until = deposit_valid_until;
|
denom_key->deposit_valid_until = deposit_valid_until;
|
||||||
|
denom_key->expire_legal = expire_legal;
|
||||||
denom_key->value = value;
|
denom_key->value = value;
|
||||||
denom_key->fee_withdraw = fee_withdraw;
|
denom_key->fee_withdraw = fee_withdraw;
|
||||||
denom_key->fee_deposit = fee_deposit;
|
denom_key->fee_deposit = fee_deposit;
|
||||||
@ -340,6 +342,116 @@ parse_json_denomkey (struct TALER_MINT_DenomPublicKey *denom_key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a mint's auditor information encoded in JSON.
|
||||||
|
*
|
||||||
|
* @param[out] auditor where to return the result
|
||||||
|
* @param[in] auditor_obj json to parse
|
||||||
|
* @param key_data information about denomination keys
|
||||||
|
* @return #GNUNET_OK if all is fine, #GNUNET_SYSERR if the signature is
|
||||||
|
* invalid or the json malformed.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
parse_json_auditor (struct TALER_MINT_AuditorInformation *auditor,
|
||||||
|
json_t *auditor_obj,
|
||||||
|
const struct TALER_MINT_Keys *key_data)
|
||||||
|
{
|
||||||
|
json_t *keys;
|
||||||
|
json_t *key;
|
||||||
|
unsigned int len;
|
||||||
|
unsigned int off;
|
||||||
|
unsigned int i;
|
||||||
|
struct TALER_MintKeyValidityPS kv;
|
||||||
|
struct MAJ_Specification spec[] = {
|
||||||
|
MAJ_spec_fixed_auto ("auditor_pub",
|
||||||
|
&auditor->auditor_pub),
|
||||||
|
MAJ_spec_json ("denomination_keys",
|
||||||
|
&keys),
|
||||||
|
MAJ_spec_end
|
||||||
|
};
|
||||||
|
|
||||||
|
auditor->auditor_url = NULL; /* #3987 */
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
MAJ_parse_json (auditor_obj,
|
||||||
|
spec))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
kv.purpose.purpose = htonl (TALER_SIGNATURE_AUDITOR_MINT_KEYS);
|
||||||
|
kv.purpose.size = htonl (sizeof (struct TALER_MintKeyValidityPS));
|
||||||
|
kv.master = key_data->master_pub;
|
||||||
|
len = json_array_size (keys);
|
||||||
|
auditor->denom_keys = GNUNET_new_array (len,
|
||||||
|
const struct TALER_MINT_DenomPublicKey *);
|
||||||
|
i = 0;
|
||||||
|
off = 0;
|
||||||
|
json_array_foreach (keys, i, key) {
|
||||||
|
struct TALER_AuditorSignatureP auditor_sig;
|
||||||
|
struct GNUNET_HashCode denom_h;
|
||||||
|
const struct TALER_MINT_DenomPublicKey *dk;
|
||||||
|
unsigned int j;
|
||||||
|
struct MAJ_Specification spec[] = {
|
||||||
|
MAJ_spec_fixed_auto ("denom_pub_h",
|
||||||
|
&denom_h),
|
||||||
|
MAJ_spec_fixed_auto ("auditor_sig",
|
||||||
|
&auditor_sig),
|
||||||
|
MAJ_spec_end
|
||||||
|
};
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
MAJ_parse_json (key,
|
||||||
|
spec))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dk = NULL;
|
||||||
|
for (j=0;j<key_data->num_denom_keys;j++)
|
||||||
|
{
|
||||||
|
if (0 == memcmp (&denom_h,
|
||||||
|
&key_data->denom_keys[j].h_key,
|
||||||
|
sizeof (struct GNUNET_HashCode)))
|
||||||
|
{
|
||||||
|
dk = &key_data->denom_keys[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NULL == dk)
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
kv.start = GNUNET_TIME_absolute_hton (dk->valid_from);
|
||||||
|
kv.expire_withdraw = GNUNET_TIME_absolute_hton (dk->withdraw_valid_until);
|
||||||
|
kv.expire_spend = GNUNET_TIME_absolute_hton (dk->deposit_valid_until);
|
||||||
|
kv.expire_legal = GNUNET_TIME_absolute_hton (dk->expire_legal);
|
||||||
|
TALER_amount_hton (&kv.value,
|
||||||
|
&dk->value);
|
||||||
|
TALER_amount_hton (&kv.fee_withdraw,
|
||||||
|
&dk->fee_withdraw);
|
||||||
|
TALER_amount_hton (&kv.fee_deposit,
|
||||||
|
&dk->fee_deposit);
|
||||||
|
TALER_amount_hton (&kv.fee_refresh,
|
||||||
|
&dk->fee_refresh);
|
||||||
|
kv.denom_hash = dk->h_key;
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_AUDITOR_MINT_KEYS,
|
||||||
|
&kv.purpose,
|
||||||
|
&auditor_sig.eddsa_sig,
|
||||||
|
&auditor->auditor_pub.eddsa_pub))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auditor->denom_keys[off] = dk;
|
||||||
|
off++;
|
||||||
|
}
|
||||||
|
auditor->num_denom_keys = off;
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode the JSON in @a resp_obj from the /keys response and store the data
|
* Decode the JSON in @a resp_obj from the /keys response and store the data
|
||||||
* in the @a key_data.
|
* in the @a key_data.
|
||||||
@ -394,8 +506,8 @@ decode_keys_json (json_t *resp_obj,
|
|||||||
EXITIF (0 == (key_data->num_sign_keys =
|
EXITIF (0 == (key_data->num_sign_keys =
|
||||||
json_array_size (sign_keys_array)));
|
json_array_size (sign_keys_array)));
|
||||||
key_data->sign_keys
|
key_data->sign_keys
|
||||||
= GNUNET_malloc (sizeof (struct TALER_MINT_SigningPublicKey)
|
= GNUNET_new_array (key_data->num_sign_keys,
|
||||||
* key_data->num_sign_keys);
|
struct TALER_MINT_SigningPublicKey);
|
||||||
index = 0;
|
index = 0;
|
||||||
json_array_foreach (sign_keys_array, index, sign_key_obj) {
|
json_array_foreach (sign_keys_array, index, sign_key_obj) {
|
||||||
EXITIF (GNUNET_SYSERR ==
|
EXITIF (GNUNET_SYSERR ==
|
||||||
@ -415,8 +527,8 @@ decode_keys_json (json_t *resp_obj,
|
|||||||
json_object_get (resp_obj, "denoms")));
|
json_object_get (resp_obj, "denoms")));
|
||||||
EXITIF (JSON_ARRAY != json_typeof (denom_keys_array));
|
EXITIF (JSON_ARRAY != json_typeof (denom_keys_array));
|
||||||
EXITIF (0 == (key_data->num_denom_keys = json_array_size (denom_keys_array)));
|
EXITIF (0 == (key_data->num_denom_keys = json_array_size (denom_keys_array)));
|
||||||
key_data->denom_keys = GNUNET_malloc (sizeof (struct TALER_MINT_DenomPublicKey)
|
key_data->denom_keys = GNUNET_new_array (key_data->num_denom_keys,
|
||||||
* key_data->num_denom_keys);
|
struct TALER_MINT_DenomPublicKey);
|
||||||
index = 0;
|
index = 0;
|
||||||
json_array_foreach (denom_keys_array, index, denom_key_obj) {
|
json_array_foreach (denom_keys_array, index, denom_key_obj) {
|
||||||
EXITIF (GNUNET_SYSERR ==
|
EXITIF (GNUNET_SYSERR ==
|
||||||
@ -427,7 +539,30 @@ decode_keys_json (json_t *resp_obj,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: parse the auditor keys (#3847) */
|
/* parse the auditor information */
|
||||||
|
{
|
||||||
|
json_t *auditors_array;
|
||||||
|
json_t *auditor_info;
|
||||||
|
unsigned int len;
|
||||||
|
unsigned int index;
|
||||||
|
|
||||||
|
EXITIF (NULL == (auditors_array =
|
||||||
|
json_object_get (resp_obj, "auditors")));
|
||||||
|
EXITIF (JSON_ARRAY != json_typeof (auditors_array));
|
||||||
|
len = json_array_size (auditors_array);
|
||||||
|
if (0 != len)
|
||||||
|
{
|
||||||
|
key_data->auditors = GNUNET_new_array (len,
|
||||||
|
struct TALER_MINT_AuditorInformation);
|
||||||
|
index = 0;
|
||||||
|
json_array_foreach (auditors_array, index, auditor_info) {
|
||||||
|
EXITIF (GNUNET_SYSERR ==
|
||||||
|
parse_json_auditor (&key_data->auditors[index],
|
||||||
|
auditor_info,
|
||||||
|
key_data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Validate signature... */
|
/* Validate signature... */
|
||||||
ks.purpose.size = htonl (sizeof (ks));
|
ks.purpose.size = htonl (sizeof (ks));
|
||||||
@ -551,7 +686,7 @@ MAH_handle_is_ready (struct TALER_MINT_Handle *h)
|
|||||||
* Obtain the URL to use for an API request.
|
* Obtain the URL to use for an API request.
|
||||||
*
|
*
|
||||||
* @param h the mint handle to query
|
* @param h the mint handle to query
|
||||||
* @param path Taler API path (i.e. "/withdraw/sign")
|
* @param path Taler API path (i.e. "/reserve/withdraw")
|
||||||
* @return the full URI to use with cURL
|
* @return the full URI to use with cURL
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
@ -708,6 +843,28 @@ TALER_MINT_get_denomination_key (const struct TALER_MINT_Keys *keys,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the denomination key details from the mint.
|
||||||
|
*
|
||||||
|
* @param keys the mint's key set
|
||||||
|
* @param hc hash of the public key of the denomination to lookup
|
||||||
|
* @return details about the given denomination key
|
||||||
|
*/
|
||||||
|
const struct TALER_MINT_DenomPublicKey *
|
||||||
|
TALER_MINT_get_denomination_key_by_hash (const struct TALER_MINT_Keys *keys,
|
||||||
|
const struct GNUNET_HashCode *hc)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i=0;i<keys->num_denom_keys;i++)
|
||||||
|
if (0 == memcmp (hc,
|
||||||
|
&keys->denom_keys[i].h_key,
|
||||||
|
sizeof (struct GNUNET_HashCode)))
|
||||||
|
return &keys->denom_keys[i];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the keys from the mint.
|
* Obtain the keys from the mint.
|
||||||
*
|
*
|
||||||
|
@ -48,7 +48,7 @@ MAH_handle_is_ready (struct TALER_MINT_Handle *h);
|
|||||||
* Obtain the URL to use for an API request.
|
* Obtain the URL to use for an API request.
|
||||||
*
|
*
|
||||||
* @param h the mint handle to query
|
* @param h the mint handle to query
|
||||||
* @param path Taler API path (i.e. "/withdraw/sign")
|
* @param path Taler API path (i.e. "/reserve/withdraw")
|
||||||
* @return the full URI to use with cURL
|
* @return the full URI to use with cURL
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
<http://www.gnu.org/licenses/>
|
<http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* @file mint-lib/mint_api_withdraw.c
|
* @file mint-lib/mint_api_reserve.c
|
||||||
* @brief Implementation of the /withdraw requests of the mint's HTTP API
|
* @brief Implementation of the /reserve requests of the mint's HTTP API
|
||||||
* @author Christian Grothoff
|
* @author Christian Grothoff
|
||||||
*/
|
*/
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
@ -31,12 +31,12 @@
|
|||||||
#include "taler_signatures.h"
|
#include "taler_signatures.h"
|
||||||
|
|
||||||
|
|
||||||
/* ********************** /withdraw/status ********************** */
|
/* ********************** /reserve/status ********************** */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A Withdraw Status Handle
|
* @brief A Withdraw Status Handle
|
||||||
*/
|
*/
|
||||||
struct TALER_MINT_WithdrawStatusHandle
|
struct TALER_MINT_ReserveStatusHandle
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,7 +57,7 @@ struct TALER_MINT_WithdrawStatusHandle
|
|||||||
/**
|
/**
|
||||||
* Function to call with the result.
|
* Function to call with the result.
|
||||||
*/
|
*/
|
||||||
TALER_MINT_WithdrawStatusResultCallback cb;
|
TALER_MINT_ReserveStatusResultCallback cb;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public key of the reserve we are querying.
|
* Public key of the reserve we are querying.
|
||||||
@ -264,16 +264,16 @@ parse_reserve_history (json_t *history,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called when we're done processing the
|
* Function called when we're done processing the
|
||||||
* HTTP /withdraw/status request.
|
* HTTP /reserve/status request.
|
||||||
*
|
*
|
||||||
* @param cls the `struct TALER_MINT_WithdrawStatusHandle`
|
* @param cls the `struct TALER_MINT_ReserveStatusHandle`
|
||||||
* @param eh curl handle of the request that finished
|
* @param eh curl handle of the request that finished
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
handle_withdraw_status_finished (void *cls,
|
handle_reserve_status_finished (void *cls,
|
||||||
CURL *eh)
|
CURL *eh)
|
||||||
{
|
{
|
||||||
struct TALER_MINT_WithdrawStatusHandle *wsh = cls;
|
struct TALER_MINT_ReserveStatusHandle *wsh = cls;
|
||||||
long response_code;
|
long response_code;
|
||||||
json_t *json;
|
json_t *json;
|
||||||
|
|
||||||
@ -376,7 +376,7 @@ handle_withdraw_status_finished (void *cls,
|
|||||||
NULL,
|
NULL,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
json_decref (json);
|
json_decref (json);
|
||||||
TALER_MINT_withdraw_status_cancel (wsh);
|
TALER_MINT_reserve_status_cancel (wsh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -396,13 +396,13 @@ handle_withdraw_status_finished (void *cls,
|
|||||||
* @return a handle for this request; NULL if the inputs are invalid (i.e.
|
* @return a handle for this request; NULL if the inputs are invalid (i.e.
|
||||||
* signatures fail to verify). In this case, the callback is not called.
|
* signatures fail to verify). In this case, the callback is not called.
|
||||||
*/
|
*/
|
||||||
struct TALER_MINT_WithdrawStatusHandle *
|
struct TALER_MINT_ReserveStatusHandle *
|
||||||
TALER_MINT_withdraw_status (struct TALER_MINT_Handle *mint,
|
TALER_MINT_reserve_status (struct TALER_MINT_Handle *mint,
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
TALER_MINT_WithdrawStatusResultCallback cb,
|
TALER_MINT_ReserveStatusResultCallback cb,
|
||||||
void *cb_cls)
|
void *cb_cls)
|
||||||
{
|
{
|
||||||
struct TALER_MINT_WithdrawStatusHandle *wsh;
|
struct TALER_MINT_ReserveStatusHandle *wsh;
|
||||||
struct TALER_MINT_Context *ctx;
|
struct TALER_MINT_Context *ctx;
|
||||||
CURL *eh;
|
CURL *eh;
|
||||||
char *pub_str;
|
char *pub_str;
|
||||||
@ -417,10 +417,10 @@ TALER_MINT_withdraw_status (struct TALER_MINT_Handle *mint,
|
|||||||
pub_str = GNUNET_STRINGS_data_to_string_alloc (reserve_pub,
|
pub_str = GNUNET_STRINGS_data_to_string_alloc (reserve_pub,
|
||||||
sizeof (struct TALER_ReservePublicKeyP));
|
sizeof (struct TALER_ReservePublicKeyP));
|
||||||
GNUNET_asprintf (&arg_str,
|
GNUNET_asprintf (&arg_str,
|
||||||
"/withdraw/status?reserve_pub=%s",
|
"/reserve/status?reserve_pub=%s",
|
||||||
pub_str);
|
pub_str);
|
||||||
GNUNET_free (pub_str);
|
GNUNET_free (pub_str);
|
||||||
wsh = GNUNET_new (struct TALER_MINT_WithdrawStatusHandle);
|
wsh = GNUNET_new (struct TALER_MINT_ReserveStatusHandle);
|
||||||
wsh->mint = mint;
|
wsh->mint = mint;
|
||||||
wsh->cb = cb;
|
wsh->cb = cb;
|
||||||
wsh->cb_cls = cb_cls;
|
wsh->cb_cls = cb_cls;
|
||||||
@ -446,7 +446,7 @@ TALER_MINT_withdraw_status (struct TALER_MINT_Handle *mint,
|
|||||||
wsh->job = MAC_job_add (ctx,
|
wsh->job = MAC_job_add (ctx,
|
||||||
eh,
|
eh,
|
||||||
GNUNET_NO,
|
GNUNET_NO,
|
||||||
&handle_withdraw_status_finished,
|
&handle_reserve_status_finished,
|
||||||
wsh);
|
wsh);
|
||||||
return wsh;
|
return wsh;
|
||||||
}
|
}
|
||||||
@ -459,7 +459,7 @@ TALER_MINT_withdraw_status (struct TALER_MINT_Handle *mint,
|
|||||||
* @param wsh the withdraw status request handle
|
* @param wsh the withdraw status request handle
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TALER_MINT_withdraw_status_cancel (struct TALER_MINT_WithdrawStatusHandle *wsh)
|
TALER_MINT_reserve_status_cancel (struct TALER_MINT_ReserveStatusHandle *wsh)
|
||||||
{
|
{
|
||||||
if (NULL != wsh->job)
|
if (NULL != wsh->job)
|
||||||
{
|
{
|
||||||
@ -472,12 +472,12 @@ TALER_MINT_withdraw_status_cancel (struct TALER_MINT_WithdrawStatusHandle *wsh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ********************** /withdraw/sign ********************** */
|
/* ********************** /reserve/withdraw ********************** */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A Withdraw Sign Handle
|
* @brief A Withdraw Sign Handle
|
||||||
*/
|
*/
|
||||||
struct TALER_MINT_WithdrawSignHandle
|
struct TALER_MINT_ReserveWithdrawHandle
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -503,7 +503,7 @@ struct TALER_MINT_WithdrawSignHandle
|
|||||||
/**
|
/**
|
||||||
* Function to call with the result.
|
* Function to call with the result.
|
||||||
*/
|
*/
|
||||||
TALER_MINT_WithdrawSignResultCallback cb;
|
TALER_MINT_ReserveWithdrawResultCallback cb;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key used to blind the value.
|
* Key used to blind the value.
|
||||||
@ -539,7 +539,7 @@ struct TALER_MINT_WithdrawSignHandle
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We got a 200 OK response for the /withdraw/sign operation.
|
* We got a 200 OK response for the /reserve/withdraw operation.
|
||||||
* Extract the coin's signature and return it to the caller.
|
* Extract the coin's signature and return it to the caller.
|
||||||
* The signature we get from the mint is for the blinded value.
|
* The signature we get from the mint is for the blinded value.
|
||||||
* Thus, we first must unblind it and then should verify its
|
* Thus, we first must unblind it and then should verify its
|
||||||
@ -553,7 +553,7 @@ struct TALER_MINT_WithdrawSignHandle
|
|||||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
|
* @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
withdraw_sign_ok (struct TALER_MINT_WithdrawSignHandle *wsh,
|
reserve_withdraw_ok (struct TALER_MINT_ReserveWithdrawHandle *wsh,
|
||||||
json_t *json)
|
json_t *json)
|
||||||
{
|
{
|
||||||
struct GNUNET_CRYPTO_rsa_Signature *blind_sig;
|
struct GNUNET_CRYPTO_rsa_Signature *blind_sig;
|
||||||
@ -598,7 +598,7 @@ withdraw_sign_ok (struct TALER_MINT_WithdrawSignHandle *wsh,
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We got a 402 PAYMENT REQUIRED response for the /withdraw/sign operation.
|
* We got a 402 PAYMENT REQUIRED response for the /reserve/withdraw operation.
|
||||||
* Check the signatures on the withdraw transactions in the provided
|
* Check the signatures on the withdraw transactions in the provided
|
||||||
* history and that the balances add up. We don't do anything directly
|
* history and that the balances add up. We don't do anything directly
|
||||||
* with the information, as the JSON will be returned to the application.
|
* with the information, as the JSON will be returned to the application.
|
||||||
@ -610,7 +610,7 @@ withdraw_sign_ok (struct TALER_MINT_WithdrawSignHandle *wsh,
|
|||||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
|
* @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
withdraw_sign_payment_required (struct TALER_MINT_WithdrawSignHandle *wsh,
|
reserve_withdraw_payment_required (struct TALER_MINT_ReserveWithdrawHandle *wsh,
|
||||||
json_t *json)
|
json_t *json)
|
||||||
{
|
{
|
||||||
struct TALER_Amount balance;
|
struct TALER_Amount balance;
|
||||||
@ -690,16 +690,16 @@ withdraw_sign_payment_required (struct TALER_MINT_WithdrawSignHandle *wsh,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called when we're done processing the
|
* Function called when we're done processing the
|
||||||
* HTTP /withdraw/sign request.
|
* HTTP /reserve/withdraw request.
|
||||||
*
|
*
|
||||||
* @param cls the `struct TALER_MINT_WithdrawSignHandle`
|
* @param cls the `struct TALER_MINT_ReserveWithdrawHandle`
|
||||||
* @param eh curl handle of the request that finished
|
* @param eh curl handle of the request that finished
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
handle_withdraw_sign_finished (void *cls,
|
handle_reserve_withdraw_finished (void *cls,
|
||||||
CURL *eh)
|
CURL *eh)
|
||||||
{
|
{
|
||||||
struct TALER_MINT_WithdrawSignHandle *wsh = cls;
|
struct TALER_MINT_ReserveWithdrawHandle *wsh = cls;
|
||||||
long response_code;
|
long response_code;
|
||||||
json_t *json;
|
json_t *json;
|
||||||
|
|
||||||
@ -713,7 +713,7 @@ handle_withdraw_sign_finished (void *cls,
|
|||||||
break;
|
break;
|
||||||
case MHD_HTTP_OK:
|
case MHD_HTTP_OK:
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
withdraw_sign_ok (wsh,
|
reserve_withdraw_ok (wsh,
|
||||||
json))
|
json))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
@ -728,7 +728,7 @@ handle_withdraw_sign_finished (void *cls,
|
|||||||
/* The mint says that the reserve has insufficient funds;
|
/* The mint says that the reserve has insufficient funds;
|
||||||
check the signatures in the history... */
|
check the signatures in the history... */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
withdraw_sign_payment_required (wsh,
|
reserve_withdraw_payment_required (wsh,
|
||||||
json))
|
json))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
@ -766,12 +766,12 @@ handle_withdraw_sign_finished (void *cls,
|
|||||||
NULL,
|
NULL,
|
||||||
json);
|
json);
|
||||||
json_decref (json);
|
json_decref (json);
|
||||||
TALER_MINT_withdraw_sign_cancel (wsh);
|
TALER_MINT_reserve_withdraw_cancel (wsh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Withdraw a coin from the mint using a /withdraw/sign request. Note
|
* Withdraw a coin from the mint using a /reserve/withdraw request. Note
|
||||||
* that to ensure that no money is lost in case of hardware failures,
|
* that to ensure that no money is lost in case of hardware failures,
|
||||||
* the caller must have committed (most of) the arguments to disk
|
* the caller must have committed (most of) the arguments to disk
|
||||||
* before calling, and be ready to repeat the request with the same
|
* before calling, and be ready to repeat the request with the same
|
||||||
@ -790,16 +790,16 @@ handle_withdraw_sign_finished (void *cls,
|
|||||||
* if the inputs are invalid (i.e. denomination key not with this mint).
|
* if the inputs are invalid (i.e. denomination key not with this mint).
|
||||||
* In this case, the callback is not called.
|
* In this case, the callback is not called.
|
||||||
*/
|
*/
|
||||||
struct TALER_MINT_WithdrawSignHandle *
|
struct TALER_MINT_ReserveWithdrawHandle *
|
||||||
TALER_MINT_withdraw_sign (struct TALER_MINT_Handle *mint,
|
TALER_MINT_reserve_withdraw (struct TALER_MINT_Handle *mint,
|
||||||
const struct TALER_MINT_DenomPublicKey *pk,
|
const struct TALER_MINT_DenomPublicKey *pk,
|
||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||||
const struct TALER_DenominationBlindingKey *blinding_key,
|
const struct TALER_DenominationBlindingKey *blinding_key,
|
||||||
TALER_MINT_WithdrawSignResultCallback res_cb,
|
TALER_MINT_ReserveWithdrawResultCallback res_cb,
|
||||||
void *res_cb_cls)
|
void *res_cb_cls)
|
||||||
{
|
{
|
||||||
struct TALER_MINT_WithdrawSignHandle *wsh;
|
struct TALER_MINT_ReserveWithdrawHandle *wsh;
|
||||||
struct TALER_WithdrawRequestPS req;
|
struct TALER_WithdrawRequestPS req;
|
||||||
struct TALER_ReserveSignatureP reserve_sig;
|
struct TALER_ReserveSignatureP reserve_sig;
|
||||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
@ -810,7 +810,7 @@ TALER_MINT_withdraw_sign (struct TALER_MINT_Handle *mint,
|
|||||||
json_t *withdraw_obj;
|
json_t *withdraw_obj;
|
||||||
CURL *eh;
|
CURL *eh;
|
||||||
|
|
||||||
wsh = GNUNET_new (struct TALER_MINT_WithdrawSignHandle);
|
wsh = GNUNET_new (struct TALER_MINT_ReserveWithdrawHandle);
|
||||||
wsh->mint = mint;
|
wsh->mint = mint;
|
||||||
wsh->cb = res_cb;
|
wsh->cb = res_cb;
|
||||||
wsh->cb_cls = res_cb_cls;
|
wsh->cb_cls = res_cb_cls;
|
||||||
@ -866,7 +866,7 @@ TALER_MINT_withdraw_sign (struct TALER_MINT_Handle *mint,
|
|||||||
GNUNET_free (coin_ev);
|
GNUNET_free (coin_ev);
|
||||||
|
|
||||||
wsh->blinding_key = blinding_key;
|
wsh->blinding_key = blinding_key;
|
||||||
wsh->url = MAH_path_to_url (mint, "/withdraw/sign");
|
wsh->url = MAH_path_to_url (mint, "/reserve/withdraw");
|
||||||
|
|
||||||
eh = curl_easy_init ();
|
eh = curl_easy_init ();
|
||||||
GNUNET_assert (NULL != (wsh->json_enc =
|
GNUNET_assert (NULL != (wsh->json_enc =
|
||||||
@ -897,7 +897,7 @@ TALER_MINT_withdraw_sign (struct TALER_MINT_Handle *mint,
|
|||||||
wsh->job = MAC_job_add (ctx,
|
wsh->job = MAC_job_add (ctx,
|
||||||
eh,
|
eh,
|
||||||
GNUNET_YES,
|
GNUNET_YES,
|
||||||
&handle_withdraw_sign_finished,
|
&handle_reserve_withdraw_finished,
|
||||||
wsh);
|
wsh);
|
||||||
return wsh;
|
return wsh;
|
||||||
}
|
}
|
||||||
@ -910,7 +910,7 @@ TALER_MINT_withdraw_sign (struct TALER_MINT_Handle *mint,
|
|||||||
* @param sign the withdraw sign request handle
|
* @param sign the withdraw sign request handle
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TALER_MINT_withdraw_sign_cancel (struct TALER_MINT_WithdrawSignHandle *sign)
|
TALER_MINT_reserve_withdraw_cancel (struct TALER_MINT_ReserveWithdrawHandle *sign)
|
||||||
{
|
{
|
||||||
if (NULL != sign->job)
|
if (NULL != sign->job)
|
||||||
{
|
{
|
||||||
@ -924,4 +924,4 @@ TALER_MINT_withdraw_sign_cancel (struct TALER_MINT_WithdrawSignHandle *sign)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* end of mint_api_withdraw.c */
|
/* end of mint_api_reserve.c */
|
619
src/mint-lib/mint_api_wire.c
Normal file
619
src/mint-lib/mint_api_wire.c
Normal file
@ -0,0 +1,619 @@
|
|||||||
|
/*
|
||||||
|
This file is part of TALER
|
||||||
|
Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors)
|
||||||
|
|
||||||
|
TALER is free software; you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3, or (at your option) any later version.
|
||||||
|
|
||||||
|
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
TALER; see the file COPYING. If not, If not, see
|
||||||
|
<http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file mint-lib/mint_api_wire.c
|
||||||
|
* @brief Implementation of the /wire request of the mint's HTTP API
|
||||||
|
* @author Christian Grothoff
|
||||||
|
*/
|
||||||
|
#include "platform.h"
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <jansson.h>
|
||||||
|
#include <microhttpd.h> /* just for HTTP status codes */
|
||||||
|
#include <gnunet/gnunet_util_lib.h>
|
||||||
|
#include "taler_mint_service.h"
|
||||||
|
#include "mint_api_common.h"
|
||||||
|
#include "mint_api_json.h"
|
||||||
|
#include "mint_api_context.h"
|
||||||
|
#include "mint_api_handle.h"
|
||||||
|
#include "taler_signatures.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A Wire Handle
|
||||||
|
*/
|
||||||
|
struct TALER_MINT_WireHandle
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The connection to mint this request handle will use
|
||||||
|
*/
|
||||||
|
struct TALER_MINT_Handle *mint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The url for this request.
|
||||||
|
*/
|
||||||
|
char *url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle for the request.
|
||||||
|
*/
|
||||||
|
struct MAC_Job *job;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to call with the result.
|
||||||
|
*/
|
||||||
|
TALER_MINT_WireResultCallback cb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closure for @a cb.
|
||||||
|
*/
|
||||||
|
void *cb_cls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download buffer
|
||||||
|
*/
|
||||||
|
struct MAC_DownloadBuffer db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to the "methods" JSON array returned by the
|
||||||
|
* /wire request.
|
||||||
|
*/
|
||||||
|
json_t *methods;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current iteration offset in the @e methods array.
|
||||||
|
*/
|
||||||
|
unsigned int methods_off;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that the signature on the "200 OK" response
|
||||||
|
* for /wire/sepa from the mint is valid.
|
||||||
|
*
|
||||||
|
* @param wh wire handle
|
||||||
|
* @param json json reply with the signature
|
||||||
|
* @return #GNUNET_SYSERR if @a json is invalid,
|
||||||
|
* #GNUNET_NO if the method is unknown,
|
||||||
|
* #GNUNET_OK if the json is valid
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
verify_wire_sepa_signature_ok (const struct TALER_MINT_WireHandle *wh,
|
||||||
|
json_t *json)
|
||||||
|
{
|
||||||
|
struct TALER_MasterSignatureP mint_sig;
|
||||||
|
struct TALER_MasterWireSepaDetailsPS mp;
|
||||||
|
const char *receiver_name;
|
||||||
|
const char *iban;
|
||||||
|
const char *bic;
|
||||||
|
const struct TALER_MINT_Keys *key_state;
|
||||||
|
struct GNUNET_HashContext *hc;
|
||||||
|
struct MAJ_Specification spec[] = {
|
||||||
|
MAJ_spec_fixed_auto ("sig", &mint_sig),
|
||||||
|
MAJ_spec_string ("receiver_name", &receiver_name),
|
||||||
|
MAJ_spec_string ("iban", &iban),
|
||||||
|
MAJ_spec_string ("bic", &bic),
|
||||||
|
MAJ_spec_end
|
||||||
|
};
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
MAJ_parse_json (json,
|
||||||
|
spec))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
key_state = TALER_MINT_get_keys (wh->mint);
|
||||||
|
mp.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SEPA_DETAILS);
|
||||||
|
mp.purpose.size = htonl (sizeof (struct TALER_MasterWireSepaDetailsPS));
|
||||||
|
hc = GNUNET_CRYPTO_hash_context_start ();
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hc,
|
||||||
|
receiver_name,
|
||||||
|
strlen (receiver_name) + 1);
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hc,
|
||||||
|
iban,
|
||||||
|
strlen (iban) + 1);
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hc,
|
||||||
|
bic,
|
||||||
|
strlen (bic) + 1);
|
||||||
|
GNUNET_CRYPTO_hash_context_finish (hc,
|
||||||
|
&mp.h_sepa_details);
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_SEPA_DETAILS,
|
||||||
|
&mp.purpose,
|
||||||
|
&mint_sig.eddsa_signature,
|
||||||
|
&key_state->master_pub.eddsa_pub))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
MAJ_parse_free (spec);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
MAJ_parse_free (spec);
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that the signature on the "200 OK" response
|
||||||
|
* for /wire/METHOD from the mint is valid.
|
||||||
|
*
|
||||||
|
* @param wh wire handle with key material
|
||||||
|
* @param method method to verify the reply for
|
||||||
|
* @param json json reply with the signature
|
||||||
|
* @return #GNUNET_SYSERR if @a json is invalid,
|
||||||
|
* #GNUNET_NO if the method is unknown,
|
||||||
|
* #GNUNET_OK if the json is valid
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
verify_wire_method_signature_ok (const struct TALER_MINT_WireHandle *wh,
|
||||||
|
const char *method,
|
||||||
|
json_t *json)
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Name fo the method.
|
||||||
|
*/
|
||||||
|
const char *method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler to invoke to verify signature.
|
||||||
|
*
|
||||||
|
* @param wh wire handle with key material
|
||||||
|
* @param json json reply with signature to verify
|
||||||
|
*/
|
||||||
|
int (*handler)(const struct TALER_MINT_WireHandle *wh,
|
||||||
|
json_t *json);
|
||||||
|
} handlers[] = {
|
||||||
|
{ "sepa", &verify_wire_sepa_signature_ok },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i=0;NULL != handlers[i].method; i++)
|
||||||
|
if (0 == strcasecmp (handlers[i].method,
|
||||||
|
method))
|
||||||
|
return handlers[i].handler (wh,
|
||||||
|
json);
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Wire transfer method `%s' not supported\n",
|
||||||
|
method);
|
||||||
|
return GNUNET_NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform the next /wire/method request or signal
|
||||||
|
* the end of the iteration.
|
||||||
|
*
|
||||||
|
* @param wh the wire handle
|
||||||
|
* @return a handle for this request
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
request_wire_method (struct TALER_MINT_WireHandle *wh);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called when we're done processing the
|
||||||
|
* HTTP /wire/METHOD request.
|
||||||
|
*
|
||||||
|
* @param cls the `struct TALER_MINT_WireHandle`
|
||||||
|
* @param eh the curl request handle
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
handle_wire_method_finished (void *cls,
|
||||||
|
CURL *eh)
|
||||||
|
{
|
||||||
|
struct TALER_MINT_WireHandle *wh = cls;
|
||||||
|
long response_code;
|
||||||
|
json_t *json;
|
||||||
|
|
||||||
|
wh->job = NULL;
|
||||||
|
json = MAC_download_get_result (&wh->db,
|
||||||
|
eh,
|
||||||
|
&response_code);
|
||||||
|
switch (response_code)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_OK:
|
||||||
|
{
|
||||||
|
const char *method;
|
||||||
|
|
||||||
|
method = json_string_value (json_array_get (wh->methods,
|
||||||
|
wh->methods_off - 1));
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
verify_wire_method_signature_ok (wh,
|
||||||
|
method,
|
||||||
|
json))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
response_code = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MHD_HTTP_FOUND:
|
||||||
|
/* /wire/test returns a 302 redirect, we should just give
|
||||||
|
this information back to the callback below */
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_BAD_REQUEST:
|
||||||
|
/* This should never happen, either us or the mint is buggy
|
||||||
|
(or API version conflict); just pass JSON reply to the application */
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_NOT_FOUND:
|
||||||
|
/* Nothing really to verify, this should never
|
||||||
|
happen, we should pass the JSON reply to the application */
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||||
|
/* Server had an internal issue; we should retry, but this API
|
||||||
|
leaves this to the application */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* unexpected response code */
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Unexpected response code %u\n",
|
||||||
|
response_code);
|
||||||
|
GNUNET_break (0);
|
||||||
|
response_code = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (0 == response_code)
|
||||||
|
{
|
||||||
|
/* signal end of iteration */
|
||||||
|
wh->cb (wh->cb_cls,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
json_decref (json);
|
||||||
|
TALER_MINT_wire_cancel (wh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* pass on successful reply */
|
||||||
|
wh->cb (wh->cb_cls,
|
||||||
|
response_code,
|
||||||
|
json_string_value (json_array_get (wh->methods,
|
||||||
|
wh->methods_off-1)),
|
||||||
|
json);
|
||||||
|
/* trigger request for the next /wire/method */
|
||||||
|
request_wire_method (wh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform the next /wire/method request or signal
|
||||||
|
* the end of the iteration.
|
||||||
|
*
|
||||||
|
* @param wh the wire handle
|
||||||
|
* @return a handle for this request
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
request_wire_method (struct TALER_MINT_WireHandle *wh)
|
||||||
|
{
|
||||||
|
struct TALER_MINT_Context *ctx;
|
||||||
|
CURL *eh;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
if (json_array_size (wh->methods) <= wh->methods_off)
|
||||||
|
{
|
||||||
|
/* we are done, signal end of iteration */
|
||||||
|
wh->cb (wh->cb_cls,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
TALER_MINT_wire_cancel (wh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GNUNET_free_non_null (wh->db.buf);
|
||||||
|
wh->db.buf = NULL;
|
||||||
|
wh->db.buf_size = 0;
|
||||||
|
wh->db.eno = 0;
|
||||||
|
GNUNET_free_non_null (wh->url);
|
||||||
|
GNUNET_asprintf (&path,
|
||||||
|
"/wire/%s",
|
||||||
|
json_string_value (json_array_get (wh->methods,
|
||||||
|
wh->methods_off++)));
|
||||||
|
wh->url = MAH_path_to_url (wh->mint,
|
||||||
|
path);
|
||||||
|
GNUNET_free (path);
|
||||||
|
|
||||||
|
eh = curl_easy_init ();
|
||||||
|
GNUNET_assert (CURLE_OK ==
|
||||||
|
curl_easy_setopt (eh,
|
||||||
|
CURLOPT_URL,
|
||||||
|
wh->url));
|
||||||
|
GNUNET_assert (CURLE_OK ==
|
||||||
|
curl_easy_setopt (eh,
|
||||||
|
CURLOPT_WRITEFUNCTION,
|
||||||
|
&MAC_download_cb));
|
||||||
|
GNUNET_assert (CURLE_OK ==
|
||||||
|
curl_easy_setopt (eh,
|
||||||
|
CURLOPT_WRITEDATA,
|
||||||
|
&wh->db));
|
||||||
|
/* The default is 'disabled', but let's be sure */
|
||||||
|
GNUNET_assert (CURLE_OK ==
|
||||||
|
curl_easy_setopt (eh,
|
||||||
|
CURLOPT_FOLLOWLOCATION,
|
||||||
|
(long) 0));
|
||||||
|
ctx = MAH_handle_to_context (wh->mint);
|
||||||
|
wh->job = MAC_job_add (ctx,
|
||||||
|
eh,
|
||||||
|
GNUNET_YES,
|
||||||
|
&handle_wire_method_finished,
|
||||||
|
wh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that the signature on the "200 OK" response
|
||||||
|
* for /wire from the mint is valid.
|
||||||
|
*
|
||||||
|
* @param wh wire handle
|
||||||
|
* @param json json reply with the signature
|
||||||
|
* @return NULL if @a json is invalid, otherwise the
|
||||||
|
* "methods" array (with an RC of 1)
|
||||||
|
*/
|
||||||
|
static json_t *
|
||||||
|
verify_wire_signature_ok (const struct TALER_MINT_WireHandle *wh,
|
||||||
|
json_t *json)
|
||||||
|
{
|
||||||
|
struct TALER_MintSignatureP mint_sig;
|
||||||
|
struct TALER_MintPublicKeyP mint_pub;
|
||||||
|
struct TALER_MintWireSupportMethodsPS mp;
|
||||||
|
json_t *methods;
|
||||||
|
const struct TALER_MINT_Keys *key_state;
|
||||||
|
struct GNUNET_HashContext *hc;
|
||||||
|
struct MAJ_Specification spec[] = {
|
||||||
|
MAJ_spec_fixed_auto ("sig", &mint_sig),
|
||||||
|
MAJ_spec_fixed_auto ("pub", &mint_pub),
|
||||||
|
MAJ_spec_json ("methods", &methods),
|
||||||
|
MAJ_spec_end
|
||||||
|
};
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
MAJ_parse_json (json,
|
||||||
|
spec))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (! json_is_array (methods))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
MAJ_parse_free (spec);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
key_state = TALER_MINT_get_keys (wh->mint);
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_MINT_test_signing_key (key_state,
|
||||||
|
&mint_pub))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
hc = GNUNET_CRYPTO_hash_context_start ();
|
||||||
|
for (i=0;i<json_array_size (methods);i++)
|
||||||
|
{
|
||||||
|
const json_t *element = json_array_get (methods, i);
|
||||||
|
const char *method;
|
||||||
|
|
||||||
|
if (! json_is_string (element))
|
||||||
|
{
|
||||||
|
GNUNET_CRYPTO_hash_context_abort (hc);
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
MAJ_parse_free (spec);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
method = json_string_value (element);
|
||||||
|
GNUNET_CRYPTO_hash_context_read (hc,
|
||||||
|
method,
|
||||||
|
strlen (method) + 1);
|
||||||
|
}
|
||||||
|
mp.purpose.purpose = htonl (TALER_SIGNATURE_MINT_WIRE_TYPES);
|
||||||
|
mp.purpose.size = htonl (sizeof (struct TALER_MintWireSupportMethodsPS));
|
||||||
|
GNUNET_CRYPTO_hash_context_finish (hc,
|
||||||
|
&mp.h_wire_types);
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MINT_WIRE_TYPES,
|
||||||
|
&mp.purpose,
|
||||||
|
&mint_sig.eddsa_signature,
|
||||||
|
&mint_pub.eddsa_pub))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
MAJ_parse_free (spec);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called when we're done processing the
|
||||||
|
* HTTP /wire request.
|
||||||
|
*
|
||||||
|
* @param cls the `struct TALER_MINT_WireHandle`
|
||||||
|
* @param eh the curl request handle
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
handle_wire_finished (void *cls,
|
||||||
|
CURL *eh)
|
||||||
|
{
|
||||||
|
struct TALER_MINT_WireHandle *wh = cls;
|
||||||
|
long response_code;
|
||||||
|
json_t *json;
|
||||||
|
|
||||||
|
wh->job = NULL;
|
||||||
|
json = MAC_download_get_result (&wh->db,
|
||||||
|
eh,
|
||||||
|
&response_code);
|
||||||
|
switch (response_code)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_OK:
|
||||||
|
{
|
||||||
|
json_t *methods;
|
||||||
|
|
||||||
|
if (NULL ==
|
||||||
|
(methods = verify_wire_signature_ok (wh,
|
||||||
|
json)))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
response_code = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
wh->methods = methods;
|
||||||
|
request_wire_method (wh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_BAD_REQUEST:
|
||||||
|
/* This should never happen, either us or the mint is buggy
|
||||||
|
(or API version conflict); just pass JSON reply to the application */
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_NOT_FOUND:
|
||||||
|
/* Nothing really to verify, this should never
|
||||||
|
happen, we should pass the JSON reply to the application */
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||||
|
/* Server had an internal issue; we should retry, but this API
|
||||||
|
leaves this to the application */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* unexpected response code */
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Unexpected response code %u\n",
|
||||||
|
response_code);
|
||||||
|
GNUNET_break (0);
|
||||||
|
response_code = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (0 != response_code)
|
||||||
|
{
|
||||||
|
/* pass on successful reply */
|
||||||
|
wh->cb (wh->cb_cls,
|
||||||
|
response_code,
|
||||||
|
NULL,
|
||||||
|
json);
|
||||||
|
}
|
||||||
|
/* signal end of iteration */
|
||||||
|
wh->cb (wh->cb_cls,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
if (NULL != json)
|
||||||
|
json_decref (json);
|
||||||
|
TALER_MINT_wire_cancel (wh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain information about a mint's wire instructions.
|
||||||
|
* A mint may provide wire instructions for creating
|
||||||
|
* a reserve. The wire instructions also indicate
|
||||||
|
* which wire formats merchants may use with the mint.
|
||||||
|
* This API is typically used by a wallet for wiring
|
||||||
|
* funds, and possibly by a merchant to determine
|
||||||
|
* supported wire formats.
|
||||||
|
*
|
||||||
|
* Note that while we return the (main) response verbatim to the
|
||||||
|
* caller for further processing, we do already verify that the
|
||||||
|
* response is well-formed (i.e. that signatures included in the
|
||||||
|
* response are all valid). If the mint's reply is not well-formed,
|
||||||
|
* we return an HTTP status code of zero to @a cb.
|
||||||
|
*
|
||||||
|
* @param mint the mint handle; the mint must be ready to operate
|
||||||
|
* @param wire_cb the callback to call when a reply for this request is available
|
||||||
|
* @param wire_cb_cls closure for the above callback
|
||||||
|
* @return a handle for this request
|
||||||
|
*/
|
||||||
|
struct TALER_MINT_WireHandle *
|
||||||
|
TALER_MINT_wire (struct TALER_MINT_Handle *mint,
|
||||||
|
TALER_MINT_WireResultCallback wire_cb,
|
||||||
|
void *wire_cb_cls)
|
||||||
|
{
|
||||||
|
struct TALER_MINT_WireHandle *wh;
|
||||||
|
struct TALER_MINT_Context *ctx;
|
||||||
|
CURL *eh;
|
||||||
|
|
||||||
|
if (GNUNET_YES !=
|
||||||
|
MAH_handle_is_ready (mint))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
wh = GNUNET_new (struct TALER_MINT_WireHandle);
|
||||||
|
wh->mint = mint;
|
||||||
|
wh->cb = wire_cb;
|
||||||
|
wh->cb_cls = wire_cb_cls;
|
||||||
|
wh->url = MAH_path_to_url (mint, "/wire");
|
||||||
|
|
||||||
|
eh = curl_easy_init ();
|
||||||
|
GNUNET_assert (CURLE_OK ==
|
||||||
|
curl_easy_setopt (eh,
|
||||||
|
CURLOPT_URL,
|
||||||
|
wh->url));
|
||||||
|
GNUNET_assert (CURLE_OK ==
|
||||||
|
curl_easy_setopt (eh,
|
||||||
|
CURLOPT_WRITEFUNCTION,
|
||||||
|
&MAC_download_cb));
|
||||||
|
GNUNET_assert (CURLE_OK ==
|
||||||
|
curl_easy_setopt (eh,
|
||||||
|
CURLOPT_WRITEDATA,
|
||||||
|
&wh->db));
|
||||||
|
ctx = MAH_handle_to_context (mint);
|
||||||
|
wh->job = MAC_job_add (ctx,
|
||||||
|
eh,
|
||||||
|
GNUNET_YES,
|
||||||
|
&handle_wire_finished,
|
||||||
|
wh);
|
||||||
|
return wh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel a wire information request. This function cannot be used
|
||||||
|
* on a request handle if a response is already served for it.
|
||||||
|
*
|
||||||
|
* @param wire the wire information request handle
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_MINT_wire_cancel (struct TALER_MINT_WireHandle *wire)
|
||||||
|
{
|
||||||
|
if (NULL != wire->job)
|
||||||
|
{
|
||||||
|
MAC_job_cancel (wire->job);
|
||||||
|
wire->job = NULL;
|
||||||
|
}
|
||||||
|
if (NULL != wire->methods)
|
||||||
|
{
|
||||||
|
json_decref (wire->methods);
|
||||||
|
wire->methods = NULL;
|
||||||
|
}
|
||||||
|
GNUNET_free_non_null (wire->db.buf);
|
||||||
|
GNUNET_free (wire->url);
|
||||||
|
GNUNET_free (wire);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* end of mint_api_wire.c */
|
@ -2,9 +2,10 @@
|
|||||||
# Currency supported by the mint (can only be one)
|
# Currency supported by the mint (can only be one)
|
||||||
CURRENCY = EUR
|
CURRENCY = EUR
|
||||||
|
|
||||||
# Wire format supproted by the mint
|
# Wire format supported by the mint
|
||||||
# TEST is used for testing... (what a shock)
|
# We use 'test' for testing of the actual
|
||||||
WIREFORMAT = TEST
|
# coin operations, and 'sepa' to test SEPA-specific routines.
|
||||||
|
WIREFORMAT = test sepa
|
||||||
|
|
||||||
# HTTP port the mint listens to
|
# HTTP port the mint listens to
|
||||||
PORT = 8081
|
PORT = 8081
|
||||||
@ -15,9 +16,15 @@ MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG
|
|||||||
# How to access our database
|
# How to access our database
|
||||||
DB = postgres
|
DB = postgres
|
||||||
|
|
||||||
# This is a testcase, use transient DB actions
|
# Is this is a testcase, use transient DB actions?
|
||||||
TESTRUN = YES
|
TESTRUN = NO
|
||||||
|
|
||||||
[mintdb-postgres]
|
[mintdb-postgres]
|
||||||
|
|
||||||
DB_CONN_STR = "postgres:///talercheck"
|
DB_CONN_STR = "postgres:///talercheck"
|
||||||
|
|
||||||
|
[mint-wire-sepa]
|
||||||
|
SEPA_RESPONSE_FILE = "test-mint-home/sepa.json"
|
||||||
|
|
||||||
|
[mint-wire-test]
|
||||||
|
REDIRECT_URL = "http://www.taler.net/"
|
||||||
|
6
src/mint-lib/test-mint-home/sepa.json
Normal file
6
src/mint-lib/test-mint-home/sepa.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"receiver_name": "Max Mustermann",
|
||||||
|
"iban": "DE89370400440532013000",
|
||||||
|
"bic": "COBADEFF370",
|
||||||
|
"sig": "8M5YJXM68PRAXKH76HYEBCJW657B23JA0RFGNDMZK2379YZMT626H1BN89KC0M1KJBWGYEN5Z763Q0Y7MCTZQ6BPPT7D9KFCTW60C10"
|
||||||
|
}
|
@ -26,6 +26,15 @@
|
|||||||
#include <gnunet/gnunet_util_lib.h>
|
#include <gnunet/gnunet_util_lib.h>
|
||||||
#include <microhttpd.h>
|
#include <microhttpd.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the configuration file is set to include wire format 'test'?
|
||||||
|
*/
|
||||||
|
#define WIRE_TEST 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the configuration file is set to include wire format 'sepa'?
|
||||||
|
*/
|
||||||
|
#define WIRE_SEPA 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main execution context for the main loop.
|
* Main execution context for the main loop.
|
||||||
@ -97,7 +106,12 @@ enum OpCode
|
|||||||
* Verify mint's /refresh/link by linking original private key to
|
* Verify mint's /refresh/link by linking original private key to
|
||||||
* results from #OC_REFRESH_REVEAL step.
|
* results from #OC_REFRESH_REVEAL step.
|
||||||
*/
|
*/
|
||||||
OC_REFRESH_LINK
|
OC_REFRESH_LINK,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the mint's /wire-method.
|
||||||
|
*/
|
||||||
|
OC_WIRE
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -116,7 +130,7 @@ struct MeltDetails
|
|||||||
const char *amount;
|
const char *amount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to withdraw_sign operations for coin to
|
* Reference to reserve_withdraw operations for coin to
|
||||||
* be used for the /refresh/melt operation.
|
* be used for the /refresh/melt operation.
|
||||||
*/
|
*/
|
||||||
const char *coin_ref;
|
const char *coin_ref;
|
||||||
@ -228,14 +242,14 @@ struct Command
|
|||||||
/**
|
/**
|
||||||
* Set to the API's handle during the operation.
|
* Set to the API's handle during the operation.
|
||||||
*/
|
*/
|
||||||
struct TALER_MINT_WithdrawStatusHandle *wsh;
|
struct TALER_MINT_ReserveStatusHandle *wsh;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected reserve balance.
|
* Expected reserve balance.
|
||||||
*/
|
*/
|
||||||
const char *expected_balance;
|
const char *expected_balance;
|
||||||
|
|
||||||
} withdraw_status;
|
} reserve_status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information for a #OC_WITHDRAW_SIGN command.
|
* Information for a #OC_WITHDRAW_SIGN command.
|
||||||
@ -281,9 +295,9 @@ struct Command
|
|||||||
/**
|
/**
|
||||||
* Withdraw handle (while operation is running).
|
* Withdraw handle (while operation is running).
|
||||||
*/
|
*/
|
||||||
struct TALER_MINT_WithdrawSignHandle *wsh;
|
struct TALER_MINT_ReserveWithdrawHandle *wsh;
|
||||||
|
|
||||||
} withdraw_sign;
|
} reserve_withdraw;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information for a #OC_DEPOSIT command.
|
* Information for a #OC_DEPOSIT command.
|
||||||
@ -297,7 +311,7 @@ struct Command
|
|||||||
const char *amount;
|
const char *amount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to a withdraw_sign operation for a coin to
|
* Reference to a reserve_withdraw operation for a coin to
|
||||||
* be used for the /deposit operation.
|
* be used for the /deposit operation.
|
||||||
*/
|
*/
|
||||||
const char *coin_ref;
|
const char *coin_ref;
|
||||||
@ -439,6 +453,23 @@ struct Command
|
|||||||
|
|
||||||
} refresh_link;
|
} refresh_link;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information for the /wire command.
|
||||||
|
*/
|
||||||
|
struct {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle to the wire request.
|
||||||
|
*/
|
||||||
|
struct TALER_MINT_WireHandle *wh;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format we expect to see, others will be *ignored*.
|
||||||
|
*/
|
||||||
|
const char *format;
|
||||||
|
|
||||||
|
} wire;
|
||||||
|
|
||||||
} details;
|
} details;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -622,7 +653,7 @@ compare_admin_add_incoming_history (const struct TALER_MINT_ReserveHistory *h,
|
|||||||
* @return #GNUNET_OK if they match, #GNUNET_SYSERR if not
|
* @return #GNUNET_OK if they match, #GNUNET_SYSERR if not
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
compare_withdraw_sign_history (const struct TALER_MINT_ReserveHistory *h,
|
compare_reserve_withdraw_history (const struct TALER_MINT_ReserveHistory *h,
|
||||||
const struct Command *cmd)
|
const struct Command *cmd)
|
||||||
{
|
{
|
||||||
struct TALER_Amount amount;
|
struct TALER_Amount amount;
|
||||||
@ -634,12 +665,12 @@ compare_withdraw_sign_history (const struct TALER_MINT_ReserveHistory *h,
|
|||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
TALER_string_to_amount (cmd->details.withdraw_sign.amount,
|
TALER_string_to_amount (cmd->details.reserve_withdraw.amount,
|
||||||
&amount));
|
&amount));
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
TALER_amount_add (&amount_with_fee,
|
TALER_amount_add (&amount_with_fee,
|
||||||
&amount,
|
&amount,
|
||||||
&cmd->details.withdraw_sign.pk->fee_withdraw));
|
&cmd->details.reserve_withdraw.pk->fee_withdraw));
|
||||||
if (0 != TALER_amount_cmp (&amount_with_fee,
|
if (0 != TALER_amount_cmp (&amount_with_fee,
|
||||||
&h->amount))
|
&h->amount))
|
||||||
{
|
{
|
||||||
@ -651,7 +682,7 @@ compare_withdraw_sign_history (const struct TALER_MINT_ReserveHistory *h,
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called with the result of a /withdraw/status request.
|
* Function called with the result of a /reserve/status request.
|
||||||
*
|
*
|
||||||
* @param cls closure with the interpreter state
|
* @param cls closure with the interpreter state
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
@ -662,7 +693,7 @@ compare_withdraw_sign_history (const struct TALER_MINT_ReserveHistory *h,
|
|||||||
* @param history detailed transaction history, NULL on error
|
* @param history detailed transaction history, NULL on error
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
withdraw_status_cb (void *cls,
|
reserve_status_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
json_t *json,
|
json_t *json,
|
||||||
const struct TALER_Amount *balance,
|
const struct TALER_Amount *balance,
|
||||||
@ -676,7 +707,7 @@ withdraw_status_cb (void *cls,
|
|||||||
unsigned int j;
|
unsigned int j;
|
||||||
struct TALER_Amount amount;
|
struct TALER_Amount amount;
|
||||||
|
|
||||||
cmd->details.withdraw_status.wsh = NULL;
|
cmd->details.reserve_status.wsh = NULL;
|
||||||
if (cmd->expected_response_code != http_status)
|
if (cmd->expected_response_code != http_status)
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
@ -700,10 +731,10 @@ withdraw_status_cb (void *cls,
|
|||||||
{
|
{
|
||||||
case OC_ADMIN_ADD_INCOMING:
|
case OC_ADMIN_ADD_INCOMING:
|
||||||
if ( ( (NULL != rel->label) &&
|
if ( ( (NULL != rel->label) &&
|
||||||
(0 == strcmp (cmd->details.withdraw_status.reserve_reference,
|
(0 == strcmp (cmd->details.reserve_status.reserve_reference,
|
||||||
rel->label) ) ) ||
|
rel->label) ) ) ||
|
||||||
( (NULL != rel->details.admin_add_incoming.reserve_reference) &&
|
( (NULL != rel->details.admin_add_incoming.reserve_reference) &&
|
||||||
(0 == strcmp (cmd->details.withdraw_status.reserve_reference,
|
(0 == strcmp (cmd->details.reserve_status.reserve_reference,
|
||||||
rel->details.admin_add_incoming.reserve_reference) ) ) )
|
rel->details.admin_add_incoming.reserve_reference) ) ) )
|
||||||
{
|
{
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
@ -718,11 +749,11 @@ withdraw_status_cb (void *cls,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OC_WITHDRAW_SIGN:
|
case OC_WITHDRAW_SIGN:
|
||||||
if (0 == strcmp (cmd->details.withdraw_status.reserve_reference,
|
if (0 == strcmp (cmd->details.reserve_status.reserve_reference,
|
||||||
rel->details.withdraw_sign.reserve_reference))
|
rel->details.reserve_withdraw.reserve_reference))
|
||||||
{
|
{
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
compare_withdraw_sign_history (&history[j],
|
compare_reserve_withdraw_history (&history[j],
|
||||||
rel))
|
rel))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
@ -743,10 +774,10 @@ withdraw_status_cb (void *cls,
|
|||||||
fail (is);
|
fail (is);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (NULL != cmd->details.withdraw_status.expected_balance)
|
if (NULL != cmd->details.reserve_status.expected_balance)
|
||||||
{
|
{
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
TALER_string_to_amount (cmd->details.withdraw_status.expected_balance,
|
TALER_string_to_amount (cmd->details.reserve_status.expected_balance,
|
||||||
&amount));
|
&amount));
|
||||||
if (0 != TALER_amount_cmp (&amount,
|
if (0 != TALER_amount_cmp (&amount,
|
||||||
balance))
|
balance))
|
||||||
@ -769,7 +800,7 @@ withdraw_status_cb (void *cls,
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called upon completion of our /withdraw/sign request.
|
* Function called upon completion of our /reserve/withdraw request.
|
||||||
*
|
*
|
||||||
* @param cls closure with the interpreter state
|
* @param cls closure with the interpreter state
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
@ -778,7 +809,7 @@ withdraw_status_cb (void *cls,
|
|||||||
* @param full_response full response from the mint (for logging, in case of errors)
|
* @param full_response full response from the mint (for logging, in case of errors)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
withdraw_sign_cb (void *cls,
|
reserve_withdraw_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
const struct TALER_DenominationSignature *sig,
|
const struct TALER_DenominationSignature *sig,
|
||||||
json_t *full_response)
|
json_t *full_response)
|
||||||
@ -786,7 +817,7 @@ withdraw_sign_cb (void *cls,
|
|||||||
struct InterpreterState *is = cls;
|
struct InterpreterState *is = cls;
|
||||||
struct Command *cmd = &is->commands[is->ip];
|
struct Command *cmd = &is->commands[is->ip];
|
||||||
|
|
||||||
cmd->details.withdraw_sign.wsh = NULL;
|
cmd->details.reserve_withdraw.wsh = NULL;
|
||||||
if (cmd->expected_response_code != http_status)
|
if (cmd->expected_response_code != http_status)
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
@ -807,7 +838,7 @@ withdraw_sign_cb (void *cls,
|
|||||||
fail (is);
|
fail (is);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cmd->details.withdraw_sign.sig.rsa_signature
|
cmd->details.reserve_withdraw.sig.rsa_signature
|
||||||
= GNUNET_CRYPTO_rsa_signature_dup (sig->rsa_signature);
|
= GNUNET_CRYPTO_rsa_signature_dup (sig->rsa_signature);
|
||||||
break;
|
break;
|
||||||
case MHD_HTTP_PAYMENT_REQUIRED:
|
case MHD_HTTP_PAYMENT_REQUIRED:
|
||||||
@ -1011,10 +1042,6 @@ link_cb (void *cls,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* check that the coins match */
|
/* check that the coins match */
|
||||||
fprintf (stderr,
|
|
||||||
"Got %u coins\n",
|
|
||||||
num_coins);
|
|
||||||
|
|
||||||
for (i=0;i<num_coins;i++)
|
for (i=0;i<num_coins;i++)
|
||||||
for (j=i+1;j<num_coins;j++)
|
for (j=i+1;j<num_coins;j++)
|
||||||
if (0 == memcmp (&coin_privs[i],
|
if (0 == memcmp (&coin_privs[i],
|
||||||
@ -1115,6 +1142,83 @@ find_pk (const struct TALER_MINT_Keys *keys,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callbacks called with the result(s) of a
|
||||||
|
* wire format inquiry request to the mint.
|
||||||
|
*
|
||||||
|
* The callback is invoked multiple times, once for each supported @a
|
||||||
|
* method. Finally, it is invoked one more time with cls/0/NULL/NULL
|
||||||
|
* to indicate the end of the iteration. If any request fails to
|
||||||
|
* generate a valid response from the mint, @a http_status will also
|
||||||
|
* be zero and the iteration will also end. Thus, the iteration
|
||||||
|
* always ends with a final call with an @a http_status of 0. If the
|
||||||
|
* @a http_status is already 0 on the first call, then the response to
|
||||||
|
* the /wire request was invalid. Later, clients can tell the
|
||||||
|
* difference between @a http_status of 0 indicating a failed
|
||||||
|
* /wire/method request and a regular end of the iteration by @a
|
||||||
|
* method being non-NULL. If the mint simply correctly asserts that
|
||||||
|
* it does not support any methods, @a method will be NULL but the @a
|
||||||
|
* http_status will be #MHD_HTTP_OK for the first call (followed by a
|
||||||
|
* cls/0/NULL/NULL call to signal the end of the iteration).
|
||||||
|
*
|
||||||
|
* @param cls closure with the interpreter state
|
||||||
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful request;
|
||||||
|
* 0 if the mint's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param method wire format method supported, i.e. "test" or "sepa", or NULL
|
||||||
|
* if already the /wire request failed.
|
||||||
|
* @param obj the received JSON reply, if successful this should be the wire
|
||||||
|
* format details as provided by /wire/METHOD/, or NULL if the
|
||||||
|
* reply was not in JSON format (in this case, the client might
|
||||||
|
* want to do an HTTP request to /wire/METHOD/ with a browser to
|
||||||
|
* provide more information to the user about the @a method).
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
wire_cb (void *cls,
|
||||||
|
unsigned int http_status,
|
||||||
|
const char *method,
|
||||||
|
json_t *obj)
|
||||||
|
{
|
||||||
|
struct InterpreterState *is = cls;
|
||||||
|
struct Command *cmd = &is->commands[is->ip];
|
||||||
|
|
||||||
|
if (0 == http_status)
|
||||||
|
{
|
||||||
|
/* 0 always signals the end of the iteration */
|
||||||
|
cmd->details.wire.wh = NULL;
|
||||||
|
}
|
||||||
|
else if ( (NULL != method) &&
|
||||||
|
(0 != strcasecmp (method,
|
||||||
|
cmd->details.wire.format)) )
|
||||||
|
{
|
||||||
|
/* not the method we care about, skip */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cmd->expected_response_code != http_status)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Unexpected response code %u to command %s/%s\n",
|
||||||
|
http_status,
|
||||||
|
cmd->label,
|
||||||
|
method);
|
||||||
|
json_dumpf (obj, stderr, 0);
|
||||||
|
fail (is);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (0 == http_status)
|
||||||
|
{
|
||||||
|
/* end of iteration, move to next command */
|
||||||
|
is->ip++;
|
||||||
|
is->task = GNUNET_SCHEDULER_add_now (&interpreter_run,
|
||||||
|
is);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* For now, we only support to be called only once
|
||||||
|
with a "positive" result; so we switch to an
|
||||||
|
expected value of 0 for the 2nd iteration */
|
||||||
|
cmd->expected_response_code = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the main interpreter loop that performs mint operations.
|
* Run the main interpreter loop that performs mint operations.
|
||||||
*
|
*
|
||||||
@ -1212,44 +1316,44 @@ interpreter_run (void *cls,
|
|||||||
return;
|
return;
|
||||||
case OC_WITHDRAW_STATUS:
|
case OC_WITHDRAW_STATUS:
|
||||||
GNUNET_assert (NULL !=
|
GNUNET_assert (NULL !=
|
||||||
cmd->details.withdraw_status.reserve_reference);
|
cmd->details.reserve_status.reserve_reference);
|
||||||
ref = find_command (is,
|
ref = find_command (is,
|
||||||
cmd->details.withdraw_status.reserve_reference);
|
cmd->details.reserve_status.reserve_reference);
|
||||||
GNUNET_assert (NULL != ref);
|
GNUNET_assert (NULL != ref);
|
||||||
GNUNET_assert (OC_ADMIN_ADD_INCOMING == ref->oc);
|
GNUNET_assert (OC_ADMIN_ADD_INCOMING == ref->oc);
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&ref->details.admin_add_incoming.reserve_priv.eddsa_priv,
|
GNUNET_CRYPTO_eddsa_key_get_public (&ref->details.admin_add_incoming.reserve_priv.eddsa_priv,
|
||||||
&reserve_pub.eddsa_pub);
|
&reserve_pub.eddsa_pub);
|
||||||
cmd->details.withdraw_status.wsh
|
cmd->details.reserve_status.wsh
|
||||||
= TALER_MINT_withdraw_status (mint,
|
= TALER_MINT_reserve_status (mint,
|
||||||
&reserve_pub,
|
&reserve_pub,
|
||||||
&withdraw_status_cb,
|
&reserve_status_cb,
|
||||||
is);
|
is);
|
||||||
trigger_context_task ();
|
trigger_context_task ();
|
||||||
return;
|
return;
|
||||||
case OC_WITHDRAW_SIGN:
|
case OC_WITHDRAW_SIGN:
|
||||||
GNUNET_assert (NULL !=
|
GNUNET_assert (NULL !=
|
||||||
cmd->details.withdraw_sign.reserve_reference);
|
cmd->details.reserve_withdraw.reserve_reference);
|
||||||
ref = find_command (is,
|
ref = find_command (is,
|
||||||
cmd->details.withdraw_sign.reserve_reference);
|
cmd->details.reserve_withdraw.reserve_reference);
|
||||||
GNUNET_assert (NULL != ref);
|
GNUNET_assert (NULL != ref);
|
||||||
GNUNET_assert (OC_ADMIN_ADD_INCOMING == ref->oc);
|
GNUNET_assert (OC_ADMIN_ADD_INCOMING == ref->oc);
|
||||||
if (NULL != cmd->details.withdraw_sign.amount)
|
if (NULL != cmd->details.reserve_withdraw.amount)
|
||||||
{
|
{
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_string_to_amount (cmd->details.withdraw_sign.amount,
|
TALER_string_to_amount (cmd->details.reserve_withdraw.amount,
|
||||||
&amount))
|
&amount))
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"Failed to parse amount `%s' at %u\n",
|
"Failed to parse amount `%s' at %u\n",
|
||||||
cmd->details.withdraw_sign.amount,
|
cmd->details.reserve_withdraw.amount,
|
||||||
is->ip);
|
is->ip);
|
||||||
fail (is);
|
fail (is);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cmd->details.withdraw_sign.pk = find_pk (is->keys,
|
cmd->details.reserve_withdraw.pk = find_pk (is->keys,
|
||||||
&amount);
|
&amount);
|
||||||
}
|
}
|
||||||
if (NULL == cmd->details.withdraw_sign.pk)
|
if (NULL == cmd->details.reserve_withdraw.pk)
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"Failed to determine denomination key at %u\n",
|
"Failed to determine denomination key at %u\n",
|
||||||
@ -1263,23 +1367,22 @@ interpreter_run (void *cls,
|
|||||||
struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
|
struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
|
||||||
|
|
||||||
priv = GNUNET_CRYPTO_eddsa_key_create ();
|
priv = GNUNET_CRYPTO_eddsa_key_create ();
|
||||||
cmd->details.withdraw_sign.coin_priv.eddsa_priv = *priv;
|
cmd->details.reserve_withdraw.coin_priv.eddsa_priv = *priv;
|
||||||
GNUNET_free (priv);
|
GNUNET_free (priv);
|
||||||
}
|
}
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&cmd->details.withdraw_sign.coin_priv.eddsa_priv,
|
GNUNET_CRYPTO_eddsa_key_get_public (&cmd->details.reserve_withdraw.coin_priv.eddsa_priv,
|
||||||
&coin_pub.eddsa_pub);
|
&coin_pub.eddsa_pub);
|
||||||
cmd->details.withdraw_sign.blinding_key.rsa_blinding_key
|
cmd->details.reserve_withdraw.blinding_key.rsa_blinding_key
|
||||||
= GNUNET_CRYPTO_rsa_blinding_key_create (GNUNET_CRYPTO_rsa_public_key_len (cmd->details.withdraw_sign.pk->key.rsa_public_key));
|
= GNUNET_CRYPTO_rsa_blinding_key_create (GNUNET_CRYPTO_rsa_public_key_len (cmd->details.reserve_withdraw.pk->key.rsa_public_key));
|
||||||
|
cmd->details.reserve_withdraw.wsh
|
||||||
cmd->details.withdraw_sign.wsh
|
= TALER_MINT_reserve_withdraw (mint,
|
||||||
= TALER_MINT_withdraw_sign (mint,
|
cmd->details.reserve_withdraw.pk,
|
||||||
cmd->details.withdraw_sign.pk,
|
|
||||||
&ref->details.admin_add_incoming.reserve_priv,
|
&ref->details.admin_add_incoming.reserve_priv,
|
||||||
&cmd->details.withdraw_sign.coin_priv,
|
&cmd->details.reserve_withdraw.coin_priv,
|
||||||
&cmd->details.withdraw_sign.blinding_key,
|
&cmd->details.reserve_withdraw.blinding_key,
|
||||||
&withdraw_sign_cb,
|
&reserve_withdraw_cb,
|
||||||
is);
|
is);
|
||||||
if (NULL == cmd->details.withdraw_sign.wsh)
|
if (NULL == cmd->details.reserve_withdraw.wsh)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
fail (is);
|
fail (is);
|
||||||
@ -1308,9 +1411,9 @@ interpreter_run (void *cls,
|
|||||||
switch (ref->oc)
|
switch (ref->oc)
|
||||||
{
|
{
|
||||||
case OC_WITHDRAW_SIGN:
|
case OC_WITHDRAW_SIGN:
|
||||||
coin_priv = &ref->details.withdraw_sign.coin_priv;
|
coin_priv = &ref->details.reserve_withdraw.coin_priv;
|
||||||
coin_pk = ref->details.withdraw_sign.pk;
|
coin_pk = ref->details.reserve_withdraw.pk;
|
||||||
coin_pk_sig = &ref->details.withdraw_sign.sig;
|
coin_pk_sig = &ref->details.reserve_withdraw.sig;
|
||||||
break;
|
break;
|
||||||
case OC_REFRESH_REVEAL:
|
case OC_REFRESH_REVEAL:
|
||||||
{
|
{
|
||||||
@ -1355,7 +1458,6 @@ interpreter_run (void *cls,
|
|||||||
fail (is);
|
fail (is);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
|
GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
|
||||||
&coin_pub.eddsa_pub);
|
&coin_pub.eddsa_pub);
|
||||||
|
|
||||||
@ -1377,6 +1479,7 @@ interpreter_run (void *cls,
|
|||||||
{
|
{
|
||||||
struct TALER_DepositRequestPS dr;
|
struct TALER_DepositRequestPS dr;
|
||||||
|
|
||||||
|
memset (&dr, 0, sizeof (dr));
|
||||||
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
|
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
|
||||||
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
|
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
|
||||||
dr.h_contract = h_contract;
|
dr.h_contract = h_contract;
|
||||||
@ -1395,7 +1498,6 @@ interpreter_run (void *cls,
|
|||||||
GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
|
GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
|
||||||
&dr.purpose,
|
&dr.purpose,
|
||||||
&coin_sig.eddsa_signature));
|
&coin_sig.eddsa_signature));
|
||||||
|
|
||||||
}
|
}
|
||||||
cmd->details.deposit.dh
|
cmd->details.deposit.dh
|
||||||
= TALER_MINT_deposit (mint,
|
= TALER_MINT_deposit (mint,
|
||||||
@ -1454,7 +1556,7 @@ interpreter_run (void *cls,
|
|||||||
GNUNET_assert (NULL != ref);
|
GNUNET_assert (NULL != ref);
|
||||||
GNUNET_assert (OC_WITHDRAW_SIGN == ref->oc);
|
GNUNET_assert (OC_WITHDRAW_SIGN == ref->oc);
|
||||||
|
|
||||||
melt_privs[i] = ref->details.withdraw_sign.coin_priv;
|
melt_privs[i] = ref->details.reserve_withdraw.coin_priv;
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_string_to_amount (md->amount,
|
TALER_string_to_amount (md->amount,
|
||||||
&melt_amounts[i]))
|
&melt_amounts[i]))
|
||||||
@ -1466,8 +1568,8 @@ interpreter_run (void *cls,
|
|||||||
fail (is);
|
fail (is);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
melt_sigs[i] = ref->details.withdraw_sign.sig;
|
melt_sigs[i] = ref->details.reserve_withdraw.sig;
|
||||||
melt_pks[i] = *ref->details.withdraw_sign.pk;
|
melt_pks[i] = *ref->details.reserve_withdraw.pk;
|
||||||
}
|
}
|
||||||
for (i=0;i<num_fresh_coins;i++)
|
for (i=0;i<num_fresh_coins;i++)
|
||||||
{
|
{
|
||||||
@ -1477,7 +1579,7 @@ interpreter_run (void *cls,
|
|||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"Failed to parse amount `%s' at %u\n",
|
"Failed to parse amount `%s' at %u\n",
|
||||||
cmd->details.withdraw_sign.amount,
|
cmd->details.reserve_withdraw.amount,
|
||||||
is->ip);
|
is->ip);
|
||||||
fail (is);
|
fail (is);
|
||||||
return;
|
return;
|
||||||
@ -1544,7 +1646,7 @@ interpreter_run (void *cls,
|
|||||||
/* find melt command */
|
/* find melt command */
|
||||||
ref = find_command (is,
|
ref = find_command (is,
|
||||||
ref->details.refresh_reveal.melt_ref);
|
ref->details.refresh_reveal.melt_ref);
|
||||||
/* find withdraw_sign command */
|
/* find reserve_withdraw command */
|
||||||
{
|
{
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
const struct MeltDetails *md;
|
const struct MeltDetails *md;
|
||||||
@ -1563,7 +1665,7 @@ interpreter_run (void *cls,
|
|||||||
/* finally, use private key from withdraw sign command */
|
/* finally, use private key from withdraw sign command */
|
||||||
cmd->details.refresh_link.rlh
|
cmd->details.refresh_link.rlh
|
||||||
= TALER_MINT_refresh_link (mint,
|
= TALER_MINT_refresh_link (mint,
|
||||||
&ref->details.withdraw_sign.coin_priv,
|
&ref->details.reserve_withdraw.coin_priv,
|
||||||
&link_cb,
|
&link_cb,
|
||||||
is);
|
is);
|
||||||
if (NULL == cmd->details.refresh_link.rlh)
|
if (NULL == cmd->details.refresh_link.rlh)
|
||||||
@ -1574,6 +1676,12 @@ interpreter_run (void *cls,
|
|||||||
}
|
}
|
||||||
trigger_context_task ();
|
trigger_context_task ();
|
||||||
return;
|
return;
|
||||||
|
case OC_WIRE:
|
||||||
|
cmd->details.wire.wh = TALER_MINT_wire (mint,
|
||||||
|
&wire_cb,
|
||||||
|
is);
|
||||||
|
trigger_context_task ();
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"Unknown instruction %d at %u (%s)\n",
|
"Unknown instruction %d at %u (%s)\n",
|
||||||
@ -1623,35 +1731,35 @@ do_shutdown (void *cls,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OC_WITHDRAW_STATUS:
|
case OC_WITHDRAW_STATUS:
|
||||||
if (NULL != cmd->details.withdraw_status.wsh)
|
if (NULL != cmd->details.reserve_status.wsh)
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"Command %u (%s) did not complete\n",
|
"Command %u (%s) did not complete\n",
|
||||||
i,
|
i,
|
||||||
cmd->label);
|
cmd->label);
|
||||||
TALER_MINT_withdraw_status_cancel (cmd->details.withdraw_status.wsh);
|
TALER_MINT_reserve_status_cancel (cmd->details.reserve_status.wsh);
|
||||||
cmd->details.withdraw_status.wsh = NULL;
|
cmd->details.reserve_status.wsh = NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OC_WITHDRAW_SIGN:
|
case OC_WITHDRAW_SIGN:
|
||||||
if (NULL != cmd->details.withdraw_sign.wsh)
|
if (NULL != cmd->details.reserve_withdraw.wsh)
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
"Command %u (%s) did not complete\n",
|
"Command %u (%s) did not complete\n",
|
||||||
i,
|
i,
|
||||||
cmd->label);
|
cmd->label);
|
||||||
TALER_MINT_withdraw_sign_cancel (cmd->details.withdraw_sign.wsh);
|
TALER_MINT_reserve_withdraw_cancel (cmd->details.reserve_withdraw.wsh);
|
||||||
cmd->details.withdraw_sign.wsh = NULL;
|
cmd->details.reserve_withdraw.wsh = NULL;
|
||||||
}
|
}
|
||||||
if (NULL != cmd->details.withdraw_sign.sig.rsa_signature)
|
if (NULL != cmd->details.reserve_withdraw.sig.rsa_signature)
|
||||||
{
|
{
|
||||||
GNUNET_CRYPTO_rsa_signature_free (cmd->details.withdraw_sign.sig.rsa_signature);
|
GNUNET_CRYPTO_rsa_signature_free (cmd->details.reserve_withdraw.sig.rsa_signature);
|
||||||
cmd->details.withdraw_sign.sig.rsa_signature = NULL;
|
cmd->details.reserve_withdraw.sig.rsa_signature = NULL;
|
||||||
}
|
}
|
||||||
if (NULL != cmd->details.withdraw_sign.blinding_key.rsa_blinding_key)
|
if (NULL != cmd->details.reserve_withdraw.blinding_key.rsa_blinding_key)
|
||||||
{
|
{
|
||||||
GNUNET_CRYPTO_rsa_blinding_key_free (cmd->details.withdraw_sign.blinding_key.rsa_blinding_key);
|
GNUNET_CRYPTO_rsa_blinding_key_free (cmd->details.reserve_withdraw.blinding_key.rsa_blinding_key);
|
||||||
cmd->details.withdraw_sign.blinding_key.rsa_blinding_key = NULL;
|
cmd->details.reserve_withdraw.blinding_key.rsa_blinding_key = NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OC_DEPOSIT:
|
case OC_DEPOSIT:
|
||||||
@ -1714,6 +1822,13 @@ do_shutdown (void *cls,
|
|||||||
cmd->details.refresh_link.rlh = NULL;
|
cmd->details.refresh_link.rlh = NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case OC_WIRE:
|
||||||
|
if (NULL != cmd->details.wire.wh)
|
||||||
|
{
|
||||||
|
TALER_MINT_wire_cancel (cmd->details.wire.wh);
|
||||||
|
cmd->details.wire.wh = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"Unknown instruction %d at %u (%s)\n",
|
"Unknown instruction %d at %u (%s)\n",
|
||||||
@ -1880,6 +1995,28 @@ run (void *cls,
|
|||||||
};
|
};
|
||||||
static struct Command commands[] =
|
static struct Command commands[] =
|
||||||
{
|
{
|
||||||
|
/* *************** start of /wire testing ************** */
|
||||||
|
|
||||||
|
#if WIRE_TEST
|
||||||
|
{ .oc = OC_WIRE,
|
||||||
|
.label = "wire-test",
|
||||||
|
/* /wire/test replies with a 302 redirect */
|
||||||
|
.expected_response_code = MHD_HTTP_FOUND,
|
||||||
|
.details.wire.format = "test" },
|
||||||
|
#endif
|
||||||
|
#if WIRE_SEPA
|
||||||
|
{ .oc = OC_WIRE,
|
||||||
|
.label = "wire-sepa",
|
||||||
|
/* /wire/sepa replies with a 200 redirect */
|
||||||
|
.expected_response_code = MHD_HTTP_OK,
|
||||||
|
.details.wire.format = "sepa" },
|
||||||
|
#endif
|
||||||
|
/* *************** end of /wire testing ************** */
|
||||||
|
|
||||||
|
#if WIRE_TEST
|
||||||
|
/* None of this works if 'test' is not allowed as we do
|
||||||
|
/admin/add/incoming with format 'test' */
|
||||||
|
|
||||||
/* Fill reserve with EUR:5.01, as withdraw fee is 1 ct per config */
|
/* Fill reserve with EUR:5.01, as withdraw fee is 1 ct per config */
|
||||||
{ .oc = OC_ADMIN_ADD_INCOMING,
|
{ .oc = OC_ADMIN_ADD_INCOMING,
|
||||||
.label = "create-reserve-1",
|
.label = "create-reserve-1",
|
||||||
@ -1890,15 +2027,15 @@ run (void *cls,
|
|||||||
{ .oc = OC_WITHDRAW_SIGN,
|
{ .oc = OC_WITHDRAW_SIGN,
|
||||||
.label = "withdraw-coin-1",
|
.label = "withdraw-coin-1",
|
||||||
.expected_response_code = MHD_HTTP_OK,
|
.expected_response_code = MHD_HTTP_OK,
|
||||||
.details.withdraw_sign.reserve_reference = "create-reserve-1",
|
.details.reserve_withdraw.reserve_reference = "create-reserve-1",
|
||||||
.details.withdraw_sign.amount = "EUR:5" },
|
.details.reserve_withdraw.amount = "EUR:5" },
|
||||||
/* Check that deposit and withdraw operation are in history, and
|
/* Check that deposit and withdraw operation are in history, and
|
||||||
that the balance is now at zero */
|
that the balance is now at zero */
|
||||||
{ .oc = OC_WITHDRAW_STATUS,
|
{ .oc = OC_WITHDRAW_STATUS,
|
||||||
.label = "withdraw-status-1",
|
.label = "withdraw-status-1",
|
||||||
.expected_response_code = MHD_HTTP_OK,
|
.expected_response_code = MHD_HTTP_OK,
|
||||||
.details.withdraw_status.reserve_reference = "create-reserve-1",
|
.details.reserve_status.reserve_reference = "create-reserve-1",
|
||||||
.details.withdraw_status.expected_balance = "EUR:0" },
|
.details.reserve_status.expected_balance = "EUR:0" },
|
||||||
/* Try to deposit the 5 EUR coin (in full) */
|
/* Try to deposit the 5 EUR coin (in full) */
|
||||||
{ .oc = OC_DEPOSIT,
|
{ .oc = OC_DEPOSIT,
|
||||||
.label = "deposit-simple",
|
.label = "deposit-simple",
|
||||||
@ -1913,8 +2050,8 @@ run (void *cls,
|
|||||||
{ .oc = OC_WITHDRAW_SIGN,
|
{ .oc = OC_WITHDRAW_SIGN,
|
||||||
.label = "withdraw-coin-2",
|
.label = "withdraw-coin-2",
|
||||||
.expected_response_code = MHD_HTTP_PAYMENT_REQUIRED,
|
.expected_response_code = MHD_HTTP_PAYMENT_REQUIRED,
|
||||||
.details.withdraw_sign.reserve_reference = "create-reserve-1",
|
.details.reserve_withdraw.reserve_reference = "create-reserve-1",
|
||||||
.details.withdraw_sign.amount = "EUR:5" },
|
.details.reserve_withdraw.amount = "EUR:5" },
|
||||||
|
|
||||||
/* Try to double-spend the 5 EUR coin with different wire details */
|
/* Try to double-spend the 5 EUR coin with different wire details */
|
||||||
{ .oc = OC_DEPOSIT,
|
{ .oc = OC_DEPOSIT,
|
||||||
@ -1958,8 +2095,8 @@ run (void *cls,
|
|||||||
{ .oc = OC_WITHDRAW_SIGN,
|
{ .oc = OC_WITHDRAW_SIGN,
|
||||||
.label = "refresh-withdraw-coin-1",
|
.label = "refresh-withdraw-coin-1",
|
||||||
.expected_response_code = MHD_HTTP_OK,
|
.expected_response_code = MHD_HTTP_OK,
|
||||||
.details.withdraw_sign.reserve_reference = "refresh-create-reserve-1",
|
.details.reserve_withdraw.reserve_reference = "refresh-create-reserve-1",
|
||||||
.details.withdraw_sign.amount = "EUR:5" },
|
.details.reserve_withdraw.amount = "EUR:5" },
|
||||||
/* Try to partially spend (deposit) 1 EUR of the 5 EUR coin (in full)
|
/* Try to partially spend (deposit) 1 EUR of the 5 EUR coin (in full)
|
||||||
(merchant would receive EUR:0.99 due to 1 ct deposit fee) */
|
(merchant would receive EUR:0.99 due to 1 ct deposit fee) */
|
||||||
{ .oc = OC_DEPOSIT,
|
{ .oc = OC_DEPOSIT,
|
||||||
@ -2026,8 +2163,8 @@ run (void *cls,
|
|||||||
|
|
||||||
// FIXME: also test with coin that was already melted
|
// FIXME: also test with coin that was already melted
|
||||||
// (signature differs from coin that was deposited...)
|
// (signature differs from coin that was deposited...)
|
||||||
|
|
||||||
/* *************** end of /refresh testing ************** */
|
/* *************** end of /refresh testing ************** */
|
||||||
|
#endif
|
||||||
|
|
||||||
{ .oc = OC_END }
|
{ .oc = OC_END }
|
||||||
};
|
};
|
||||||
|
@ -7,6 +7,7 @@ if USE_COVERAGE
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
bin_PROGRAMS = \
|
bin_PROGRAMS = \
|
||||||
|
taler-auditor-sign \
|
||||||
taler-mint-keyup \
|
taler-mint-keyup \
|
||||||
taler-mint-keycheck \
|
taler-mint-keycheck \
|
||||||
taler-mint-reservemod \
|
taler-mint-reservemod \
|
||||||
@ -15,7 +16,6 @@ bin_PROGRAMS = \
|
|||||||
|
|
||||||
taler_mint_keyup_SOURCES = \
|
taler_mint_keyup_SOURCES = \
|
||||||
taler-mint-keyup.c
|
taler-mint-keyup.c
|
||||||
|
|
||||||
taler_mint_keyup_LDADD = \
|
taler_mint_keyup_LDADD = \
|
||||||
$(LIBGCRYPT_LIBS) \
|
$(LIBGCRYPT_LIBS) \
|
||||||
$(top_builddir)/src/util/libtalerutil.la \
|
$(top_builddir)/src/util/libtalerutil.la \
|
||||||
@ -24,6 +24,14 @@ taler_mint_keyup_LDADD = \
|
|||||||
-lgnunetutil $(XLIB)
|
-lgnunetutil $(XLIB)
|
||||||
taler_mint_keyup_LDFLAGS = $(POSTGRESQL_LDFLAGS)
|
taler_mint_keyup_LDFLAGS = $(POSTGRESQL_LDFLAGS)
|
||||||
|
|
||||||
|
taler_auditor_sign_SOURCES = \
|
||||||
|
taler-auditor-sign.c
|
||||||
|
taler_auditor_sign_LDADD = \
|
||||||
|
$(LIBGCRYPT_LIBS) \
|
||||||
|
$(top_builddir)/src/util/libtalerutil.la \
|
||||||
|
$(top_builddir)/src/mintdb/libtalermintdb.la \
|
||||||
|
-lgnunetutil $(XLIB)
|
||||||
|
|
||||||
|
|
||||||
taler_mint_sepa_SOURCES = \
|
taler_mint_sepa_SOURCES = \
|
||||||
taler-mint-sepa.c
|
taler-mint-sepa.c
|
||||||
|
@ -23,6 +23,11 @@
|
|||||||
#include "taler_mintdb_lib.h"
|
#include "taler_mintdb_lib.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are we running in verbose mode?
|
||||||
|
*/
|
||||||
|
static int verbose;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filename of the auditor's private key.
|
* Filename of the auditor's private key.
|
||||||
*/
|
*/
|
||||||
@ -44,17 +49,68 @@ static char *mint_request_file;
|
|||||||
*/
|
*/
|
||||||
static char *output_file;
|
static char *output_file;
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle to the auditor's configuration
|
|
||||||
*/
|
|
||||||
static struct GNUNET_CONFIGURATION_Handle *kcfg;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Master public key of the mint.
|
* Master public key of the mint.
|
||||||
*/
|
*/
|
||||||
static struct TALER_MasterPublicKeyP master_public_key;
|
static struct TALER_MasterPublicKeyP master_public_key;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print denomination key details for diagnostics.
|
||||||
|
*
|
||||||
|
* @param dk denomination key to print
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
print_dk (const struct TALER_DenominationKeyValidityPS *dk)
|
||||||
|
{
|
||||||
|
struct TALER_Amount a;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
fprintf (stdout,
|
||||||
|
"Denomination key hash: %s\n",
|
||||||
|
GNUNET_h2s_full (&dk->denom_hash));
|
||||||
|
TALER_amount_ntoh (&a,
|
||||||
|
&dk->value);
|
||||||
|
fprintf (stdout,
|
||||||
|
"Value: %s\n",
|
||||||
|
s = TALER_amount_to_string (&a));
|
||||||
|
GNUNET_free (s);
|
||||||
|
TALER_amount_ntoh (&a,
|
||||||
|
&dk->fee_withdraw);
|
||||||
|
fprintf (stdout,
|
||||||
|
"Withdraw fee: %s\n",
|
||||||
|
s = TALER_amount_to_string (&a));
|
||||||
|
GNUNET_free (s);
|
||||||
|
TALER_amount_ntoh (&a,
|
||||||
|
&dk->fee_deposit);
|
||||||
|
fprintf (stdout,
|
||||||
|
"Deposit fee: %s\n",
|
||||||
|
s = TALER_amount_to_string (&a));
|
||||||
|
GNUNET_free (s);
|
||||||
|
TALER_amount_ntoh (&a,
|
||||||
|
&dk->fee_refresh);
|
||||||
|
fprintf (stdout,
|
||||||
|
"Refresh fee: %s\n",
|
||||||
|
s = TALER_amount_to_string (&a));
|
||||||
|
GNUNET_free (s);
|
||||||
|
|
||||||
|
fprintf (stdout,
|
||||||
|
"Validity start time: %s\n",
|
||||||
|
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->start)));
|
||||||
|
fprintf (stdout,
|
||||||
|
"Withdraw end time: %s\n",
|
||||||
|
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_withdraw)));
|
||||||
|
fprintf (stdout,
|
||||||
|
"Deposit end time: %s\n",
|
||||||
|
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_spend)));
|
||||||
|
fprintf (stdout,
|
||||||
|
"Legal dispute end time: %s\n",
|
||||||
|
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dk->expire_legal)));
|
||||||
|
|
||||||
|
fprintf (stdout,
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main function of the taler-auditor-sign tool. This tool is used
|
* The main function of the taler-auditor-sign tool. This tool is used
|
||||||
@ -79,18 +135,24 @@ main (int argc,
|
|||||||
"public key of the mint (Crockford base32 encoded)", 1,
|
"public key of the mint (Crockford base32 encoded)", 1,
|
||||||
&GNUNET_GETOPT_set_filename, &mint_public_key},
|
&GNUNET_GETOPT_set_filename, &mint_public_key},
|
||||||
{'r', "mint-request", "FILE",
|
{'r', "mint-request", "FILE",
|
||||||
"set of keys the mint requested the auditor to sign", 0,
|
"set of keys the mint requested the auditor to sign", 1,
|
||||||
&GNUNET_GETOPT_set_string, &mint_request_file},
|
&GNUNET_GETOPT_set_string, &mint_request_file},
|
||||||
{'o', "output", "FILE",
|
{'o', "output", "FILE",
|
||||||
"where to write our signature", 0,
|
"where to write our signature", 1,
|
||||||
&GNUNET_GETOPT_set_string, &output_file},
|
&GNUNET_GETOPT_set_string, &output_file},
|
||||||
GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION),
|
GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION),
|
||||||
|
GNUNET_GETOPT_OPTION_VERBOSE (&verbose),
|
||||||
GNUNET_GETOPT_OPTION_END
|
GNUNET_GETOPT_OPTION_END
|
||||||
};
|
};
|
||||||
struct GNUNET_CRYPTO_EddsaPrivateKey *eddsa_priv;
|
struct GNUNET_CRYPTO_EddsaPrivateKey *eddsa_priv;
|
||||||
|
struct TALER_AuditorSignatureP *sigs;
|
||||||
|
struct TALER_AuditorPublicKeyP apub;
|
||||||
struct GNUNET_DISK_FileHandle *fh;
|
struct GNUNET_DISK_FileHandle *fh;
|
||||||
struct GNUNET_DISK_FileHandle *fout;
|
struct TALER_DenominationKeyValidityPS *dks;
|
||||||
|
unsigned int dks_len;
|
||||||
|
struct TALER_MintKeyValidityPS kv;
|
||||||
off_t in_size;
|
off_t in_size;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
GNUNET_log_setup ("taler-mint-keyup",
|
GNUNET_log_setup ("taler-mint-keyup",
|
||||||
@ -114,10 +176,13 @@ main (int argc,
|
|||||||
auditor_key_file);
|
auditor_key_file);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
GNUNET_CRYPTO_eddsa_key_get_public (eddsa_priv,
|
||||||
|
&apub.eddsa_pub);
|
||||||
if (NULL == mint_public_key)
|
if (NULL == mint_public_key)
|
||||||
{
|
{
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Mint public key not given\n");
|
"Mint public key not given\n");
|
||||||
|
GNUNET_free (eddsa_priv);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
@ -129,12 +194,14 @@ main (int argc,
|
|||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Public key `%s' malformed\n",
|
"Public key `%s' malformed\n",
|
||||||
mint_public_key);
|
mint_public_key);
|
||||||
|
GNUNET_free (eddsa_priv);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (NULL == mint_request_file)
|
if (NULL == mint_request_file)
|
||||||
{
|
{
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Mint signing request not given\n");
|
"Mint signing request not given\n");
|
||||||
|
GNUNET_free (eddsa_priv);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
fh = GNUNET_DISK_file_open (mint_request_file,
|
fh = GNUNET_DISK_file_open (mint_request_file,
|
||||||
@ -146,6 +213,7 @@ main (int argc,
|
|||||||
"Failed to open file `%s': %s\n",
|
"Failed to open file `%s': %s\n",
|
||||||
mint_request_file,
|
mint_request_file,
|
||||||
STRERROR (errno));
|
STRERROR (errno));
|
||||||
|
GNUNET_free (eddsa_priv);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
@ -157,34 +225,95 @@ main (int argc,
|
|||||||
mint_request_file,
|
mint_request_file,
|
||||||
STRERROR (errno));
|
STRERROR (errno));
|
||||||
GNUNET_DISK_file_close (fh);
|
GNUNET_DISK_file_close (fh);
|
||||||
|
GNUNET_free (eddsa_priv);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (0 != (in_size % sizeof (struct TALER_DenominationKeyValidityPS)))
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"Input file size of file `%s' is invalid\n",
|
||||||
|
mint_request_file);
|
||||||
|
GNUNET_DISK_file_close (fh);
|
||||||
|
GNUNET_free (eddsa_priv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dks_len = in_size / sizeof (struct TALER_DenominationKeyValidityPS);
|
||||||
|
kv.purpose.purpose = htonl (TALER_SIGNATURE_AUDITOR_MINT_KEYS);
|
||||||
|
kv.purpose.size = htonl (sizeof (struct TALER_MintKeyValidityPS));
|
||||||
|
kv.master = master_public_key;
|
||||||
|
dks = GNUNET_new_array (dks_len,
|
||||||
|
struct TALER_DenominationKeyValidityPS);
|
||||||
|
sigs = GNUNET_new_array (dks_len,
|
||||||
|
struct TALER_AuditorSignatureP);
|
||||||
|
if (in_size !=
|
||||||
|
GNUNET_DISK_file_read (fh,
|
||||||
|
dks,
|
||||||
|
in_size))
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"Failed to read input file `%s': %s\n",
|
||||||
|
mint_request_file,
|
||||||
|
STRERROR (errno));
|
||||||
|
GNUNET_DISK_file_close (fh);
|
||||||
|
GNUNET_free (sigs);
|
||||||
|
GNUNET_free (dks);
|
||||||
|
GNUNET_free (eddsa_priv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
GNUNET_DISK_file_close (fh);
|
||||||
|
for (i=0;i<dks_len;i++)
|
||||||
|
{
|
||||||
|
struct TALER_DenominationKeyValidityPS *dk = &dks[i];
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
print_dk (dk);
|
||||||
|
kv.start = dk->start;
|
||||||
|
kv.expire_withdraw = dk->expire_withdraw;
|
||||||
|
kv.expire_spend = dk->expire_spend;
|
||||||
|
kv.expire_legal = dk->expire_legal;
|
||||||
|
kv.value = dk->value;
|
||||||
|
kv.fee_withdraw = dk->fee_withdraw;
|
||||||
|
kv.fee_deposit = dk->fee_deposit;
|
||||||
|
kv.fee_refresh = dk->fee_refresh;
|
||||||
|
kv.denom_hash = dk->denom_hash;
|
||||||
|
|
||||||
|
/* Finally sign ... */
|
||||||
|
GNUNET_CRYPTO_eddsa_sign (eddsa_priv,
|
||||||
|
&kv.purpose,
|
||||||
|
&sigs[i].eddsa_sig);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL == output_file)
|
if (NULL == output_file)
|
||||||
{
|
{
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Output file not given\n");
|
"Output file not given\n");
|
||||||
GNUNET_DISK_file_close (fh);
|
GNUNET_free (dks);
|
||||||
|
GNUNET_free (sigs);
|
||||||
|
GNUNET_free (eddsa_priv);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
fout = GNUNET_DISK_file_open (output_file,
|
|
||||||
GNUNET_DISK_OPEN_READ |
|
/* write result to disk */
|
||||||
GNUNET_DISK_OPEN_TRUNCATE |
|
if (GNUNET_OK !=
|
||||||
GNUNET_DISK_OPEN_CREATE,
|
TALER_MINTDB_auditor_write (output_file,
|
||||||
GNUNET_DISK_PERM_USER_READ |
|
&apub,
|
||||||
GNUNET_DISK_PERM_USER_WRITE |
|
sigs,
|
||||||
GNUNET_DISK_PERM_GROUP_READ |
|
&master_public_key,
|
||||||
GNUNET_DISK_PERM_OTHER_READ);
|
dks_len,
|
||||||
if (NULL == fout)
|
dks))
|
||||||
{
|
{
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Failed to open file `%s': %s\n",
|
"Failed to write to file `%s': %s\n",
|
||||||
output_file,
|
output_file,
|
||||||
STRERROR (errno));
|
STRERROR (errno));
|
||||||
GNUNET_DISK_file_close (fh);
|
GNUNET_free (sigs);
|
||||||
|
GNUNET_free (dks);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* FIXME: finally do real work... */
|
GNUNET_free (sigs);
|
||||||
|
GNUNET_free (dks);
|
||||||
GNUNET_free (eddsa_priv);
|
GNUNET_free (eddsa_priv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -157,6 +157,17 @@ struct CoinTypeParams
|
|||||||
*/
|
*/
|
||||||
static char *masterkeyfile;
|
static char *masterkeyfile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filename where to write denomination key signing
|
||||||
|
* requests for the auditor (optional, can be NULL).
|
||||||
|
*/
|
||||||
|
static char *auditorrequestfile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle for writing the output for the auditor.
|
||||||
|
*/
|
||||||
|
static FILE *auditor_output_file;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Director of the mint, containing the keys.
|
* Director of the mint, containing the keys.
|
||||||
*/
|
*/
|
||||||
@ -807,6 +818,20 @@ mint_keys_update_cointype (void *cls,
|
|||||||
GNUNET_CRYPTO_rsa_private_key_free (denomkey_issue.denom_priv.rsa_private_key);
|
GNUNET_CRYPTO_rsa_private_key_free (denomkey_issue.denom_priv.rsa_private_key);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ( (NULL != auditor_output_file) &&
|
||||||
|
(sizeof (denomkey_issue.issue.properties) !=
|
||||||
|
fwrite (&denomkey_issue.issue.properties,
|
||||||
|
sizeof (struct TALER_DenominationKeyValidityPS),
|
||||||
|
1,
|
||||||
|
auditor_output_file)) )
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"Failed to write denomination key information to %s: %s\n",
|
||||||
|
auditorrequestfile,
|
||||||
|
STRERROR (errno));
|
||||||
|
*ret = GNUNET_SYSERR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
GNUNET_CRYPTO_rsa_private_key_free (denomkey_issue.denom_priv.rsa_private_key);
|
GNUNET_CRYPTO_rsa_private_key_free (denomkey_issue.denom_priv.rsa_private_key);
|
||||||
p.anchor = GNUNET_TIME_absolute_add (p.anchor,
|
p.anchor = GNUNET_TIME_absolute_add (p.anchor,
|
||||||
p.duration_spend);
|
p.duration_spend);
|
||||||
@ -859,6 +884,9 @@ main (int argc,
|
|||||||
{'m', "master-key", "FILE",
|
{'m', "master-key", "FILE",
|
||||||
"master key file (private key)", 1,
|
"master key file (private key)", 1,
|
||||||
&GNUNET_GETOPT_set_filename, &masterkeyfile},
|
&GNUNET_GETOPT_set_filename, &masterkeyfile},
|
||||||
|
{'o', "output", "FILE",
|
||||||
|
"auditor denomination key signing request file to create", 1,
|
||||||
|
&GNUNET_GETOPT_set_filename, &auditorrequestfile},
|
||||||
{'t', "time", "TIMESTAMP",
|
{'t', "time", "TIMESTAMP",
|
||||||
"pretend it is a different time for the update", 0,
|
"pretend it is a different time for the update", 0,
|
||||||
&GNUNET_GETOPT_set_string, &pretend_time_str},
|
&GNUNET_GETOPT_set_string, &pretend_time_str},
|
||||||
@ -927,6 +955,20 @@ main (int argc,
|
|||||||
GNUNET_CRYPTO_eddsa_key_get_public (&master_priv.eddsa_priv,
|
GNUNET_CRYPTO_eddsa_key_get_public (&master_priv.eddsa_priv,
|
||||||
&master_public_key.eddsa_pub);
|
&master_public_key.eddsa_pub);
|
||||||
|
|
||||||
|
if (NULL != auditorrequestfile)
|
||||||
|
{
|
||||||
|
auditor_output_file = FOPEN (auditorrequestfile,
|
||||||
|
"w");
|
||||||
|
if (NULL == auditor_output_file)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"Failed to open `%s' for writing: %s\n",
|
||||||
|
auditorrequestfile,
|
||||||
|
STRERROR (errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* check if key from file matches the one from the configuration */
|
/* check if key from file matches the one from the configuration */
|
||||||
{
|
{
|
||||||
struct GNUNET_CRYPTO_EddsaPublicKey master_public_key_from_cfg;
|
struct GNUNET_CRYPTO_EddsaPublicKey master_public_key_from_cfg;
|
||||||
@ -986,6 +1028,11 @@ main (int argc,
|
|||||||
|
|
||||||
if (GNUNET_OK != mint_keys_update_denomkeys ())
|
if (GNUNET_OK != mint_keys_update_denomkeys ())
|
||||||
return 1;
|
return 1;
|
||||||
|
if (NULL != auditor_output_file)
|
||||||
|
{
|
||||||
|
FCLOSE (auditor_output_file);
|
||||||
|
auditor_output_file = NULL;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ taler_mint_httpd_SOURCES = \
|
|||||||
taler-mint-httpd_mhd.c taler-mint-httpd_mhd.h \
|
taler-mint-httpd_mhd.c taler-mint-httpd_mhd.h \
|
||||||
taler-mint-httpd_admin.c taler-mint-httpd_admin.h \
|
taler-mint-httpd_admin.c taler-mint-httpd_admin.h \
|
||||||
taler-mint-httpd_deposit.c taler-mint-httpd_deposit.h \
|
taler-mint-httpd_deposit.c taler-mint-httpd_deposit.h \
|
||||||
taler-mint-httpd_withdraw.c taler-mint-httpd_withdraw.h \
|
taler-mint-httpd_reserve.c taler-mint-httpd_reserve.h \
|
||||||
taler-mint-httpd_wire.c taler-mint-httpd_wire.h \
|
taler-mint-httpd_wire.c taler-mint-httpd_wire.h \
|
||||||
taler-mint-httpd_refresh.c taler-mint-httpd_refresh.h
|
taler-mint-httpd_refresh.c taler-mint-httpd_refresh.h
|
||||||
taler_mint_httpd_LDADD = \
|
taler_mint_httpd_LDADD = \
|
||||||
@ -34,3 +34,9 @@ if HAVE_DEVELOPER
|
|||||||
taler_mint_httpd_SOURCES += \
|
taler_mint_httpd_SOURCES += \
|
||||||
taler-mint-httpd_test.c taler-mint-httpd_test.h
|
taler-mint-httpd_test.c taler-mint-httpd_test.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
check_SCRIPTS = \
|
||||||
|
test_taler_mint_httpd.sh \
|
||||||
|
test_taler_mint_httpd_afl.sh
|
||||||
|
|
||||||
|
TESTS = $(check_SCRIPTS)
|
||||||
|
7
src/mint/afl-tests/id:000000,orig:admin_add_incoming.req
Normal file
7
src/mint/afl-tests/id:000000,orig:admin_add_incoming.req
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
8
src/mint/afl-tests/id:000001,orig:deposit.req
Normal file
8
src/mint/afl-tests/id:000001,orig:deposit.req
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
POST /deposit HTTP/1.1
|
||||||
|
Host: locst:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-: applicn/json
|
||||||
|
Content-Length: 1658
|
||||||
|
Expect: 100-continue
|
||||||
|
|
||||||
|
{"ub_sig":"51SPJSSDESGPR80A40M74WV140520818ECG26E9M8S0M6CSH6X334GSN8RW30D9G8MT46CA660W34GSG6MT4AD9K8GT3ECSH6MVK0E2374V38H1M8MR4CDJ66MWK4E1S6MR3GCT28CV32H1Q8N23GCHG70S36C1K8MS3GCSN8RV36D9S710KGD9K6GWKEGJ28GRM4CJ56X1K6DJ18D2KGHA46D13GDA66GVK4GHJ8N13AE9J8RVK6GT184S48E1K6X336G9Q8N142CJ4692M6EA16GRKJD9N6523ADA36X13GG9G70TK6DHN68R36CT18GR4CDSJ6CW3GCT364W46CSR8RV42GJ474SMADSH851K4H9Q8GS42CHS8RV3GCSJ64V46DSN8RSM6HHN6N246D9S6934AH9P6X23JGSH652K0DJ5612KJGA26N242CH35452081918G2J2G0","timestamp":"/Date(1442821652)/","f":{"currency":"EUR","value":5,"fraction":0},"wire":{"type":"TEST","bank":"dest bank","account":42},"coin_pub":"JXWK4NS0H2W4V4BETQ90CCEDADP6QQ3MV3YZ7RV2KXEM8PWXE8Q0","H_wire":"YQED9FDYPKK2QQYB3FS19Y15ZMKBAXJP2C73CXASAF1KM6ZYY723TEJ3HBR6D864A7X5W58G92QJ0A9PFMZNB81ZP9NJAQQCCABM4RG","H_contract":"1CMEEFQ5S4QJGGAMVYFV07XQRHQA311CR2MTRNC5M9KZV6ETDV1SY00WJFEV2CG9BXQTEQPZAF8A54C2HX32TZCN20VBGPFPS2Z16B0","merchant_pub":"C36TEXQXFW00170C2EJ66ZR0000CX9VPZNZG00109NX020000000","denom_pub":"51R7ARKCD5HJTTV5F4G0M818E9SP280A40G2GVH04CR30GT58S2K2HJ16H336C9N8CVK4E9N6H1MADHH61330HHM6N1K8E1H8RVKJH256D1M6E1K8RWKJGSH8S2M6DJ170TK2H266GTK8DSS64RKJDJ26D144DJ474SK0GHQ711MAD9G752M2CJ58S1KJDA570SK2E9G8N23GCJ28S146DHH610K2H1Q8CW3GGA16S146H9G68TKACSQ6914CE1H691K2E9N6RWM8H9P8CWM2H9S8GSK0H9P6D1K6H9G6X0M4C2171144HJ46N334H9J692M4H9M8MR4CCJ46GRKEGA46533CDJ38MV4CH9K892MAH1P8S2K6D9K6N246E256H244G9Q6D346GJ56S23JGHJ690KADHJ8H242H2575132CSM6X1M4G9N6RR48E9H8MVM8E9354520818CMG26C1H60R30C935452081918G2J2G0","transaction_id":1,"refund_deadline":"/Date(0)/","coin_sig":"X16E0DP8C2BJNVNX09G24FFC5GA4W7RN2YXZP9WJTAN9BY6B4GMA39QNYR51XNNEZ3H1J7TP0K9G55JZ8V7WS7CZMD7E64HWYBFWM00"}
|
File diff suppressed because one or more lines are too long
7
src/mint/afl-tests/id:000002,orig:keys.req
Normal file
7
src/mint/afl-tests/id:000002,orig:keys.req
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
GET /keys HTTP/1.1
|
||||||
|
User-Agent: Wget/1.16.3 (linux-gnu)
|
||||||
|
Accept: */*
|
||||||
|
Accept-Encoding: identity
|
||||||
|
Host: 127.0.0.1:8081
|
||||||
|
Connection: Keep-Alive
|
||||||
|
|
5
src/mint/afl-tests/id:000003,orig:refresh_link.req
Normal file
5
src/mint/afl-tests/id:000003,orig:refresh_link.req
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
GET /refresh/link?coin_pub=WQHES0X5XK43VBG1Y8FXR2YEJM04HQVMDTCS07MH691XWADG8QCG HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
|
8
src/mint/afl-tests/id:000004,orig:refresh_melt.req
Normal file
8
src/mint/afl-tests/id:000004,orig:refresh_melt.req
Normal file
File diff suppressed because one or more lines are too long
7
src/mint/afl-tests/id:000005,orig:refresh_reveal.req
Normal file
7
src/mint/afl-tests/id:000005,orig:refresh_reveal.req
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
POST /refresh/reveal HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 255
|
||||||
|
|
||||||
|
{"session_hash":"V97SB8T670M9V71D1Q0KVQ4GSJCVQ5AAKTTH9QKT0ZJZZBFNZAV4NA8NMWRRGVPFEBEGB6ANCN9BPQASJ40TM4Y1C49648TJJ07PGSG","transfer_privs":[["EQKJA401A9NJ2YJDFZJ1EV8AYXBHWZB6NT5T0TWSJHVKVDM6W8A0"],["TKDJ4DF3GZVG0DGAB9E3RGBGSTANYB6JVVWXJGPMB2AY4VQNTBA0"]]}
|
4
src/mint/afl-tests/id:000006,orig:reserve_status.req
Normal file
4
src/mint/afl-tests/id:000006,orig:reserve_status.req
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
GET /reserve/status?reserve_pub=TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0 HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
|
7
src/mint/afl-tests/id:000007,orig:reserve_withdraw.req
Normal file
7
src/mint/afl-tests/id:000007,orig:reserve_withdraw.req
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
POST /reserve/withdraw HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 919
|
||||||
|
|
||||||
|
{"coin_ev":"Q5X8A8TCBFH7E5BMY7HSB17SHFTM1JPJGV61P2CA7Z9EXG8P2HYS69B31NZESKXHSZHNJ2DQN3CC2AWFNC6V90J577JD3TXBMAY8Y5M9V60KKT73Z1DW24JFSNAK91G1F2WT55ADP1EG7N5F9AY7A7ZJD03MPYSH0RDP7SVZS2KRPA5JRHFR4GDJ59CFNE7A43M95ZKQHQAS8","denom_pub":"51R7ARKCD5HJTTV5F4G0M818E9SP280A40G2GVH04CR30GT58S2K2HJ16H336C9N8CVK4E9N6H1MADHH61330HHM6N1K8E1H8RVKJH256D1M6E1K8RWKJGSH8S2M6DJ170TK2H266GTK8DSS64RKJDJ26D144DJ474SK0GHQ711MAD9G752M2CJ58S1KJDA570SK2E9G8N23GCJ28S146DHH610K2H1Q8CW3GGA16S146H9G68TKACSQ6914CE1H691K2E9N6RWM8H9P8CWM2H9S8GSK0H9P6D1K6H9G6X0M4C2171144HJ46N334H9J692M4H9M8MR4CCJ46GRKEGA46533CDJ38MV4CH9K892MAH1P8S2K6D9K6N246E256H244G9Q6D346GJ56S23JGHJ690KADHJ8H242H2575132CSM6X1M4G9N6RR48E9H8MVM8E9354520818CMG26C1H60R30C935452081918G2J2G0","reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","reserve_sig":"8427B3RTB217124EB1C37ZVJFC08KN17RHGHE9ENZQMQVJ0S11SAX6H8Z06SWCKT06DRQ9DQ8XD786XKQ94T27PYR9GC9EMT1Y02W10"}
|
5
src/mint/afl-tests/id:000008,orig:wire.req
Normal file
5
src/mint/afl-tests/id:000008,orig:wire.req
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
GET /wire HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
|
5
src/mint/afl-tests/id:000009,orig:wire_sepa.req
Normal file
5
src/mint/afl-tests/id:000009,orig:wire_sepa.req
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
GET /wire/sepa HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
|
5
src/mint/afl-tests/id:000010,orig:wire_test.req
Normal file
5
src/mint/afl-tests/id:000010,orig:wire_test.req
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
GET /wire/test HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
|
@ -0,0 +1,7 @@
|
|||||||
|
PoST /admin/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POsT /admin/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POSt /admin/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
BIN
src/mint/afl-tests/id:000012,src:000000,op:flip1,pos:4,+cov
Normal file
BIN
src/mint/afl-tests/id:000012,src:000000,op:flip1,pos:4,+cov
Normal file
Binary file not shown.
BIN
src/mint/afl-tests/id:000013,src:000000,op:flip1,pos:4,+cov
Normal file
BIN
src/mint/afl-tests/id:000013,src:000000,op:flip1,pos:4,+cov
Normal file
Binary file not shown.
@ -0,0 +1,7 @@
|
|||||||
|
POST ¯admin/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST ¯admin/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST ?admin/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /adMin/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
7
src/mint/afl-tests/id:000016,src:000000,op:flip1,pos:11
Normal file
7
src/mint/afl-tests/id:000016,src:000000,op:flip1,pos:11
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin?add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST 'admin/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/aDd/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /aDmin/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/atd/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admIn/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
7
src/mint/afl-tests/id:000019,src:000000,op:flip1,pos:11
Normal file
7
src/mint/afl-tests/id:000019,src:000000,op:flip1,pos:11
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin?add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incOming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/Add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incmming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/aDd/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incomIng HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/iNcoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incominG HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incomiNg HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
BIN
src/mint/afl-tests/id:000025,src:000000,op:flip1,pos:24,+cov
Normal file
BIN
src/mint/afl-tests/id:000025,src:000000,op:flip1,pos:24,+cov
Normal file
Binary file not shown.
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming @TTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HtTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HDTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HVTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTÔP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
7
src/mint/afl-tests/id:000030,src:000000,op:flip1,pos:27
Normal file
7
src/mint/afl-tests/id:000030,src:000000,op:flip1,pos:27
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTDP/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HT\P/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTT@/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTÐ/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTP/±.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTT@/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTP/q.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTT/1.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTP/9.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTP/0.1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTP/1&1
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTP/1.±
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
7
src/mint/afl-tests/id:000038,src:000000,op:flip1,pos:32
Normal file
7
src/mint/afl-tests/id:000038,src:000000,op:flip1,pos:32
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTP/1.3
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTP/1.
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
@ -0,0 +1,7 @@
|
|||||||
|
POST /admin/add/incoming HTTP/1.!
|
||||||
|
Host: localhost:8081
|
||||||
|
Accept: */*
|
||||||
|
Content-Type: application/json
|
||||||
|
Content-Length: 220
|
||||||
|
|
||||||
|
{"reserve_pub":"TMZCK5CFM1KZQGY1WTF0CEZZPGA0670G94969RF79PA5106ARTK0","amount":{"currency":"EUR","value":5,"fraction":10000},"execution_date":"/Date(1442821651)/","wire":{"type":"TEST","bank":"source bank","account":42}}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user