updating code to match simplified specification (#4039)
This commit is contained in:
parent
e5988bf353
commit
9bbfca568f
@ -52,18 +52,6 @@ json_t *
|
||||
TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp);
|
||||
|
||||
|
||||
/**
|
||||
* Convert a signature (with purpose) to a JSON object representation.
|
||||
*
|
||||
* @param purpose purpose of the signature
|
||||
* @param signature the signature
|
||||
* @return the JSON reporesentation of the signature with purpose
|
||||
*/
|
||||
json_t *
|
||||
TALER_json_from_eddsa_sig (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
|
||||
const struct GNUNET_CRYPTO_EddsaSignature *signature);
|
||||
|
||||
|
||||
/**
|
||||
* Convert RSA public key to JSON.
|
||||
*
|
||||
@ -93,7 +81,8 @@ TALER_json_from_rsa_signature (struct GNUNET_CRYPTO_rsa_Signature *sig);
|
||||
* @return json string that encodes @a data
|
||||
*/
|
||||
json_t *
|
||||
TALER_json_from_data (const void *data, size_t size);
|
||||
TALER_json_from_data (const void *data,
|
||||
size_t size);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -62,13 +62,20 @@ TALER_MINT_verify_coin_history_ (const char *currency,
|
||||
{
|
||||
json_t *transaction;
|
||||
struct TALER_Amount amount;
|
||||
struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
|
||||
struct TALER_CoinSpendSignatureP sig;
|
||||
void *details;
|
||||
size_t details_size;
|
||||
const char *type;
|
||||
struct MAJ_Specification spec[] = {
|
||||
MAJ_spec_amount ("amount",
|
||||
&amount),
|
||||
MAJ_spec_eddsa_signed_purpose ("signature",
|
||||
&purpose,
|
||||
&coin_pub->eddsa_pub),
|
||||
MAJ_spec_string ("type",
|
||||
&type),
|
||||
MAJ_spec_fixed_auto ("signature",
|
||||
&sig),
|
||||
MAJ_spec_varsize ("details",
|
||||
&details,
|
||||
&details_size),
|
||||
MAJ_spec_end
|
||||
};
|
||||
|
||||
@ -81,57 +88,90 @@ TALER_MINT_verify_coin_history_ (const char *currency,
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
switch (ntohl (purpose->purpose))
|
||||
if (0 == strcasecmp (type,
|
||||
"DEPOSIT"))
|
||||
{
|
||||
case TALER_SIGNATURE_WALLET_COIN_DEPOSIT:
|
||||
{
|
||||
const struct TALER_DepositRequestPS *dr;
|
||||
struct TALER_Amount dr_amount;
|
||||
const struct TALER_DepositRequestPS *dr;
|
||||
struct TALER_Amount dr_amount;
|
||||
|
||||
if (ntohl (purpose->size) != sizeof (struct TALER_DepositRequestPS))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
MAJ_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
dr = (const struct TALER_DepositRequestPS *) purpose;
|
||||
TALER_amount_ntoh (&dr_amount,
|
||||
&dr->amount_with_fee);
|
||||
if (0 != TALER_amount_cmp (&dr_amount,
|
||||
&amount))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
MAJ_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TALER_SIGNATURE_WALLET_COIN_MELT:
|
||||
if (details_size != sizeof (struct TALER_DepositRequestPS))
|
||||
{
|
||||
const struct TALER_RefreshMeltCoinAffirmationPS *rm;
|
||||
struct TALER_Amount rm_amount;
|
||||
|
||||
if (ntohl (purpose->size) != sizeof (struct TALER_RefreshMeltCoinAffirmationPS))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
MAJ_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
rm = (const struct TALER_RefreshMeltCoinAffirmationPS *) purpose;
|
||||
TALER_amount_ntoh (&rm_amount,
|
||||
&rm->amount_with_fee);
|
||||
if (0 != TALER_amount_cmp (&rm_amount,
|
||||
&amount))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
MAJ_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
GNUNET_break_op (0);
|
||||
MAJ_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dr = (const struct TALER_DepositRequestPS *) details;
|
||||
if (details_size != ntohl (dr->purpose.size))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
MAJ_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
|
||||
&dr->purpose,
|
||||
&sig.eddsa_signature,
|
||||
&coin_pub->eddsa_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
MAJ_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
// FIXME: check sig!
|
||||
TALER_amount_ntoh (&dr_amount,
|
||||
&dr->amount_with_fee);
|
||||
if (0 != TALER_amount_cmp (&dr_amount,
|
||||
&amount))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
MAJ_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
else if (0 == strcasecmp (type,
|
||||
"MELT"))
|
||||
{
|
||||
const struct TALER_RefreshMeltCoinAffirmationPS *rm;
|
||||
struct TALER_Amount rm_amount;
|
||||
|
||||
if (details_size != sizeof (struct TALER_RefreshMeltCoinAffirmationPS))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
MAJ_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
rm = (const struct TALER_RefreshMeltCoinAffirmationPS *) details;
|
||||
if (details_size != ntohl (rm->purpose.size))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
MAJ_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT,
|
||||
&rm->purpose,
|
||||
&sig.eddsa_signature,
|
||||
&coin_pub->eddsa_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
MAJ_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
TALER_amount_ntoh (&rm_amount,
|
||||
&rm->amount_with_fee);
|
||||
if (0 != TALER_amount_cmp (&rm_amount,
|
||||
&amount))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
MAJ_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* signature not supported, new version on server? */
|
||||
GNUNET_break (0);
|
||||
GNUNET_break_op (0);
|
||||
MAJ_parse_free (spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
@ -213,49 +213,6 @@ parse_json (json_t *root,
|
||||
}
|
||||
break;
|
||||
|
||||
case MAJ_CMD_EDDSA_SIGNATURE:
|
||||
{
|
||||
struct TALER_CoinSpendSignatureP sig;
|
||||
struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
|
||||
size_t size;
|
||||
struct MAJ_Specification sig_spec[] = {
|
||||
MAJ_spec_fixed_auto ("eddsa_sig", &sig),
|
||||
MAJ_spec_varsize ("eddsa_val", (void**) &purpose, &size),
|
||||
MAJ_spec_end
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
MAJ_parse_json (pos,
|
||||
sig_spec))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
MAJ_parse_free (sig_spec);
|
||||
return i;
|
||||
}
|
||||
if (size != ntohl (purpose->size))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
MAJ_parse_free (sig_spec);
|
||||
return i;
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (ntohl (purpose->purpose),
|
||||
purpose,
|
||||
&sig.eddsa_signature,
|
||||
spec[i].details.eddsa_signature.pub_key))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to verify signature of purpose %u\n",
|
||||
ntohl (purpose->purpose));
|
||||
GNUNET_break_op (0);
|
||||
MAJ_parse_free (sig_spec);
|
||||
return i;
|
||||
}
|
||||
*spec[i].details.eddsa_signature.purpose_p = purpose;
|
||||
}
|
||||
break;
|
||||
|
||||
case MAJ_CMD_UINT16:
|
||||
{
|
||||
json_int_t val;
|
||||
@ -337,10 +294,6 @@ parse_free (struct MAJ_Specification *spec,
|
||||
GNUNET_CRYPTO_rsa_signature_free (*spec[i].details.rsa_signature);
|
||||
*spec[i].details.rsa_signature = NULL;
|
||||
break;
|
||||
case MAJ_CMD_EDDSA_SIGNATURE:
|
||||
GNUNET_free (*spec[i].details.eddsa_signature.purpose_p);
|
||||
*spec[i].details.eddsa_signature.purpose_p = NULL;
|
||||
break;
|
||||
case MAJ_CMD_JSON_OBJECT:
|
||||
json_decref (*spec[i].details.obj);
|
||||
*spec[i].details.obj = NULL;
|
||||
@ -535,28 +488,4 @@ MAJ_spec_rsa_signature (const char *name,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specification for parsing an EdDSA object signature with purpose.
|
||||
* Also validates the signature (!).
|
||||
*
|
||||
* @param name name of the JSON field
|
||||
* @param purpose_p where to store the purpose
|
||||
* @param pub_key public key to use for validation
|
||||
*/
|
||||
struct MAJ_Specification
|
||||
MAJ_spec_eddsa_signed_purpose (const char *name,
|
||||
struct GNUNET_CRYPTO_EccSignaturePurpose **purpose_p,
|
||||
const struct GNUNET_CRYPTO_EddsaPublicKey *pub_key)
|
||||
{
|
||||
struct MAJ_Specification ret =
|
||||
{
|
||||
.cmd = MAJ_CMD_EDDSA_SIGNATURE,
|
||||
.field = name,
|
||||
.details.eddsa_signature.purpose_p = purpose_p,
|
||||
.details.eddsa_signature.pub_key = pub_key
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* end of mint_api_json.c */
|
||||
|
@ -68,11 +68,6 @@ enum MAJ_Command
|
||||
*/
|
||||
MAJ_CMD_RSA_SIGNATURE,
|
||||
|
||||
/**
|
||||
* Parse object with EdDSA signature and purpose at current position.
|
||||
*/
|
||||
MAJ_CMD_EDDSA_SIGNATURE,
|
||||
|
||||
/**
|
||||
* Parse `const char *` JSON string at current position.
|
||||
*/
|
||||
@ -309,20 +304,6 @@ MAJ_spec_amount (const char *name,
|
||||
struct TALER_Amount *amount);
|
||||
|
||||
|
||||
/**
|
||||
* Specification for parsing an EdDSA object signature with purpose.
|
||||
* Also validates the signature (!).
|
||||
*
|
||||
* @param name name of the JSON field
|
||||
* @param purpose_p where to store the purpose
|
||||
* @param pub_key public key to use for validation
|
||||
*/
|
||||
struct MAJ_Specification
|
||||
MAJ_spec_eddsa_signed_purpose (const char *name,
|
||||
struct GNUNET_CRYPTO_EccSignaturePurpose **purpose_p,
|
||||
const struct GNUNET_CRYPTO_EddsaPublicKey *pub_key);
|
||||
|
||||
|
||||
/**
|
||||
* Specification for parsing an RSA public key.
|
||||
*
|
||||
|
@ -167,13 +167,14 @@ parse_reserve_history (json_t *history,
|
||||
else if (0 == strcasecmp (type,
|
||||
"WITHDRAW"))
|
||||
{
|
||||
struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
|
||||
const struct TALER_WithdrawRequestPS *withdraw_purpose;
|
||||
struct TALER_ReserveSignatureP sig;
|
||||
struct TALER_WithdrawRequestPS withdraw_purpose;
|
||||
struct TALER_Amount amount_from_purpose;
|
||||
struct MAJ_Specification withdraw_spec[] = {
|
||||
MAJ_spec_eddsa_signed_purpose ("signature",
|
||||
&purpose,
|
||||
&reserve_pub->eddsa_pub),
|
||||
MAJ_spec_fixed_auto ("signature",
|
||||
&sig),
|
||||
MAJ_spec_fixed_auto ("details",
|
||||
&withdraw_purpose),
|
||||
MAJ_spec_end
|
||||
};
|
||||
unsigned int i;
|
||||
@ -186,17 +187,19 @@ parse_reserve_history (json_t *history,
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
/* Check that the signature actually signed a withdraw request */
|
||||
if ( (ntohl (purpose->purpose) != TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW) ||
|
||||
(ntohl (purpose->size) != sizeof (struct TALER_WithdrawRequestPS)) )
|
||||
/* Check that the signature is a valid withdraw request */
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
|
||||
&withdraw_purpose.purpose,
|
||||
&sig.eddsa_signature,
|
||||
&reserve_pub->eddsa_pub))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
MAJ_parse_free (withdraw_spec);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
withdraw_purpose = (const struct TALER_WithdrawRequestPS *) purpose;
|
||||
TALER_amount_ntoh (&amount_from_purpose,
|
||||
&withdraw_purpose->amount_with_fee);
|
||||
&withdraw_purpose.amount_with_fee);
|
||||
if (0 != TALER_amount_cmp (&amount,
|
||||
&amount_from_purpose))
|
||||
{
|
||||
@ -211,8 +214,8 @@ parse_reserve_history (json_t *history,
|
||||
"uuid" array to remember the hashes of all
|
||||
purposes, and compare the hashes to find
|
||||
duplicates. */
|
||||
GNUNET_CRYPTO_hash (withdraw_purpose,
|
||||
ntohl (withdraw_purpose->purpose.size),
|
||||
GNUNET_CRYPTO_hash (&withdraw_purpose,
|
||||
ntohl (withdraw_purpose.purpose.size),
|
||||
&uuid[uuid_off]);
|
||||
for (i=0;i<uuid_off;i++)
|
||||
{
|
||||
|
@ -404,10 +404,11 @@ TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection,
|
||||
static json_t *
|
||||
compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
||||
{
|
||||
json_t *transaction;
|
||||
json_t *details;
|
||||
const char *type;
|
||||
struct TALER_Amount value;
|
||||
json_t *history;
|
||||
const struct TALER_CoinSpendSignatureP *sig;
|
||||
const struct TALER_MINTDB_TransactionList *pos;
|
||||
|
||||
history = json_array ();
|
||||
@ -420,7 +421,7 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
||||
struct TALER_DepositRequestPS dr;
|
||||
const struct TALER_MINTDB_Deposit *deposit = pos->details.deposit;
|
||||
|
||||
type = "deposit";
|
||||
type = "DEPOSIT";
|
||||
value = deposit->amount_with_fee;
|
||||
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
|
||||
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
|
||||
@ -435,12 +436,12 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
||||
&deposit->deposit_fee);
|
||||
dr.merchant = deposit->merchant_pub;
|
||||
dr.coin_pub = deposit->coin.coin_pub;
|
||||
|
||||
sig = &deposit->csig;
|
||||
/* internal sanity check before we hand out a bogus sig... */
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
|
||||
&dr.purpose,
|
||||
&deposit->csig.eddsa_signature,
|
||||
&sig->eddsa_signature,
|
||||
&deposit->coin.coin_pub.eddsa_pub))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -448,8 +449,8 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
transaction = TALER_json_from_eddsa_sig (&dr.purpose,
|
||||
&deposit->csig.eddsa_signature);
|
||||
details = TALER_json_from_data (&dr.purpose,
|
||||
sizeof (struct TALER_DepositRequestPS));
|
||||
break;
|
||||
}
|
||||
case TALER_MINTDB_TT_REFRESH_MELT:
|
||||
@ -457,7 +458,7 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
||||
struct TALER_RefreshMeltCoinAffirmationPS ms;
|
||||
const struct TALER_MINTDB_RefreshMelt *melt = pos->details.melt;
|
||||
|
||||
type = "melt";
|
||||
type = "MELT";
|
||||
value = melt->amount_with_fee;
|
||||
ms.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT);
|
||||
ms.purpose.size = htonl (sizeof (struct TALER_RefreshMeltCoinAffirmationPS));
|
||||
@ -467,12 +468,12 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
||||
TALER_amount_hton (&ms.melt_fee,
|
||||
&melt->melt_fee);
|
||||
ms.coin_pub = melt->coin.coin_pub;
|
||||
|
||||
sig = &melt->coin_sig;
|
||||
/* internal sanity check before we hand out a bogus sig... */
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT,
|
||||
&ms.purpose,
|
||||
&melt->coin_sig.eddsa_signature,
|
||||
&sig->eddsa_signature,
|
||||
&melt->coin.coin_pub.eddsa_pub))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -480,18 +481,20 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
transaction = TALER_json_from_eddsa_sig (&ms.purpose,
|
||||
&melt->coin_sig.eddsa_signature);
|
||||
details = TALER_json_from_data (&ms.purpose,
|
||||
sizeof (struct TALER_RefreshMeltCoinAffirmationPS));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
GNUNET_assert (0);
|
||||
}
|
||||
json_array_append_new (history,
|
||||
json_pack ("{s:s, s:o, s:o}",
|
||||
json_pack ("{s:s, s:o, s:o, s:o}",
|
||||
"type", type,
|
||||
"amount", TALER_json_from_amount (&value),
|
||||
"signature", transaction));
|
||||
"signature", TALER_json_from_data (sig,
|
||||
sizeof (struct TALER_CoinSpendSignatureP)),
|
||||
"details", details));
|
||||
}
|
||||
return history;
|
||||
}
|
||||
@ -539,7 +542,6 @@ compile_reserve_history (const struct TALER_MINTDB_ReserveHistory *rh,
|
||||
struct TALER_Amount withdraw_total;
|
||||
struct TALER_Amount value;
|
||||
json_t *json_history;
|
||||
json_t *transaction;
|
||||
int ret;
|
||||
const struct TALER_MINTDB_ReserveHistory *pos;
|
||||
struct TALER_WithdrawRequestPS wr;
|
||||
@ -609,14 +611,13 @@ compile_reserve_history (const struct TALER_MINTDB_ReserveHistory *rh,
|
||||
GNUNET_CRYPTO_rsa_public_key_hash (pos->details.withdraw->denom_pub.rsa_public_key,
|
||||
&wr.h_denomination_pub);
|
||||
wr.h_coin_envelope = pos->details.withdraw->h_coin_envelope;
|
||||
|
||||
transaction = TALER_json_from_eddsa_sig (&wr.purpose,
|
||||
&pos->details.withdraw->reserve_sig.eddsa_signature);
|
||||
|
||||
json_array_append_new (json_history,
|
||||
json_pack ("{s:s, s:o, s:o}",
|
||||
json_pack ("{s:s, s:o, s:o, s:o}",
|
||||
"type", "WITHDRAW",
|
||||
"signature", transaction,
|
||||
"signature", TALER_json_from_data (&pos->details.withdraw->reserve_sig,
|
||||
sizeof (struct TALER_ReserveSignatureP)),
|
||||
"details", TALER_json_from_data (&wr,
|
||||
sizeof (wr)),
|
||||
"amount", TALER_json_from_amount (&value)));
|
||||
break;
|
||||
}
|
||||
|
@ -103,40 +103,6 @@ TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a signature (with purpose) to a JSON object representation.
|
||||
*
|
||||
* @param purpose purpose of the signature
|
||||
* @param signature the signature
|
||||
* @return the JSON reporesentation of the signature with purpose
|
||||
*/
|
||||
json_t *
|
||||
TALER_json_from_eddsa_sig (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
|
||||
const struct GNUNET_CRYPTO_EddsaSignature *signature)
|
||||
{
|
||||
json_t *root;
|
||||
json_t *el;
|
||||
|
||||
root = json_object ();
|
||||
|
||||
el = json_integer ((json_int_t) ntohl (purpose->size));
|
||||
json_object_set_new (root, "size", el);
|
||||
|
||||
el = json_integer ((json_int_t) ntohl (purpose->purpose));
|
||||
json_object_set_new (root, "purpose", el);
|
||||
|
||||
el = TALER_json_from_data (purpose,
|
||||
ntohl (purpose->size));
|
||||
json_object_set_new (root, "eddsa_val", el);
|
||||
|
||||
el = TALER_json_from_data (signature,
|
||||
sizeof (struct GNUNET_CRYPTO_EddsaSignature));
|
||||
json_object_set_new (root, "eddsa_sig", el);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert RSA public key to JSON.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user