diff options
Diffstat (limited to 'src/json')
-rw-r--r-- | src/json/Makefile.am | 18 | ||||
-rw-r--r-- | src/json/json.c | 234 | ||||
-rw-r--r-- | src/json/json_helper.c | 804 | ||||
-rw-r--r-- | src/json/json_pack.c | 148 | ||||
-rw-r--r-- | src/json/json_wire.c | 74 | ||||
-rw-r--r-- | src/json/test_json.c | 3 | ||||
-rw-r--r-- | src/json/test_json_wire.c | 80 |
7 files changed, 768 insertions, 593 deletions
diff --git a/src/json/Makefile.am b/src/json/Makefile.am index 2f5ec3f17..ce863cb7e 100644 --- a/src/json/Makefile.am +++ b/src/json/Makefile.am @@ -16,7 +16,7 @@ libtalerjson_la_SOURCES = \ json_pack.c \ json_wire.c libtalerjson_la_LDFLAGS = \ - -version-info 1:0:1 \ + -version-info 3:0:1 \ -no-undefined libtalerjson_la_LIBADD = \ $(top_builddir)/src/util/libtalerutil.la \ @@ -28,12 +28,10 @@ libtalerjson_la_LIBADD = \ $(XLIB) TESTS = \ - test_json \ - test_json_wire + test_json check_PROGRAMS= \ - test_json \ - test_json_wire + test_json test_json_SOURCES = \ test_json.c @@ -43,13 +41,3 @@ test_json_LDADD = \ $(top_builddir)/src/util/libtalerutil.la \ -lgnunetutil \ -ljansson - - -test_json_wire_SOURCES = \ - test_json_wire.c -test_json_wire_LDADD = \ - $(top_builddir)/src/json/libtalerjson.la \ - -lgnunetjson \ - $(top_builddir)/src/util/libtalerutil.la \ - -lgnunetutil \ - -ljansson diff --git a/src/json/json.c b/src/json/json.c index d4ac37489..639bd530c 100644 --- a/src/json/json.c +++ b/src/json/json.c @@ -62,170 +62,6 @@ contains_real (const json_t *json) /** - * Dump character in the low range into @a buf - * following RFC 8785. - * - * @param[in,out] buf buffer to modify - * @param val value to dump - */ -static void -lowdump (struct GNUNET_Buffer *buf, - unsigned char val) -{ - char scratch[7]; - - switch (val) - { - case 0x8: - GNUNET_buffer_write (buf, - "\\b", - 2); - break; - case 0x9: - GNUNET_buffer_write (buf, - "\\t", - 2); - break; - case 0xA: - GNUNET_buffer_write (buf, - "\\n", - 2); - break; - case 0xC: - GNUNET_buffer_write (buf, - "\\f", - 2); - break; - case 0xD: - GNUNET_buffer_write (buf, - "\\r", - 2); - break; - default: - GNUNET_snprintf (scratch, - sizeof (scratch), - "\\u%04x", - (unsigned int) val); - GNUNET_buffer_write (buf, - scratch, - 6); - break; - } -} - - -/** - * Re-encode string at @a inp to match RFC 8785 (section 3.2.2.2). - * - * @param[in,out] inp pointer to string to re-encode - * @return number of bytes in resulting @a inp - */ -static size_t -rfc8785encode (char **inp) -{ - struct GNUNET_Buffer buf = { 0 }; - size_t left = strlen (*inp) + 1; - size_t olen; - char *in = *inp; - const char *pos = in; - - GNUNET_buffer_prealloc (&buf, - left + 40); - buf.warn_grow = 0; /* disable, + 40 is just a wild guess */ - while (1) - { - int mbl = u8_mblen ((unsigned char *) pos, - left); - unsigned char val; - - if (0 == mbl) - break; - val = (unsigned char) *pos; - if ( (1 == mbl) && - (val <= 0x1F) ) - { - /* Should not happen, as input is produced by - * JSON stringification */ - GNUNET_break (0); - lowdump (&buf, - val); - } - else if ( (1 == mbl) && ('\\' == *pos) ) - { - switch (*(pos + 1)) - { - case '\\': - mbl = 2; - GNUNET_buffer_write (&buf, - pos, - mbl); - break; - case 'u': - { - unsigned int num; - uint32_t n32; - unsigned char res[8]; - size_t rlen; - - GNUNET_assert ( (1 == - sscanf (pos + 2, - "%4x", - &num)) || - (1 == - sscanf (pos + 2, - "%4X", - &num)) ); - mbl = 6; - n32 = (uint32_t) num; - rlen = sizeof (res); - u32_to_u8 (&n32, - 1, - res, - &rlen); - if ( (1 == rlen) && - (res[0] <= 0x1F) ) - { - lowdump (&buf, - res[0]); - } - else - { - GNUNET_buffer_write (&buf, - (const char *) res, - rlen); - } - } - break; - default: - mbl = 2; - GNUNET_buffer_write (&buf, - pos, - mbl); - break; - } - } - else - { - GNUNET_buffer_write (&buf, - pos, - mbl); - } - left -= mbl; - pos += mbl; - } - - /* 0-terminate buffer */ - GNUNET_buffer_write (&buf, - "", - 1); - GNUNET_free (in); - *inp = GNUNET_buffer_reap (&buf, - &olen); - return olen; -} - - -/** * Dump the @a json to a string and hash it. * * @param json value to hash @@ -262,7 +98,7 @@ dump_and_hash (const json_t *json, GNUNET_break (0); return GNUNET_SYSERR; } - len = rfc8785encode (&wire_enc); + len = TALER_rfc8785encode (&wire_enc); if (NULL == salt) { GNUNET_CRYPTO_hash (wire_enc, @@ -697,7 +533,7 @@ TALER_JSON_contract_part_forget (json_t *json, /** - * Look over all of the values of a '$forgettable' object. Replace 'True' + * Loop over all of the values of a '$forgettable' object. Replace 'True' * values with proper random salts. Fails if any forgettable values are * neither 'True' nor valid salts (strings). * @@ -742,51 +578,64 @@ seed_forgettable (json_t *f) } -/** - * Take a given contract with "forgettable" fields marked - * but with 'True' instead of a real salt. Replaces all - * 'True' values with proper random salts. Fails if any - * forgettable markers are neither 'True' nor valid salts. - * - * @param[in,out] json JSON to transform - * @return #GNUNET_OK on success - */ enum GNUNET_GenericReturnValue -TALER_JSON_contract_seed_forgettable (json_t *json) +TALER_JSON_contract_seed_forgettable (const json_t *spec, + json_t *contract) { - if (json_is_object (json)) + if (json_is_object (spec)) { const char *key; json_t *val; - json_object_foreach (json, + json_object_foreach ((json_t *) spec, key, val) { + json_t *cval = json_object_get (contract, + key); + if (0 == strcmp ("$forgettable", key)) { + json_t *xval = json_deep_copy (val); + if (GNUNET_OK != - seed_forgettable (val)) + seed_forgettable (xval)) + { + json_decref (xval); return GNUNET_SYSERR; + } + GNUNET_assert (0 == + json_object_set_new (contract, + "$forgettable", + xval)); continue; } + if (NULL == cval) + continue; if (GNUNET_OK != - TALER_JSON_contract_seed_forgettable (val)) + TALER_JSON_contract_seed_forgettable (val, + cval)) return GNUNET_SYSERR; } } - if (json_is_array (json)) + if (json_is_array (spec)) { size_t index; json_t *val; - json_array_foreach (json, + json_array_foreach ((json_t *) spec, index, val) { + json_t *ival = json_array_get (contract, + index); + + if (NULL == ival) + continue; if (GNUNET_OK != - TALER_JSON_contract_seed_forgettable (val)) + TALER_JSON_contract_seed_forgettable (val, + ival)) return GNUNET_SYSERR; } } @@ -819,6 +668,7 @@ parse_path (json_t *obj, json_t *next_obj = NULL; char *next_dot; + GNUNET_assert (NULL != id); /* make stupid compiler happy */ if (NULL == next_id) { cb (cb_cls, @@ -1008,12 +858,12 @@ TALER_JSON_get_error_code2 (const void *data, void -TALER_deposit_extension_hash (const json_t *extensions, - struct TALER_ExtensionContractHashP *ech) +TALER_deposit_policy_hash (const json_t *policy, + struct TALER_ExtensionPolicyHashP *ech) { GNUNET_assert (GNUNET_OK == - dump_and_hash (extensions, - "taler-contract-extensions", + dump_and_hash (policy, + "taler-extensions-policy", &ech->hash)); } @@ -1031,17 +881,17 @@ TALER_JSON_canonicalize (const json_t *input) GNUNET_break (0); return NULL; } - rfc8785encode (&wire_enc); + TALER_rfc8785encode (&wire_enc); return wire_enc; } enum GNUNET_GenericReturnValue -TALER_JSON_extensions_config_hash (const json_t *config, - struct TALER_ExtensionConfigHashP *ech) +TALER_JSON_extensions_manifests_hash (const json_t *manifests, + struct TALER_ExtensionManifestsHashP *ech) { - return dump_and_hash (config, - "taler-extension-configuration", + return dump_and_hash (manifests, + "taler-extensions-manifests", &ech->hash); } diff --git a/src/json/json_helper.c b/src/json/json_helper.c index 1db65ff66..0a533610b 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2021 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA 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 @@ -32,20 +32,20 @@ * @param cipher_s input string * @return numeric cipher value */ -static enum TALER_DenominationCipher +static enum GNUNET_CRYPTO_BlindSignatureAlgorithm string_to_cipher (const char *cipher_s) { if ((0 == strcasecmp (cipher_s, "RSA")) || (0 == strcasecmp (cipher_s, "RSA+age_restricted"))) - return TALER_DENOMINATION_RSA; + return GNUNET_CRYPTO_BSA_RSA; if ((0 == strcasecmp (cipher_s, "CS")) || (0 == strcasecmp (cipher_s, "CS+age_restricted"))) - return TALER_DENOMINATION_CS; - return TALER_DENOMINATION_INVALID; + return GNUNET_CRYPTO_BSA_CS; + return GNUNET_CRYPTO_BSA_INVALID; } @@ -64,17 +64,6 @@ TALER_JSON_from_amount (const struct TALER_Amount *amount) } -json_t * -TALER_JSON_from_amount_nbo (const struct TALER_AmountNBO *amount) -{ - struct TALER_Amount a; - - TALER_amount_ntoh (&a, - amount); - return TALER_JSON_from_amount (&a); -} - - /** * Parse given JSON object to Amount * @@ -160,7 +149,7 @@ TALER_JSON_spec_amount_any (const char *name, /** - * Parse given JSON object to Amount in NBO. + * Parse given JSON object to currency spec. * * @param cls closure, NULL * @param root the json object representing data @@ -168,77 +157,119 @@ TALER_JSON_spec_amount_any (const char *name, * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error */ static enum GNUNET_GenericReturnValue -parse_amount_nbo (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) +parse_cspec (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) { - const char *currency = cls; - struct TALER_AmountNBO *r_amount = spec->ptr; - const char *sv; + struct TALER_CurrencySpecification *r_cspec = spec->ptr; + const char *currency = spec->cls; + const char *name; + uint32_t fid; + uint32_t fnd; + uint32_t ftzd; + const json_t *map; + struct GNUNET_JSON_Specification gspec[] = { + GNUNET_JSON_spec_string ("name", + &name), + GNUNET_JSON_spec_uint32 ("num_fractional_input_digits", + &fid), + GNUNET_JSON_spec_uint32 ("num_fractional_normal_digits", + &fnd), + GNUNET_JSON_spec_uint32 ("num_fractional_trailing_zero_digits", + &ftzd), + GNUNET_JSON_spec_object_const ("alt_unit_names", + &map), + GNUNET_JSON_spec_end () + }; + const char *emsg; + unsigned int eline; - (void) cls; - if (! json_is_string (root)) + memset (r_cspec->currency, + 0, + sizeof (r_cspec->currency)); + if (GNUNET_OK != + GNUNET_JSON_parse (root, + gspec, + &emsg, + &eline)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to parse %s at %u: %s\n", + spec[eline].field, + eline, + emsg); + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + if (strlen (currency) >= TALER_CURRENCY_LEN) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + if ( (fid > TALER_AMOUNT_FRAC_LEN) || + (fnd > TALER_AMOUNT_FRAC_LEN) || + (ftzd > TALER_AMOUNT_FRAC_LEN) ) { - GNUNET_break (0); + GNUNET_break_op (0); return GNUNET_SYSERR; } - sv = json_string_value (root); if (GNUNET_OK != - TALER_string_to_amount_nbo (sv, - r_amount)) + TALER_check_currency (currency)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "`%s' is not a valid amount\n", - sv); GNUNET_break_op (0); return GNUNET_SYSERR; } - if ( (NULL != currency) && - (0 != - strcasecmp (currency, - r_amount->currency)) ) + strcpy (r_cspec->currency, + currency); + if (GNUNET_OK != + TALER_check_currency_scale_map (map)) { GNUNET_break_op (0); return GNUNET_SYSERR; } + r_cspec->name = GNUNET_strdup (name); + r_cspec->map_alt_unit_names = json_incref ((json_t *) map); return GNUNET_OK; } -struct GNUNET_JSON_Specification -TALER_JSON_spec_amount_nbo (const char *name, - const char *currency, - struct TALER_AmountNBO *r_amount) +/** + * Cleanup data left from parsing encrypted contract. + * + * @param cls closure, NULL + * @param[out] spec where to free the data + */ +static void +clean_cspec (void *cls, + struct GNUNET_JSON_Specification *spec) { - struct GNUNET_JSON_Specification ret = { - .parser = &parse_amount_nbo, - .cleaner = NULL, - .cls = (void *) currency, - .field = name, - .ptr = r_amount, - .ptr_size = 0, - .size_ptr = NULL - }; + struct TALER_CurrencySpecification *cspec = spec->ptr; - GNUNET_assert (NULL != currency); - return ret; + (void) cls; + GNUNET_free (cspec->name); + json_decref (cspec->map_alt_unit_names); } struct GNUNET_JSON_Specification -TALER_JSON_spec_amount_any_nbo (const char *name, - struct TALER_AmountNBO *r_amount) +TALER_JSON_spec_currency_specification ( + const char *name, + const char *currency, + struct TALER_CurrencySpecification *r_cspec) { struct GNUNET_JSON_Specification ret = { - .parser = &parse_amount_nbo, - .cleaner = NULL, - .cls = NULL, + .parser = &parse_cspec, + .cleaner = &clean_cspec, + .cls = (void *) currency, .field = name, - .ptr = r_amount, - .ptr_size = 0, + .ptr = r_cspec, + .ptr_size = sizeof (*r_cspec), .size_ptr = NULL }; + memset (r_cspec, + 0, + sizeof (*r_cspec)); return ret; } @@ -266,8 +297,6 @@ parse_denomination_group (void *cls, GNUNET_JSON_spec_uint32 ("age_mask", &group->age_mask.bits), &age_mask_missing), - GNUNET_JSON_spec_fixed_auto ("hash", - &group->hash), GNUNET_JSON_spec_end () }; const char *emsg; @@ -279,12 +308,17 @@ parse_denomination_group (void *cls, &emsg, &eline)) { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to parse %s at %u: %s\n", + spec[eline].field, + eline, + emsg); GNUNET_break_op (0); return GNUNET_SYSERR; } group->cipher = string_to_cipher (cipher); - if (TALER_DENOMINATION_INVALID == group->cipher) + if (GNUNET_CRYPTO_BSA_INVALID == group->cipher) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -314,11 +348,9 @@ TALER_JSON_spec_denomination_group (const char *name, struct GNUNET_JSON_Specification ret = { .cls = (void *) currency, .parser = &parse_denomination_group, - .cleaner = NULL, .field = name, .ptr = group, - .ptr_size = sizeof(*group), - .size_ptr = NULL, + .ptr_size = sizeof(*group) }; return ret; @@ -390,11 +422,8 @@ TALER_JSON_spec_econtract (const char *name, struct GNUNET_JSON_Specification ret = { .parser = &parse_econtract, .cleaner = &clean_econtract, - .cls = NULL, .field = name, - .ptr = econtract, - .ptr_size = 0, - .size_ptr = NULL + .ptr = econtract }; return ret; @@ -419,7 +448,9 @@ parse_age_commitment (void *cls, unsigned int idx; size_t num; - if (NULL == root || ! json_is_array (root)) + (void) cls; + if ( (NULL == root) || + (! json_is_array (root))) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -464,7 +495,7 @@ parse_age_commitment (void *cls, /** - * Cleanup data left fom parsing age commitment + * Cleanup data left from parsing age commitment * * @param cls closure, NULL * @param[out] spec where to free the data @@ -493,11 +524,8 @@ TALER_JSON_spec_age_commitment (const char *name, struct GNUNET_JSON_Specification ret = { .parser = &parse_age_commitment, .cleaner = &clean_age_commitment, - .cls = NULL, .field = name, - .ptr = age_commitment, - .ptr_size = 0, - .size_ptr = NULL + .ptr = age_commitment }; return ret; @@ -518,6 +546,7 @@ parse_denom_pub (void *cls, struct GNUNET_JSON_Specification *spec) { struct TALER_DenominationPublicKey *denom_pub = spec->ptr; + struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub; const char *cipher; bool age_mask_missing = false; struct GNUNET_JSON_Specification dspec[] = { @@ -545,16 +574,19 @@ parse_denom_pub (void *cls, if (age_mask_missing) denom_pub->age_mask.bits = 0; - - denom_pub->cipher = string_to_cipher (cipher); - switch (denom_pub->cipher) + bsign_pub = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey); + bsign_pub->rc = 1; + bsign_pub->cipher = string_to_cipher (cipher); + switch (bsign_pub->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_rsa_public_key ( "rsa_public_key", - &denom_pub->details.rsa_public_key), + &bsign_pub->details.rsa_public_key), GNUNET_JSON_spec_end () }; @@ -565,16 +597,18 @@ parse_denom_pub (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (bsign_pub); return GNUNET_SYSERR; } + denom_pub->bsign_pub_key = bsign_pub; return GNUNET_OK; } - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed ("cs_public_key", - &denom_pub->details.cs_public_key, - sizeof (denom_pub->details.cs_public_key)), + &bsign_pub->details.cs_public_key, + sizeof (bsign_pub->details.cs_public_key)), GNUNET_JSON_spec_end () }; @@ -585,14 +619,16 @@ parse_denom_pub (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (bsign_pub); return GNUNET_SYSERR; } + denom_pub->bsign_pub_key = bsign_pub; return GNUNET_OK; } - default: - GNUNET_break_op (0); - return GNUNET_SYSERR; } + GNUNET_break_op (0); + GNUNET_free (bsign_pub); + return GNUNET_SYSERR; } @@ -624,7 +660,7 @@ TALER_JSON_spec_denom_pub (const char *field, .ptr = pk }; - pk->cipher = TALER_DENOMINATION_INVALID; + pk->bsign_pub_key = NULL; return ret; } @@ -634,7 +670,7 @@ TALER_JSON_spec_denom_pub (const char *field, * * Depending on the cipher in cls, it parses the corresponding public key type. * - * @param cls closure, enum TALER_DenominationCipher + * @param cls closure, enum GNUNET_CRYPTO_BlindSignatureAlgorithm * @param root the json object representing data * @param[out] spec where to write the data * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error @@ -645,18 +681,25 @@ parse_denom_pub_cipher (void *cls, struct GNUNET_JSON_Specification *spec) { struct TALER_DenominationPublicKey *denom_pub = spec->ptr; - enum TALER_DenominationCipher cipher = (enum TALER_DenominationCipher) cls; + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher = + (enum GNUNET_CRYPTO_BlindSignatureAlgorithm) (long) cls; + struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub; const char *emsg; unsigned int eline; + bsign_pub = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey); + bsign_pub->cipher = cipher; + bsign_pub->rc = 1; switch (cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_rsa_public_key ( "rsa_pub", - &denom_pub->details.rsa_public_key), + &bsign_pub->details.rsa_public_key), GNUNET_JSON_spec_end () }; @@ -667,16 +710,18 @@ parse_denom_pub_cipher (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (bsign_pub); return GNUNET_SYSERR; } + denom_pub->bsign_pub_key = bsign_pub; return GNUNET_OK; } - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed ("cs_pub", - &denom_pub->details.cs_public_key, - sizeof (denom_pub->details.cs_public_key)), + &bsign_pub->details.cs_public_key, + sizeof (bsign_pub->details.cs_public_key)), GNUNET_JSON_spec_end () }; @@ -687,20 +732,23 @@ parse_denom_pub_cipher (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (bsign_pub); return GNUNET_SYSERR; } + denom_pub->bsign_pub_key = bsign_pub; return GNUNET_OK; } - default: - GNUNET_break_op (0); - return GNUNET_SYSERR; } + GNUNET_break_op (0); + GNUNET_free (bsign_pub); + return GNUNET_SYSERR; } struct GNUNET_JSON_Specification TALER_JSON_spec_denom_pub_cipher (const char *field, - enum TALER_DenominationCipher cipher, + enum GNUNET_CRYPTO_BlindSignatureAlgorithm + cipher, struct TALER_DenominationPublicKey *pk) { struct GNUNET_JSON_Specification ret = { @@ -729,6 +777,7 @@ parse_denom_sig (void *cls, struct GNUNET_JSON_Specification *spec) { struct TALER_DenominationSignature *denom_sig = spec->ptr; + struct GNUNET_CRYPTO_UnblindedSignature *unblinded_sig; const char *cipher; struct GNUNET_JSON_Specification dspec[] = { GNUNET_JSON_spec_string ("cipher", @@ -748,15 +797,19 @@ parse_denom_sig (void *cls, GNUNET_break_op (0); return GNUNET_SYSERR; } - denom_sig->cipher = string_to_cipher (cipher); - switch (denom_sig->cipher) + unblinded_sig = GNUNET_new (struct GNUNET_CRYPTO_UnblindedSignature); + unblinded_sig->cipher = string_to_cipher (cipher); + unblinded_sig->rc = 1; + switch (unblinded_sig->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_rsa_signature ( "rsa_signature", - &denom_sig->details.rsa_signature), + &unblinded_sig->details.rsa_signature), GNUNET_JSON_spec_end () }; @@ -767,17 +820,21 @@ parse_denom_sig (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (unblinded_sig); return GNUNET_SYSERR; } + denom_sig->unblinded_sig = unblinded_sig; return GNUNET_OK; } - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed_auto ("cs_signature_r", - &denom_sig->details.cs_signature.r_point), + &unblinded_sig->details.cs_signature. + r_point), GNUNET_JSON_spec_fixed_auto ("cs_signature_s", - &denom_sig->details.cs_signature.s_scalar), + &unblinded_sig->details.cs_signature. + s_scalar), GNUNET_JSON_spec_end () }; @@ -788,14 +845,16 @@ parse_denom_sig (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (unblinded_sig); return GNUNET_SYSERR; } + denom_sig->unblinded_sig = unblinded_sig; return GNUNET_OK; } - default: - GNUNET_break_op (0); - return GNUNET_SYSERR; } + GNUNET_break_op (0); + GNUNET_free (unblinded_sig); + return GNUNET_SYSERR; } @@ -827,7 +886,7 @@ TALER_JSON_spec_denom_sig (const char *field, .ptr = sig }; - sig->cipher = TALER_DENOMINATION_INVALID; + sig->unblinded_sig = NULL; return ret; } @@ -846,6 +905,7 @@ parse_blinded_denom_sig (void *cls, struct GNUNET_JSON_Specification *spec) { struct TALER_BlindedDenominationSignature *denom_sig = spec->ptr; + struct GNUNET_CRYPTO_BlindedSignature *blinded_sig; const char *cipher; struct GNUNET_JSON_Specification dspec[] = { GNUNET_JSON_spec_string ("cipher", @@ -865,15 +925,19 @@ parse_blinded_denom_sig (void *cls, GNUNET_break_op (0); return GNUNET_SYSERR; } - denom_sig->cipher = string_to_cipher (cipher); - switch (denom_sig->cipher) + blinded_sig = GNUNET_new (struct GNUNET_CRYPTO_BlindedSignature); + blinded_sig->cipher = string_to_cipher (cipher); + blinded_sig->rc = 1; + switch (blinded_sig->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_rsa_signature ( "blinded_rsa_signature", - &denom_sig->details.blinded_rsa_signature), + &blinded_sig->details.blinded_rsa_signature), GNUNET_JSON_spec_end () }; @@ -884,17 +948,19 @@ parse_blinded_denom_sig (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (blinded_sig); return GNUNET_SYSERR; } + denom_sig->blinded_sig = blinded_sig; return GNUNET_OK; } - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_uint32 ("b", - &denom_sig->details.blinded_cs_answer.b), + &blinded_sig->details.blinded_cs_answer.b), GNUNET_JSON_spec_fixed_auto ("s", - &denom_sig->details.blinded_cs_answer. + &blinded_sig->details.blinded_cs_answer. s_scalar), GNUNET_JSON_spec_end () }; @@ -906,15 +972,16 @@ parse_blinded_denom_sig (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (blinded_sig); return GNUNET_SYSERR; } + denom_sig->blinded_sig = blinded_sig; return GNUNET_OK; } - break; - default: - GNUNET_break_op (0); - return GNUNET_SYSERR; } + GNUNET_break_op (0); + GNUNET_free (blinded_sig); + return GNUNET_SYSERR; } @@ -947,7 +1014,7 @@ TALER_JSON_spec_blinded_denom_sig ( .ptr = sig }; - sig->cipher = TALER_DENOMINATION_INVALID; + sig->blinded_sig = NULL; return ret; } @@ -966,6 +1033,7 @@ parse_blinded_planchet (void *cls, struct GNUNET_JSON_Specification *spec) { struct TALER_BlindedPlanchet *blinded_planchet = spec->ptr; + struct GNUNET_CRYPTO_BlindedMessage *blinded_message; const char *cipher; struct GNUNET_JSON_Specification dspec[] = { GNUNET_JSON_spec_string ("cipher", @@ -985,16 +1053,20 @@ parse_blinded_planchet (void *cls, GNUNET_break_op (0); return GNUNET_SYSERR; } - blinded_planchet->cipher = string_to_cipher (cipher); - switch (blinded_planchet->cipher) + blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage); + blinded_message->rc = 1; + blinded_message->cipher = string_to_cipher (cipher); + switch (blinded_message->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_varsize ( "rsa_blinded_planchet", - &blinded_planchet->details.rsa_blinded_planchet.blinded_msg, - &blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size), + &blinded_message->details.rsa_blinded_message.blinded_msg, + &blinded_message->details.rsa_blinded_message.blinded_msg_size), GNUNET_JSON_spec_end () }; @@ -1005,22 +1077,24 @@ parse_blinded_planchet (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (blinded_message); return GNUNET_SYSERR; } + blinded_planchet->blinded_message = blinded_message; return GNUNET_OK; } - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed_auto ( "cs_nonce", - &blinded_planchet->details.cs_blinded_planchet.nonce), + &blinded_message->details.cs_blinded_message.nonce), GNUNET_JSON_spec_fixed_auto ( "cs_blinded_c0", - &blinded_planchet->details.cs_blinded_planchet.c[0]), + &blinded_message->details.cs_blinded_message.c[0]), GNUNET_JSON_spec_fixed_auto ( "cs_blinded_c1", - &blinded_planchet->details.cs_blinded_planchet.c[1]), + &blinded_message->details.cs_blinded_message.c[1]), GNUNET_JSON_spec_end () }; @@ -1031,15 +1105,16 @@ parse_blinded_planchet (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (blinded_message); return GNUNET_SYSERR; } + blinded_planchet->blinded_message = blinded_message; return GNUNET_OK; } - break; - default: - GNUNET_break_op (0); - return GNUNET_SYSERR; } + GNUNET_break_op (0); + GNUNET_free (blinded_message); + return GNUNET_SYSERR; } @@ -1071,7 +1146,7 @@ TALER_JSON_spec_blinded_planchet (const char *field, .ptr = blinded_planchet }; - blinded_planchet->cipher = TALER_DENOMINATION_INVALID; + blinded_planchet->blinded_message = NULL; return ret; } @@ -1090,6 +1165,7 @@ parse_exchange_withdraw_values (void *cls, struct GNUNET_JSON_Specification *spec) { struct TALER_ExchangeWithdrawValues *ewv = spec->ptr; + struct GNUNET_CRYPTO_BlindingInputValues *bi; const char *cipher; struct GNUNET_JSON_Specification dspec[] = { GNUNET_JSON_spec_string ("cipher", @@ -1098,6 +1174,7 @@ parse_exchange_withdraw_values (void *cls, }; const char *emsg; unsigned int eline; + enum GNUNET_CRYPTO_BlindSignatureAlgorithm ci; (void) cls; if (GNUNET_OK != @@ -1109,21 +1186,27 @@ parse_exchange_withdraw_values (void *cls, GNUNET_break_op (0); return GNUNET_SYSERR; } - ewv->cipher = string_to_cipher (cipher); - switch (ewv->cipher) + ci = string_to_cipher (cipher); + switch (ci) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: + ewv->blinding_inputs = TALER_denom_ewv_rsa_singleton ()->blinding_inputs; return GNUNET_OK; - case TALER_DENOMINATION_CS: + case GNUNET_CRYPTO_BSA_CS: + bi = GNUNET_new (struct GNUNET_CRYPTO_BlindingInputValues); + bi->cipher = GNUNET_CRYPTO_BSA_CS; + bi->rc = 1; { struct GNUNET_JSON_Specification ispec[] = { GNUNET_JSON_spec_fixed ( "r_pub_0", - &ewv->details.cs_values.r_pub[0], + &bi->details.cs_values.r_pub[0], sizeof (struct GNUNET_CRYPTO_CsRPublic)), GNUNET_JSON_spec_fixed ( "r_pub_1", - &ewv->details.cs_values.r_pub[1], + &bi->details.cs_values.r_pub[1], sizeof (struct GNUNET_CRYPTO_CsRPublic)), GNUNET_JSON_spec_end () }; @@ -1135,14 +1218,33 @@ parse_exchange_withdraw_values (void *cls, &eline)) { GNUNET_break_op (0); + GNUNET_free (bi); return GNUNET_SYSERR; } + ewv->blinding_inputs = bi; return GNUNET_OK; } - default: - GNUNET_break_op (0); - return GNUNET_SYSERR; } + GNUNET_break_op (0); + return GNUNET_SYSERR; +} + + +/** + * Cleanup data left from parsing withdraw values + * + * @param cls closure, NULL + * @param[out] spec where to free the data + */ +static void +clean_exchange_withdraw_values ( + void *cls, + struct GNUNET_JSON_Specification *spec) +{ + struct TALER_ExchangeWithdrawValues *ewv = spec->ptr; + + (void) cls; + TALER_denom_ewv_free (ewv); } @@ -1153,11 +1255,12 @@ TALER_JSON_spec_exchange_withdraw_values ( { struct GNUNET_JSON_Specification ret = { .parser = &parse_exchange_withdraw_values, + .cleaner = &clean_exchange_withdraw_values, .field = field, .ptr = ewv }; - ewv->cipher = TALER_DENOMINATION_INVALID; + ewv->blinding_inputs = NULL; return ret; } @@ -1234,11 +1337,6 @@ parse_i18n_string (void *cls, const char *str; str = json_string_value (val); - if (NULL == str) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } *(const char **) spec->ptr = str; } return GNUNET_OK; @@ -1258,8 +1356,11 @@ i18n_cleaner (void *cls, struct I18nContext *ctx = cls; (void) spec; - GNUNET_free (ctx->lp); - GNUNET_free (ctx); + if (NULL != ctx) + { + GNUNET_free (ctx->lp); + GNUNET_free (ctx); + } } @@ -1279,8 +1380,9 @@ TALER_JSON_spec_i18n_string (const char *name, .size_ptr = NULL }; - ctx->lp = (NULL != language_pattern) ? GNUNET_strdup (language_pattern) : - NULL; + ctx->lp = (NULL != language_pattern) + ? GNUNET_strdup (language_pattern) + : NULL; ctx->field = name; *strptr = NULL; return ret; @@ -1318,4 +1420,400 @@ TALER_JSON_spec_i18n_str (const char *name, } +/** + * Parse given JSON object with Taler error code. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_ec (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + enum TALER_ErrorCode *ec = spec->ptr; + json_int_t num; + + (void) cls; + if (! json_is_integer (root)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + num = json_integer_value (root); + if (num < 0) + { + GNUNET_break_op (0); + *ec = TALER_EC_INVALID; + return GNUNET_SYSERR; + } + *ec = (enum TALER_ErrorCode) num; + return GNUNET_OK; +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_ec (const char *field, + enum TALER_ErrorCode *ec) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_ec, + .field = field, + .ptr = ec + }; + + *ec = TALER_EC_NONE; + return ret; +} + + +/** + * Parse given JSON object with AML decision. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_aml_decision (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + enum TALER_AmlDecisionState *aml = spec->ptr; + json_int_t num; + + (void) cls; + if (! json_is_integer (root)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + num = json_integer_value (root); + if ( (num > TALER_AML_MAX) || + (num < 0) ) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + *aml = (enum TALER_AmlDecisionState) num; + return GNUNET_OK; +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_aml_decision (const char *field, + enum TALER_AmlDecisionState *aml_state) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_aml_decision, + .field = field, + .ptr = aml_state + }; + + return ret; +} + + +/** + * Parse given JSON object to web URL. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_web_url (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + const char *str; + + (void) cls; + str = json_string_value (root); + if (NULL == str) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + if (! TALER_is_web_url (str)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + *(const char **) spec->ptr = str; + return GNUNET_OK; +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_web_url (const char *field, + const char **url) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_web_url, + .field = field, + .ptr = url + }; + + *url = NULL; + return ret; +} + + +/** + * Parse given JSON object to payto:// URI. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_payto_uri (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + const char *str; + char *err; + + (void) cls; + str = json_string_value (root); + if (NULL == str) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + err = TALER_payto_validate (str); + if (NULL != err) + { + GNUNET_break_op (0); + GNUNET_free (err); + return GNUNET_SYSERR; + } + *(const char **) spec->ptr = str; + return GNUNET_OK; +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_payto_uri (const char *field, + const char **payto_uri) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_payto_uri, + .field = field, + .ptr = payto_uri + }; + + *payto_uri = NULL; + return ret; +} + + +/** + * Parse given JSON object with protocol version. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_protocol_version (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + struct TALER_JSON_ProtocolVersion *pv = spec->ptr; + const char *ver; + char dummy; + + (void) cls; + if (! json_is_string (root)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + ver = json_string_value (root); + if (3 != sscanf (ver, + "%u:%u:%u%c", + &pv->current, + &pv->revision, + &pv->age, + &dummy)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_version (const char *field, + struct TALER_JSON_ProtocolVersion *ver) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_protocol_version, + .field = field, + .ptr = ver + }; + + return ret; +} + + +/** + * Parse given JSON object to an OTP key. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_otp_key (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + const char *pos_key; + + (void) cls; + pos_key = json_string_value (root); + if (NULL == pos_key) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + { + size_t pos_key_length = strlen (pos_key); + void *key; /* pos_key in binary */ + size_t key_len; /* length of the key */ + int dret; + + key_len = pos_key_length * 5 / 8; + key = GNUNET_malloc (key_len); + dret = TALER_rfc3548_base32decode (pos_key, + pos_key_length, + key, + key_len); + if (-1 == dret) + { + GNUNET_free (key); + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + GNUNET_free (key); + } + *(const char **) spec->ptr = pos_key; + return GNUNET_OK; +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_otp_key (const char *name, + const char **otp_key) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_otp_key, + .field = name, + .ptr = otp_key + }; + + *otp_key = NULL; + return ret; +} + + +/** + * Parse given JSON object to `enum TALER_MerchantConfirmationAlgorithm` + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static enum GNUNET_GenericReturnValue +parse_otp_type (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + static const struct Entry + { + const char *name; + enum TALER_MerchantConfirmationAlgorithm val; + } lt [] = { + { .name = "NONE", + .val = TALER_MCA_NONE }, + { .name = "TOTP_WITHOUT_PRICE", + .val = TALER_MCA_WITHOUT_PRICE }, + { .name = "TOTP_WITH_PRICE", + .val = TALER_MCA_WITH_PRICE }, + { .name = NULL, + .val = TALER_MCA_NONE }, + }; + enum TALER_MerchantConfirmationAlgorithm *res + = (enum TALER_MerchantConfirmationAlgorithm *) spec->ptr; + + (void) cls; + if (json_is_string (root)) + { + const char *str; + + str = json_string_value (root); + if (NULL == str) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + for (unsigned int i = 0; NULL != lt[i].name; i++) + { + if (0 == strcasecmp (str, + lt[i].name)) + { + *res = lt[i].val; + return GNUNET_OK; + } + } + GNUNET_break_op (0); + } + if (json_is_integer (root)) + { + json_int_t val; + + val = json_integer_value (root); + for (unsigned int i = 0; NULL != lt[i].name; i++) + { + if (val == lt[i].val) + { + *res = lt[i].val; + return GNUNET_OK; + } + } + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + GNUNET_break_op (0); + return GNUNET_SYSERR; +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_otp_type (const char *name, + enum TALER_MerchantConfirmationAlgorithm *mca) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_otp_type, + .field = name, + .ptr = mca + }; + + *mca = TALER_MCA_NONE; + return ret; +} + + /* end of json/json_helper.c */ diff --git a/src/json/json_pack.c b/src/json/json_pack.c index 834e8104b..71c8db9d2 100644 --- a/src/json/json_pack.c +++ b/src/json/json_pack.c @@ -39,15 +39,6 @@ TALER_JSON_pack_time_abs_human (const char *name, struct GNUNET_JSON_PackSpec -TALER_JSON_pack_time_abs_nbo_human (const char *name, - struct GNUNET_TIME_AbsoluteNBO at) -{ - return TALER_JSON_pack_time_abs_human (name, - GNUNET_TIME_absolute_ntoh (at)); -} - - -struct GNUNET_JSON_PackSpec TALER_JSON_pack_econtract ( const char *name, const struct TALER_EncryptedContract *econtract) @@ -110,37 +101,41 @@ TALER_JSON_pack_denom_pub ( const char *name, const struct TALER_DenominationPublicKey *pk) { + const struct GNUNET_CRYPTO_BlindSignPublicKey *bsp; struct GNUNET_JSON_PackSpec ps = { .field_name = name, }; if (NULL == pk) return ps; - switch (pk->cipher) + bsp = pk->bsign_pub_key; + switch (bsp->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: ps.object = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", "RSA"), + GNUNET_JSON_pack_string ("cipher", + "RSA"), GNUNET_JSON_pack_uint64 ("age_mask", pk->age_mask.bits), GNUNET_JSON_pack_rsa_public_key ("rsa_public_key", - pk->details.rsa_public_key)); - break; - case TALER_DENOMINATION_CS: + bsp->details.rsa_public_key)); + return ps; + case GNUNET_CRYPTO_BSA_CS: ps.object = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("cipher", "CS"), + GNUNET_JSON_pack_string ("cipher", + "CS"), GNUNET_JSON_pack_uint64 ("age_mask", pk->age_mask.bits), GNUNET_JSON_pack_data_varsize ("cs_public_key", - &pk->details.cs_public_key, - sizeof (pk->details.cs_public_key))); - break; - default: - GNUNET_assert (0); + &bsp->details.cs_public_key, + sizeof (bsp->details.cs_public_key))); + return ps; } - + GNUNET_assert (0); return ps; } @@ -150,33 +145,36 @@ TALER_JSON_pack_denom_sig ( const char *name, const struct TALER_DenominationSignature *sig) { + const struct GNUNET_CRYPTO_UnblindedSignature *bs; struct GNUNET_JSON_PackSpec ps = { .field_name = name, }; if (NULL == sig) return ps; - switch (sig->cipher) + bs = sig->unblinded_sig; + switch (bs->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "RSA"), GNUNET_JSON_pack_rsa_signature ("rsa_signature", - sig->details.rsa_signature)); - break; - case TALER_DENOMINATION_CS: + bs->details.rsa_signature)); + return ps; + case GNUNET_CRYPTO_BSA_CS: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "CS"), GNUNET_JSON_pack_data_auto ("cs_signature_r", - &sig->details.cs_signature.r_point), + &bs->details.cs_signature.r_point), GNUNET_JSON_pack_data_auto ("cs_signature_s", - &sig->details.cs_signature.s_scalar)); - break; - default: - GNUNET_assert (0); + &bs->details.cs_signature.s_scalar)); + return ps; } + GNUNET_assert (0); return ps; } @@ -186,36 +184,39 @@ TALER_JSON_pack_exchange_withdraw_values ( const char *name, const struct TALER_ExchangeWithdrawValues *ewv) { + const struct GNUNET_CRYPTO_BlindingInputValues *biv; struct GNUNET_JSON_PackSpec ps = { .field_name = name, }; if (NULL == ewv) return ps; - switch (ewv->cipher) + biv = ewv->blinding_inputs; + switch (biv->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "RSA")); - break; - case TALER_DENOMINATION_CS: + return ps; + case GNUNET_CRYPTO_BSA_CS: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "CS"), GNUNET_JSON_pack_data_varsize ( "r_pub_0", - &ewv->details.cs_values.r_pub[0], + &biv->details.cs_values.r_pub[0], sizeof(struct GNUNET_CRYPTO_CsRPublic)), GNUNET_JSON_pack_data_varsize ( "r_pub_1", - &ewv->details.cs_values.r_pub[1], + &biv->details.cs_values.r_pub[1], sizeof(struct GNUNET_CRYPTO_CsRPublic)) ); - break; - default: - GNUNET_assert (0); + return ps; } + GNUNET_assert (0); return ps; } @@ -225,33 +226,36 @@ TALER_JSON_pack_blinded_denom_sig ( const char *name, const struct TALER_BlindedDenominationSignature *sig) { + const struct GNUNET_CRYPTO_BlindedSignature *bs; struct GNUNET_JSON_PackSpec ps = { .field_name = name, }; if (NULL == sig) return ps; - switch (sig->cipher) + bs = sig->blinded_sig; + switch (bs->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "RSA"), GNUNET_JSON_pack_rsa_signature ("blinded_rsa_signature", - sig->details.blinded_rsa_signature)); - break; - case TALER_DENOMINATION_CS: + bs->details.blinded_rsa_signature)); + return ps; + case GNUNET_CRYPTO_BSA_CS: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "CS"), GNUNET_JSON_pack_uint64 ("b", - sig->details.blinded_cs_answer.b), + bs->details.blinded_cs_answer.b), GNUNET_JSON_pack_data_auto ("s", - &sig->details.blinded_cs_answer.s_scalar)); - break; - default: - GNUNET_assert (0); + &bs->details.blinded_cs_answer.s_scalar)); + return ps; } + GNUNET_assert (0); return ps; } @@ -261,40 +265,43 @@ TALER_JSON_pack_blinded_planchet ( const char *name, const struct TALER_BlindedPlanchet *blinded_planchet) { + const struct GNUNET_CRYPTO_BlindedMessage *bm; struct GNUNET_JSON_PackSpec ps = { .field_name = name, }; if (NULL == blinded_planchet) return ps; - switch (blinded_planchet->cipher) + bm = blinded_planchet->blinded_message; + switch (bm->cipher) { - case TALER_DENOMINATION_RSA: + case GNUNET_CRYPTO_BSA_INVALID: + break; + case GNUNET_CRYPTO_BSA_RSA: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "RSA"), GNUNET_JSON_pack_data_varsize ( "rsa_blinded_planchet", - blinded_planchet->details.rsa_blinded_planchet.blinded_msg, - blinded_planchet->details.rsa_blinded_planchet.blinded_msg_size)); - break; - case TALER_DENOMINATION_CS: + bm->details.rsa_blinded_message.blinded_msg, + bm->details.rsa_blinded_message.blinded_msg_size)); + return ps; + case GNUNET_CRYPTO_BSA_CS: ps.object = GNUNET_JSON_PACK ( GNUNET_JSON_pack_string ("cipher", "CS"), GNUNET_JSON_pack_data_auto ( "cs_nonce", - &blinded_planchet->details.cs_blinded_planchet.nonce), + &bm->details.cs_blinded_message.nonce), GNUNET_JSON_pack_data_auto ( "cs_blinded_c0", - &blinded_planchet->details.cs_blinded_planchet.c[0]), + &bm->details.cs_blinded_message.c[0]), GNUNET_JSON_pack_data_auto ( "cs_blinded_c1", - &blinded_planchet->details.cs_blinded_planchet.c[1])); - break; - default: - GNUNET_assert (0); + &bm->details.cs_blinded_message.c[1])); + return ps; } + GNUNET_assert (0); return ps; } @@ -314,19 +321,4 @@ TALER_JSON_pack_amount (const char *name, } -struct GNUNET_JSON_PackSpec -TALER_JSON_pack_amount_nbo (const char *name, - const struct TALER_AmountNBO *amount) -{ - struct GNUNET_JSON_PackSpec ps = { - .field_name = name, - .object = (NULL != amount) - ? TALER_JSON_from_amount_nbo (amount) - : NULL - }; - - return ps; -} - - /* End of json/json_pack.c */ diff --git a/src/json/json_wire.c b/src/json/json_wire.c index 544b56453..9d22d28ea 100644 --- a/src/json/json_wire.c +++ b/src/json/json_wire.c @@ -70,80 +70,6 @@ TALER_JSON_merchant_wire_signature_hash (const json_t *wire_s, } -enum GNUNET_GenericReturnValue -TALER_JSON_exchange_wire_signature_check ( - const json_t *wire_s, - const struct TALER_MasterPublicKeyP *master_pub) -{ - const char *payto_uri; - struct TALER_MasterSignatureP master_sig; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("payto_uri", - &payto_uri), - GNUNET_JSON_spec_fixed_auto ("master_sig", - &master_sig), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (wire_s, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - - { - char *err; - - err = TALER_payto_validate (payto_uri); - if (NULL != err) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "URI `%s' ill-formed: %s\n", - payto_uri, - err); - GNUNET_free (err); - return GNUNET_SYSERR; - } - } - - return TALER_exchange_wire_signature_check (payto_uri, - master_pub, - &master_sig); -} - - -json_t * -TALER_JSON_exchange_wire_signature_make ( - const char *payto_uri, - const struct TALER_MasterPrivateKeyP *master_priv) -{ - struct TALER_MasterSignatureP master_sig; - char *err; - - if (NULL != - (err = TALER_payto_validate (payto_uri))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Invalid payto URI `%s': %s\n", - payto_uri, - err); - GNUNET_free (err); - return NULL; - } - TALER_exchange_wire_signature_make (payto_uri, - master_priv, - &master_sig); - return GNUNET_JSON_PACK ( - GNUNET_JSON_pack_string ("payto_uri", - payto_uri), - GNUNET_JSON_pack_data_auto ("master_sig", - &master_sig)); -} - - char * TALER_JSON_wire_to_payto (const json_t *wire_s) { diff --git a/src/json/test_json.c b/src/json/test_json.c index d37f66eaf..fba72f84b 100644 --- a/src/json/test_json.c +++ b/src/json/test_json.c @@ -103,7 +103,8 @@ test_contract (void) "k2", "n1", "n2", /***/ "$forgettable", "n1", true); GNUNET_assert (GNUNET_OK == - TALER_JSON_contract_seed_forgettable (c1)); + TALER_JSON_contract_seed_forgettable (c1, + c1)); GNUNET_assert (GNUNET_OK == TALER_JSON_contract_hash (c1, &h1)); diff --git a/src/json/test_json_wire.c b/src/json/test_json_wire.c deleted file mode 100644 index b417b25fe..000000000 --- a/src/json/test_json_wire.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - This file is part of TALER - (C) 2015, 2016 Taler Systems SA - - 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, see <http://www.gnu.org/licenses/> -*/ - -/** - * @file json/test_json_wire.c - * @brief Tests for Taler-specific crypto logic - * @author Christian Grothoff <christian@grothoff.org> - */ -#include "platform.h" -#include "taler_util.h" -#include "taler_json_lib.h" - - -int -main (int argc, - const char *const argv[]) -{ - struct TALER_MasterPublicKeyP master_pub; - struct TALER_MasterPrivateKeyP master_priv; - json_t *wire_xtalerbank; - json_t *wire_iban; - const char *payto_xtalerbank = "payto://x-taler-bank/42"; - const char *payto_iban = - "payto://iban/BIC-TO-BE-SKIPPED/DE89370400440532013000?receiver-name=Test"; - char *p_xtalerbank; - char *p_iban; - - (void) argc; - (void) argv; - GNUNET_log_setup ("test-json-wire", - "WARNING", - NULL); - GNUNET_CRYPTO_eddsa_key_create (&master_priv.eddsa_priv); - GNUNET_CRYPTO_eddsa_key_get_public (&master_priv.eddsa_priv, - &master_pub.eddsa_pub); - wire_xtalerbank = TALER_JSON_exchange_wire_signature_make (payto_xtalerbank, - &master_priv); - wire_iban = TALER_JSON_exchange_wire_signature_make (payto_iban, - &master_priv); - if (NULL == wire_iban) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not parse payto/IBAN (%s) into 'wire object'\n", - payto_iban); - return 1; - } - p_xtalerbank = TALER_JSON_wire_to_payto (wire_xtalerbank); - p_iban = TALER_JSON_wire_to_payto (wire_iban); - GNUNET_assert (0 == strcmp (p_xtalerbank, payto_xtalerbank)); - GNUNET_assert (0 == strcmp (p_iban, payto_iban)); - GNUNET_free (p_xtalerbank); - GNUNET_free (p_iban); - - GNUNET_assert (GNUNET_OK == - TALER_JSON_exchange_wire_signature_check (wire_xtalerbank, - &master_pub)); - GNUNET_assert (GNUNET_OK == - TALER_JSON_exchange_wire_signature_check (wire_iban, - &master_pub)); - json_decref (wire_xtalerbank); - json_decref (wire_iban); - - return 0; -} - - -/* end of test_json_wire.c */ |