aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mint/mint_db.c429
-rw-r--r--src/mint/mint_db.h153
-rw-r--r--src/mint/taler-mint-httpd_db.c90
-rw-r--r--src/mint/taler-mint-httpd_responses.c66
-rw-r--r--src/mint/taler-mint-httpd_responses.h15
5 files changed, 450 insertions, 303 deletions
diff --git a/src/mint/mint_db.c b/src/mint/mint_db.c
index 2b699928f..39b5a1514 100644
--- a/src/mint/mint_db.c
+++ b/src/mint/mint_db.c
@@ -60,7 +60,12 @@ static char *TALER_MINT_db_connection_cfg_str;
} while (0)
-
+/**
+ * Setup prepared statements.
+ *
+ * @param db_conn connection handle to initialize
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
+ */
int
TALER_MINT_DB_prepare (PGconn *db_conn)
{
@@ -494,189 +499,6 @@ TALER_MINT_DB_prepare (PGconn *db_conn)
}
-int
-TALER_MINT_DB_set_commit_signature (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
- const struct GNUNET_CRYPTO_EddsaSignature *commit_sig)
-{
- GNUNET_break (0);
- return GNUNET_SYSERR;
-}
-
-
-int
-TALER_db_get_link (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
- LinkIterator link_iter,
- void *cls)
-{
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(coin_pub),
- TALER_DB_QUERY_PARAM_END
- };
-
- PGresult *result = TALER_DB_exec_prepared (db_conn, "get_link", params);
-
- if (PGRES_TUPLES_OK != PQresultStatus (result))
- {
- break_db_err (result);
- PQclear (result);
- return GNUNET_SYSERR;
- }
-
- if (0 == PQntuples (result))
- {
- PQclear (result);
- return GNUNET_NO;
- }
-
-
- int i = 0;
- int res;
-
- for (i = 0; i < PQntuples (result); i++)
- {
- struct TALER_RefreshLinkEncrypted *link_enc;
- struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
- struct GNUNET_CRYPTO_rsa_Signature *sig;
- char *ld_buf;
- size_t ld_buf_size;
- char *pk_buf;
- size_t pk_buf_size;
- char *sig_buf;
- size_t sig_buf_size;
- struct TALER_DB_ResultSpec rs[] = {
- TALER_DB_RESULT_SPEC_VAR("link_vector_enc", &ld_buf, &ld_buf_size),
- TALER_DB_RESULT_SPEC_VAR("denom_pub", &pk_buf, &pk_buf_size),
- TALER_DB_RESULT_SPEC_VAR("ev_sig", &sig_buf, &sig_buf_size),
- TALER_DB_RESULT_SPEC_END
- };
-
- if (GNUNET_OK != TALER_DB_extract_result (result, rs, i))
- {
- PQclear (result);
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- if (ld_buf_size < sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))
- {
- PQclear (result);
- GNUNET_free (pk_buf);
- GNUNET_free (sig_buf);
- GNUNET_free (ld_buf);
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- link_enc = GNUNET_malloc (sizeof (struct TALER_RefreshLinkEncrypted) +
- ld_buf_size - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
- link_enc->blinding_key_enc = (const char *) &link_enc[1];
- link_enc->blinding_key_enc_size = ld_buf_size - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey);
- memcpy (link_enc->coin_priv_enc,
- ld_buf,
- ld_buf_size);
-
- sig = GNUNET_CRYPTO_rsa_signature_decode (sig_buf,
- sig_buf_size);
- denom_pub = GNUNET_CRYPTO_rsa_public_key_decode (pk_buf,
- pk_buf_size);
- GNUNET_free (pk_buf);
- GNUNET_free (sig_buf);
- GNUNET_free (ld_buf);
- if ( (NULL == sig) ||
- (NULL == denom_pub) )
- {
- if (NULL != denom_pub)
- GNUNET_CRYPTO_rsa_public_key_free (denom_pub);
- if (NULL != sig)
- GNUNET_CRYPTO_rsa_signature_free (sig);
- GNUNET_free (link_enc);
- GNUNET_break (0);
- PQclear (result);
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK != (res = link_iter (cls,
- link_enc,
- denom_pub,
- sig)))
- {
- GNUNET_assert (GNUNET_SYSERR != res);
- GNUNET_CRYPTO_rsa_signature_free (sig);
- GNUNET_CRYPTO_rsa_public_key_free (denom_pub);
- GNUNET_free (link_enc);
- PQclear (result);
- return res;
- }
- GNUNET_CRYPTO_rsa_signature_free (sig);
- GNUNET_CRYPTO_rsa_public_key_free (denom_pub);
- GNUNET_free (link_enc);
- }
-
- return GNUNET_OK;
-}
-
-
-int
-TALER_db_get_transfer (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
- struct GNUNET_CRYPTO_EcdsaPublicKey *transfer_pub,
- struct GNUNET_HashCode *shared_secret_enc)
-{
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR(coin_pub),
- TALER_DB_QUERY_PARAM_END
- };
-
- PGresult *result = TALER_DB_exec_prepared (db_conn, "get_transfer", params);
-
- if (PGRES_TUPLES_OK != PQresultStatus (result))
- {
- break_db_err (result);
- PQclear (result);
- return GNUNET_SYSERR;
- }
-
- if (0 == PQntuples (result))
- {
- PQclear (result);
- return GNUNET_NO;
- }
-
- if (1 != PQntuples (result))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "got %d tuples for get_transfer\n",
- PQntuples (result));
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
-
- struct TALER_DB_ResultSpec rs[] = {
- TALER_DB_RESULT_SPEC("transfer_pub", transfer_pub),
- TALER_DB_RESULT_SPEC("link_secret_enc", shared_secret_enc),
- TALER_DB_RESULT_SPEC_END
- };
-
- if (GNUNET_OK != TALER_DB_extract_result (result, rs, 0))
- {
- PQclear (result);
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
-
- PQclear (result);
- return GNUNET_OK;
-}
-
-
-
-
-
-// Chaos
-////////////////////////////////////////////////////////////////
-// Order
-
-
-
/**
* Close thread-local database connection when a thread is destroyed.
*
@@ -1696,6 +1518,245 @@ TALER_MINT_DB_get_refresh_commit_link (PGconn *db_conn,
}
+/**
+ * Insert signature of a new coin generated during refresh into
+ * the database indexed by the refresh session and the index
+ * of the coin. This data is later used should an old coin
+ * be used to try to obtain the private keys during "/refresh/link".
+ *
+ * @param db_conn database connection
+ * @param session_pub refresh session
+ * @param newcoin_index coin index
+ * @param ev_sig coin signature
+ * @return #GNUNET_OK on success
+ */
+int
+TALER_MINT_DB_insert_refresh_collectable (PGconn *db_conn,
+ const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
+ uint16_t newcoin_index,
+ const struct GNUNET_CRYPTO_rsa_Signature *ev_sig)
+{
+ // FIXME: check logic!
+ uint16_t newcoin_index_nbo = htons (newcoin_index);
+ char *buf;
+ size_t buf_size;
+ PGresult *result;
+
+ buf_size = GNUNET_CRYPTO_rsa_signature_encode (ev_sig,
+ &buf);
+ {
+ struct TALER_DB_QueryParam params[] = {
+ TALER_DB_QUERY_PARAM_PTR(session_pub),
+ TALER_DB_QUERY_PARAM_PTR(&newcoin_index_nbo),
+ TALER_DB_QUERY_PARAM_PTR_SIZED(buf, buf_size),
+ TALER_DB_QUERY_PARAM_END
+ };
+ result = TALER_DB_exec_prepared (db_conn,
+ "insert_refresh_collectable",
+ params);
+ }
+ GNUNET_free (buf);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ break_db_err (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ PQclear (result);
+ return GNUNET_OK;
+}
+
+
+/**
+ * Obtain the link data of a coin, that is the encrypted link
+ * information, the denomination keys and the signatures.
+ *
+ * @param db_conn database connection
+ * @param coin_pub public key to use to retrieve linkage data
+ * @return all known link data for the coin
+ */
+struct LinkDataList *
+TALER_db_get_link (PGconn *db_conn,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub)
+{
+ struct LinkDataList *ldl;
+ struct LinkDataList *pos;
+ struct TALER_DB_QueryParam params[] = {
+ TALER_DB_QUERY_PARAM_PTR(coin_pub),
+ TALER_DB_QUERY_PARAM_END
+ };
+ PGresult *result = TALER_DB_exec_prepared (db_conn, "get_link", params);
+
+ ldl = NULL;
+ if (PGRES_TUPLES_OK != PQresultStatus (result))
+ {
+ break_db_err (result);
+ PQclear (result);
+ return NULL;
+ }
+
+ if (0 == PQntuples (result))
+ {
+ PQclear (result);
+ return NULL;
+ }
+
+
+ int i = 0;
+
+ for (i = 0; i < PQntuples (result); i++)
+ {
+ struct TALER_RefreshLinkEncrypted *link_enc;
+ struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
+ struct GNUNET_CRYPTO_rsa_Signature *sig;
+ char *ld_buf;
+ size_t ld_buf_size;
+ char *pk_buf;
+ size_t pk_buf_size;
+ char *sig_buf;
+ size_t sig_buf_size;
+ struct TALER_DB_ResultSpec rs[] = {
+ TALER_DB_RESULT_SPEC_VAR("link_vector_enc", &ld_buf, &ld_buf_size),
+ TALER_DB_RESULT_SPEC_VAR("denom_pub", &pk_buf, &pk_buf_size),
+ TALER_DB_RESULT_SPEC_VAR("ev_sig", &sig_buf, &sig_buf_size),
+ TALER_DB_RESULT_SPEC_END
+ };
+
+ if (GNUNET_OK != TALER_DB_extract_result (result, rs, i))
+ {
+ PQclear (result);
+ GNUNET_break (0);
+ TALER_db_link_data_list_free (ldl);
+ return NULL;
+ }
+ if (ld_buf_size < sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))
+ {
+ PQclear (result);
+ GNUNET_free (pk_buf);
+ GNUNET_free (sig_buf);
+ GNUNET_free (ld_buf);
+ TALER_db_link_data_list_free (ldl);
+ return NULL;
+ }
+ // FIXME: use util API for this!
+ link_enc = GNUNET_malloc (sizeof (struct TALER_RefreshLinkEncrypted) +
+ ld_buf_size - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
+ link_enc->blinding_key_enc = (const char *) &link_enc[1];
+ link_enc->blinding_key_enc_size = ld_buf_size - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey);
+ memcpy (link_enc->coin_priv_enc,
+ ld_buf,
+ ld_buf_size);
+
+ sig = GNUNET_CRYPTO_rsa_signature_decode (sig_buf,
+ sig_buf_size);
+ denom_pub = GNUNET_CRYPTO_rsa_public_key_decode (pk_buf,
+ pk_buf_size);
+ GNUNET_free (pk_buf);
+ GNUNET_free (sig_buf);
+ GNUNET_free (ld_buf);
+ if ( (NULL == sig) ||
+ (NULL == denom_pub) )
+ {
+ if (NULL != denom_pub)
+ GNUNET_CRYPTO_rsa_public_key_free (denom_pub);
+ if (NULL != sig)
+ GNUNET_CRYPTO_rsa_signature_free (sig);
+ GNUNET_free (link_enc);
+ GNUNET_break (0);
+ PQclear (result);
+ TALER_db_link_data_list_free (ldl);
+ return NULL;
+ }
+ pos = GNUNET_new (struct LinkDataList);
+ pos->next = ldl;
+ pos->link_data_enc = link_enc;
+ pos->denom_pub = denom_pub;
+ pos->ev_sig = sig;
+ ldl = pos;
+ }
+ return ldl;
+}
+
+
+/**
+ * Free memory of the link data list.
+ *
+ * @param ldl link data list to release
+ */
+void
+TALER_db_link_data_list_free (struct LinkDataList *ldl)
+{
+ GNUNET_break (0); // FIXME
+}
+
+
+/**
+ * Obtain shared secret and transfer public key from the public key of
+ * the coin. This information and the link information returned by
+ * #TALER_db_get_link() enable the owner of an old coin to determine
+ * the private keys of the new coins after the melt.
+ *
+ *
+ * @param db_conn database connection
+ * @param coin_pub public key of the coin
+ * @param transfer_pub[OUT] public transfer key
+ * @param shared_secret_enc[OUT] set to shared secret
+ * @return #GNUNET_OK on success,
+ * #GNUNET_NO on failure (not found)
+ * #GNUNET_SYSERR on internal failure (database issue)
+ */
+int
+TALER_db_get_transfer (PGconn *db_conn,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
+ struct GNUNET_CRYPTO_EcdsaPublicKey *transfer_pub,
+ struct TALER_EncryptedLinkSecret *shared_secret_enc)
+{
+ struct TALER_DB_QueryParam params[] = {
+ TALER_DB_QUERY_PARAM_PTR(coin_pub),
+ TALER_DB_QUERY_PARAM_END
+ };
+
+ PGresult *result = TALER_DB_exec_prepared (db_conn, "get_transfer", params);
+
+ if (PGRES_TUPLES_OK != PQresultStatus (result))
+ {
+ break_db_err (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ if (0 == PQntuples (result))
+ {
+ PQclear (result);
+ return GNUNET_NO;
+ }
+
+ if (1 != PQntuples (result))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "got %d tuples for get_transfer\n",
+ PQntuples (result));
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+
+ struct TALER_DB_ResultSpec rs[] = {
+ TALER_DB_RESULT_SPEC("transfer_pub", transfer_pub),
+ TALER_DB_RESULT_SPEC("link_secret_enc", shared_secret_enc),
+ TALER_DB_RESULT_SPEC_END
+ };
+
+ if (GNUNET_OK != TALER_DB_extract_result (result, rs, 0))
+ {
+ PQclear (result);
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+
+ PQclear (result);
+ return GNUNET_OK;
+}
+
diff --git a/src/mint/mint_db.h b/src/mint/mint_db.h
index 658e87e46..6d82afd16 100644
--- a/src/mint/mint_db.h
+++ b/src/mint/mint_db.h
@@ -29,55 +29,10 @@
/**
- * FIXME.
- */
-int
-TALER_MINT_DB_prepare (PGconn *db_conn);
-
-
-
-
-
-
-/**
- * FIXME: doc, name is bad, too.
- */
-typedef int
-(*LinkIterator) (void *cls,
- const struct TALER_RefreshLinkEncrypted *link_data_enc,
- const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub,
- const struct GNUNET_CRYPTO_rsa_Signature *ev_sig);
-
-
-int
-TALER_db_get_link (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
- LinkIterator link_iter,
- void *cls);
-
-
-/**
- * Obtain shared secret from the transfer public key (?).
- *
- * @param shared_secret_enc[out] set to shared secret; FIXME: use other type
- * to indicate this is the encrypted secret
- */
-int
-TALER_db_get_transfer (PGconn *db_conn,
- const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
- struct GNUNET_CRYPTO_EcdsaPublicKey *transfer_pub,
- struct GNUNET_HashCode *shared_secret_enc);
-
-
-
-// Chaos
-////////////////////////////////////////////////////////////////
-// Order
-
-
-
-/**
* Initialize database subsystem.
+ *
+ * @param connection_cfg configuration for the DB
+ * @return #GNUNET_OK on success
*/
int
TALER_MINT_DB_init (const char *connection_cfg);
@@ -94,6 +49,17 @@ TALER_MINT_DB_get_connection (void);
/**
+ * Setup prepared statements. FIXME: should this be part of the API,
+ * or just internal to "TALER_MINT_DB_get_connection()"?
+ *
+ * @param db_conn connection handle to initialize
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
+ */
+int
+TALER_MINT_DB_prepare (PGconn *db_conn);
+
+
+/**
* Start a transaction.
*
* @param db_conn connection to use
@@ -712,6 +678,97 @@ TALER_MINT_DB_get_refresh_commit_link (PGconn *db_conn,
/**
+ * Insert signature of a new coin generated during refresh into
+ * the database indexed by the refresh session and the index
+ * of the coin. This data is later used should an old coin
+ * be used to try to obtain the private keys during "/refresh/link".
+ *
+ * @param db_conn database connection
+ * @param session_pub refresh session
+ * @param newcoin_index coin index
+ * @param ev_sig coin signature
+ * @return #GNUNET_OK on success
+ */
+int
+TALER_MINT_DB_insert_refresh_collectable (PGconn *db_conn,
+ const struct GNUNET_CRYPTO_EddsaPublicKey *session_pub,
+ uint16_t newcoin_index,
+ const struct GNUNET_CRYPTO_rsa_Signature *ev_sig);
+
+
+/**
+ * Linked list of refresh information linked to a coin.
+ */
+struct LinkDataList
+{
+ /**
+ * Information is stored in a NULL-terminated linked list.
+ */
+ struct LinkDataList *next;
+
+ /**
+ * Link data, used to recover the private key of the coin
+ * by the owner of the old coin.
+ */
+ struct TALER_RefreshLinkEncrypted *link_data_enc;
+
+ /**
+ * Denomination public key, determines the value of the coin.
+ */
+ struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub;
+
+ /**
+ * Signature over the blinded envelope.
+ */
+ struct GNUNET_CRYPTO_rsa_Signature *ev_sig;
+};
+
+
+/**
+ * Obtain the link data of a coin, that is the encrypted link
+ * information, the denomination keys and the signatures.
+ *
+ * @param db_conn database connection
+ * @param coin_pub public key to use to retrieve linkage data
+ * @return all known link data for the coin
+ */
+struct LinkDataList *
+TALER_db_get_link (PGconn *db_conn,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub);
+
+
+/**
+ * Free memory of the link data list.
+ *
+ * @param ldl link data list to release
+ */
+void
+TALER_db_link_data_list_free (struct LinkDataList *ldl);
+
+
+/**
+ * Obtain shared secret and transfer public key from the public key of
+ * the coin. This information and the link information returned by
+ * #TALER_db_get_link() enable the owner of an old coin to determine
+ * the private keys of the new coins after the melt.
+ *
+ *
+ * @param db_conn database connection
+ * @param coin_pub public key of the coin
+ * @param transfer_pub[OUT] public transfer key
+ * @param shared_secret_enc[OUT] set to shared secret
+ * @return #GNUNET_OK on success,
+ * #GNUNET_NO on failure (not found)
+ * #GNUNET_SYSERR on internal failure (database issue)
+ */
+int
+TALER_db_get_transfer (PGconn *db_conn,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub,
+ struct GNUNET_CRYPTO_EcdsaPublicKey *transfer_pub,
+ struct TALER_EncryptedLinkSecret *shared_secret_enc);
+
+
+/**
* Specification for a /lock operation.
*/
struct Lock
diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c
index d213f3bb1..cd51b58af 100644
--- a/src/mint/taler-mint-httpd_db.c
+++ b/src/mint/taler-mint-httpd_db.c
@@ -988,6 +988,16 @@ refresh_mint_coin (struct MHD_Connection *connection,
GNUNET_break (0);
return NULL;
}
+ if (GNUNET_OK !=
+ TALER_MINT_DB_insert_refresh_collectable (db_conn,
+ refresh_session,
+ coin_off,
+ ev_sig))
+ {
+ GNUNET_break (0);
+ GNUNET_CRYPTO_rsa_signature_free (ev_sig);
+ return NULL;
+ }
return ev_sig;
}
@@ -1173,47 +1183,6 @@ TALER_MINT_db_execute_refresh_reveal (struct MHD_Connection *connection,
}
-
-/**
- * FIXME: move into response generation logic!
- * FIXME: need to separate this from DB logic!
- */
-static int
-link_iter (void *cls,
- const struct TALER_RefreshLinkEncrypted *link_data_enc,
- const struct GNUNET_CRYPTO_rsa_PublicKey *denom_pub,
- const struct GNUNET_CRYPTO_rsa_Signature *ev_sig)
-{
- json_t *list = cls;
- json_t *obj = json_object ();
- char *buf;
- size_t buf_len;
-
-
- json_array_append_new (list, obj);
-
- json_object_set_new (obj, "link_enc",
- TALER_JSON_from_data (link_data_enc->coin_priv_enc,
- sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey) +
- link_data_enc->blinding_key_enc_size));
-
- buf_len = GNUNET_CRYPTO_rsa_public_key_encode (denom_pub,
- &buf);
- json_object_set_new (obj, "denom_pub",
- TALER_JSON_from_data (buf,
- buf_len));
- GNUNET_free (buf);
- buf_len = GNUNET_CRYPTO_rsa_signature_encode (ev_sig,
- &buf);
- json_object_set_new (obj, "ev_sig",
- TALER_JSON_from_data (buf,
- buf_len));
- GNUNET_free (buf);
-
- return GNUNET_OK;
-}
-
-
/**
* Execute a "/refresh/link". Returns the linkage information that
* will allow the owner of a coin to follow the refresh trail to
@@ -1228,18 +1197,16 @@ TALER_MINT_db_execute_refresh_link (struct MHD_Connection *connection,
const struct GNUNET_CRYPTO_EcdsaPublicKey *coin_pub)
{
int res;
- json_t *root;
- json_t *list;
PGconn *db_conn;
struct GNUNET_CRYPTO_EcdsaPublicKey transfer_pub;
- struct GNUNET_HashCode shared_secret_enc;
+ struct TALER_EncryptedLinkSecret shared_secret_enc;
+ struct LinkDataList *ldl;
if (NULL == (db_conn = TALER_MINT_DB_get_connection ()))
{
GNUNET_break (0);
return TALER_MINT_reply_internal_db_error (connection);
}
-
res = TALER_db_get_transfer (db_conn,
coin_pub,
&transfer_pub,
@@ -1259,21 +1226,8 @@ TALER_MINT_db_execute_refresh_link (struct MHD_Connection *connection,
}
GNUNET_assert (GNUNET_OK == res);
- /* FIXME: separate out response generation logic! */
-
- list = json_array ();
- root = json_object ();
- json_object_set_new (root, "new_coins", list);
-
- res = TALER_db_get_link (db_conn, coin_pub,
- &link_iter, list);
- if (GNUNET_SYSERR == res)
- {
- GNUNET_break (0);
- // FIXME: return error code!
- return MHD_NO;
- }
- if (GNUNET_NO == res)
+ ldl = TALER_db_get_link (db_conn, coin_pub);
+ if (NULL == ldl)
{
return TALER_MINT_reply_json_pack (connection,
MHD_HTTP_NOT_FOUND,
@@ -1281,17 +1235,11 @@ TALER_MINT_db_execute_refresh_link (struct MHD_Connection *connection,
"error",
"link data not found (link)");
}
- GNUNET_assert (GNUNET_OK == res);
- json_object_set_new (root, "transfer_pub",
- TALER_JSON_from_data (&transfer_pub,
- sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)));
- json_object_set_new (root, "secret_enc",
- TALER_JSON_from_data (&shared_secret_enc,
- sizeof (struct GNUNET_HashCode)));
- res = TALER_MINT_reply_json (connection,
- root,
- MHD_HTTP_OK);
- json_decref (root);
+ res = TALER_MINT_reply_refresh_link_success (connection,
+ &transfer_pub,
+ &shared_secret_enc,
+ ldl);
+ TALER_db_link_data_list_free (ldl);
return res;
}
diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c
index 264e5a126..4a920c08b 100644
--- a/src/mint/taler-mint-httpd_responses.c
+++ b/src/mint/taler-mint-httpd_responses.c
@@ -647,5 +647,71 @@ TALER_MINT_reply_refresh_reveal_success (struct MHD_Connection *connection,
}
+/**
+ * Send a response for "/refresh/link".
+ *
+ * @param connection the connection to send the response to
+ * @param transfer_pub transfer public key
+ * @param shared_secret_enc encrypted shared secret
+ * @param ldl linked list with link data
+ * @return a MHD result code
+ */
+int
+TALER_MINT_reply_refresh_link_success (struct MHD_Connection *connection,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *transfer_pub,
+ const struct TALER_EncryptedLinkSecret *shared_secret_enc,
+ const struct LinkDataList *ldl)
+{
+ const struct LinkDataList *pos;
+ json_t *root;
+ json_t *list;
+ int res;
+
+ list = json_array ();
+ for (pos = ldl; NULL != pos; pos = pos->next)
+ {
+ json_t *obj;
+ char *buf;
+ size_t buf_len;
+
+ obj = json_object ();
+ json_object_set_new (obj, "link_enc",
+ TALER_JSON_from_data (ldl->link_data_enc->coin_priv_enc,
+ sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey) +
+ ldl->link_data_enc->blinding_key_enc_size));
+ buf_len = GNUNET_CRYPTO_rsa_public_key_encode (ldl->denom_pub,
+ &buf);
+ json_object_set_new (obj, "denom_pub",
+ TALER_JSON_from_data (buf,
+ buf_len));
+ GNUNET_free (buf);
+ buf_len = GNUNET_CRYPTO_rsa_signature_encode (ldl->ev_sig,
+ &buf);
+ json_object_set_new (obj, "ev_sig",
+ TALER_JSON_from_data (buf,
+ buf_len));
+ GNUNET_free (buf);
+ json_array_append_new (list, obj);
+ }
+
+ root = json_object ();
+ json_object_set_new (root,
+ "new_coins",
+ list);
+ json_object_set_new (root,
+ "transfer_pub",
+ TALER_JSON_from_data (transfer_pub,
+ sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)));
+ json_object_set_new (root,
+ "secret_enc",
+ TALER_JSON_from_data (shared_secret_enc,
+ sizeof (struct TALER_EncryptedLinkSecret)));
+ res = TALER_MINT_reply_json (connection,
+ root,
+ MHD_HTTP_OK);
+ json_decref (root);
+ return res;
+}
+
/* end of taler-mint-httpd_responses.c */
diff --git a/src/mint/taler-mint-httpd_responses.h b/src/mint/taler-mint-httpd_responses.h
index c6f31f1dc..24fb2ef8a 100644
--- a/src/mint/taler-mint-httpd_responses.h
+++ b/src/mint/taler-mint-httpd_responses.h
@@ -292,5 +292,20 @@ TALER_MINT_reply_refresh_reveal_success (struct MHD_Connection *connection,
struct GNUNET_CRYPTO_rsa_Signature **sigs);
+/**
+ * Send a response for "/refresh/link".
+ *
+ * @param connection the connection to send the response to
+ * @param transfer_pub transfer public key
+ * @param shared_secret_enc encrypted shared secret
+ * @param ldl linked list with link data
+ * @return a MHD result code
+ */
+int
+TALER_MINT_reply_refresh_link_success (struct MHD_Connection *connection,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *transfer_pub,
+ const struct TALER_EncryptedLinkSecret *shared_secret_enc,
+ const struct LinkDataList *ldl);
+
#endif