diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/exchange/taler-exchange-httpd_keys.c | 4 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd_keys.h | 2 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd_refreshes_reveal.c | 19 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd_withdraw.c | 14 | ||||
| -rw-r--r-- | src/exchangedb/plugin_exchangedb_common.c | 2 | ||||
| -rw-r--r-- | src/exchangedb/plugin_exchangedb_postgres.c | 18 | ||||
| -rw-r--r-- | src/include/taler_crypto_lib.h | 64 | ||||
| -rw-r--r-- | src/include/taler_exchange_service.h | 2 | ||||
| -rw-r--r-- | src/include/taler_exchangedb_plugin.h | 6 | ||||
| -rw-r--r-- | src/include/taler_json_lib.h | 29 | ||||
| -rw-r--r-- | src/include/taler_pq_lib.h | 25 | ||||
| -rw-r--r-- | src/json/json_helper.c | 98 | ||||
| -rw-r--r-- | src/json/json_pack.c | 26 | ||||
| -rw-r--r-- | src/lib/exchange_api_refreshes_reveal.c | 12 | ||||
| -rw-r--r-- | src/lib/exchange_api_withdraw.c | 2 | ||||
| -rw-r--r-- | src/lib/exchange_api_withdraw2.c | 8 | ||||
| -rw-r--r-- | src/pq/pq_query_helper.c | 94 | ||||
| -rw-r--r-- | src/pq/pq_result_helper.c | 127 | ||||
| -rw-r--r-- | src/util/crypto.c | 16 | ||||
| -rw-r--r-- | src/util/crypto_helper_denom.c | 8 | ||||
| -rw-r--r-- | src/util/denom.c | 48 | 
21 files changed, 550 insertions, 74 deletions
| diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index e18295c6..ad06b668 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -1918,14 +1918,14 @@ TEH_keys_denomination_by_hash2 (  } -struct TALER_DenominationSignature +struct TALER_BlindedDenominationSignature  TEH_keys_denomination_sign (const struct TALER_DenominationHash *h_denom_pub,                              const void *msg,                              size_t msg_size,                              enum TALER_ErrorCode *ec)  {    struct TEH_KeyStateHandle *ksh; -  struct TALER_DenominationSignature none; +  struct TALER_BlindedDenominationSignature none;    memset (&none,            0, diff --git a/src/exchange/taler-exchange-httpd_keys.h b/src/exchange/taler-exchange-httpd_keys.h index db967a31..9ad0c6a3 100644 --- a/src/exchange/taler-exchange-httpd_keys.h +++ b/src/exchange/taler-exchange-httpd_keys.h @@ -171,7 +171,7 @@ TEH_keys_denomination_by_hash2 (struct TEH_KeyStateHandle *ksh,   * @return signature, the value inside the structure will be NULL on failure,   *         see @a ec for details about the failure   */ -struct TALER_DenominationSignature +struct TALER_BlindedDenominationSignature  TEH_keys_denomination_sign (const struct TALER_DenominationHash *h_denom_pub,                              const void *msg,                              size_t msg_size, diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c index 925f7a09..4ec70313 100644 --- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c +++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c @@ -55,7 +55,8 @@  static MHD_RESULT  reply_refreshes_reveal_success (struct MHD_Connection *connection,                                  unsigned int num_freshcoins, -                                const struct TALER_DenominationSignature *sigs) +                                const struct +                                TALER_BlindedDenominationSignature *sigs)  {    json_t *list; @@ -68,8 +69,8 @@ reply_refreshes_reveal_success (struct MHD_Connection *connection,      json_t *obj;      obj = GNUNET_JSON_PACK ( -      TALER_JSON_pack_denom_sig ("ev_sig", -                                 &sigs[freshcoin_index])); +      TALER_JSON_pack_blinded_denom_sig ("ev_sig", +                                         &sigs[freshcoin_index]));      GNUNET_assert (0 ==                     json_array_append_new (list,                                            obj)); @@ -123,7 +124,7 @@ struct RevealContext    /**     * Envelopes with the signatures to be returned.  Initially NULL.     */ -  struct TALER_DenominationSignature *ev_sigs; +  struct TALER_BlindedDenominationSignature *ev_sigs;    /**     * Size of the @e dks, @e rcds and @e ev_sigs arrays (if non-NULL). @@ -187,10 +188,10 @@ check_exists_cb (void *cls,    if (NULL == rctx->ev_sigs)    {      rctx->ev_sigs = GNUNET_new_array (num_freshcoins, -                                      struct TALER_DenominationSignature); +                                      struct TALER_BlindedDenominationSignature);      for (unsigned int i = 0; i<num_freshcoins; i++) -      TALER_denom_sig_deep_copy (&rctx->ev_sigs[i], -                                 &rrcs[i].coin_sig); +      TALER_blinded_denom_sig_deep_copy (&rctx->ev_sigs[i], +                                         &rrcs[i].coin_sig);    }  } @@ -683,7 +684,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,    /* sign _early_ (optimistic!) to keep out of transaction scope! */    rctx->ev_sigs = GNUNET_new_array (rctx->num_fresh_coins, -                                    struct TALER_DenominationSignature); +                                    struct TALER_BlindedDenominationSignature);    for (unsigned int i = 0; i<rctx->num_fresh_coins; i++)    {      enum TALER_ErrorCode ec = TALER_EC_NONE; @@ -769,7 +770,7 @@ cleanup:    if (NULL != rctx->ev_sigs)    {      for (unsigned int i = 0; i<num_fresh_coins; i++) -      TALER_denom_sig_free (&rctx->ev_sigs[i]); +      TALER_blinded_denom_sig_free (&rctx->ev_sigs[i]);      GNUNET_free (rctx->ev_sigs);      rctx->ev_sigs = NULL; /* just to be safe... */    } diff --git a/src/exchange/taler-exchange-httpd_withdraw.c b/src/exchange/taler-exchange-httpd_withdraw.c index d9c3b9e9..ef1bb27d 100644 --- a/src/exchange/taler-exchange-httpd_withdraw.c +++ b/src/exchange/taler-exchange-httpd_withdraw.c @@ -199,7 +199,7 @@ withdraw_transaction (void *cls,    struct WithdrawContext *wc = cls;    struct TALER_EXCHANGEDB_Reserve r;    enum GNUNET_DB_QueryStatus qs; -  struct TALER_DenominationSignature denom_sig; +  struct TALER_BlindedDenominationSignature denom_sig;  #if OPTIMISTIC_SIGN    /* store away optimistic signature to protect @@ -231,7 +231,7 @@ withdraw_transaction (void *cls,         optimization trade-off loses in this case: we unnecessarily computed         a signature :-( */  #if OPTIMISTIC_SIGN -    TALER_denom_sig_free (&denom_sig); +    TALER_blinded_denom_sig_free (&denom_sig);  #endif      return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;    } @@ -582,7 +582,7 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,      {        /* Even if #withdraw_transaction() failed, it may have created a signature           (or we might have done it optimistically above). */ -      TALER_denom_sig_free (&wc.collectable.sig); +      TALER_blinded_denom_sig_free (&wc.collectable.sig);        GNUNET_JSON_parse_free (spec);        return mhd_ret;      } @@ -593,7 +593,7 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,    if (wc.kyc_denied)    { -    TALER_denom_sig_free (&wc.collectable.sig); +    TALER_blinded_denom_sig_free (&wc.collectable.sig);      return TALER_MHD_REPLY_JSON_PACK (        rc->connection,        MHD_HTTP_ACCEPTED, @@ -607,9 +607,9 @@ TEH_handler_withdraw (struct TEH_RequestContext *rc,      ret = TALER_MHD_REPLY_JSON_PACK (        rc->connection,        MHD_HTTP_OK, -      TALER_JSON_pack_denom_sig ("ev_sig", -                                 &wc.collectable.sig)); -    TALER_denom_sig_free (&wc.collectable.sig); +      TALER_JSON_pack_blinded_denom_sig ("ev_sig", +                                         &wc.collectable.sig)); +    TALER_blinded_denom_sig_free (&wc.collectable.sig);      return ret;    }  } diff --git a/src/exchangedb/plugin_exchangedb_common.c b/src/exchangedb/plugin_exchangedb_common.c index 2d482698..a07ae78c 100644 --- a/src/exchangedb/plugin_exchangedb_common.c +++ b/src/exchangedb/plugin_exchangedb_common.c @@ -49,7 +49,7 @@ common_free_reserve_history (void *cls,          struct TALER_EXCHANGEDB_CollectableBlindcoin *cbc;          cbc = rh->details.withdraw; -        TALER_denom_sig_free (&cbc->sig); +        TALER_blinded_denom_sig_free (&cbc->sig);          GNUNET_free (cbc);          break;        } diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 017145e6..85550e98 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -4404,8 +4404,8 @@ postgres_get_withdraw_info (    struct GNUNET_PQ_ResultSpec rs[] = {      GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",                                            &collectable->denom_pub_hash), -    TALER_PQ_result_spec_denom_sig ("denom_sig", -                                    &collectable->sig), +    TALER_PQ_result_spec_blinded_denom_sig ("denom_sig", +                                            &collectable->sig),      GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",                                            &collectable->reserve_sig),      GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", @@ -4456,7 +4456,7 @@ postgres_insert_withdraw_info (    struct GNUNET_PQ_QueryParam params[] = {      GNUNET_PQ_query_param_auto_from_type (&collectable->h_coin_envelope),      GNUNET_PQ_query_param_auto_from_type (&collectable->denom_pub_hash), -    TALER_PQ_query_param_denom_sig (&collectable->sig), +    TALER_PQ_query_param_blinded_denom_sig (&collectable->sig),      GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_pub),      GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_sig),      TALER_PQ_query_param_absolute_time (&now), @@ -4660,8 +4660,8 @@ add_withdraw_coin (void *cls,                                                &cbc->h_coin_envelope),          GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",                                                &cbc->denom_pub_hash), -        TALER_PQ_result_spec_denom_sig ("denom_sig", -                                        &cbc->sig), +        TALER_PQ_result_spec_blinded_denom_sig ("denom_sig", +                                                &cbc->sig),          GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",                                                &cbc->reserve_sig),          TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", @@ -6088,7 +6088,7 @@ postgres_insert_refresh_reveal (        GNUNET_PQ_query_param_fixed_size (rrc->coin_ev,                                          rrc->coin_ev_size),        GNUNET_PQ_query_param_auto_from_type (&h_coin_ev), -      TALER_PQ_query_param_denom_sig (&rrc->coin_sig), +      TALER_PQ_query_param_blinded_denom_sig (&rrc->coin_sig),        GNUNET_PQ_query_param_end      };      enum GNUNET_DB_QueryStatus qs; @@ -6180,8 +6180,8 @@ add_revealed_coins (void *cls,        GNUNET_PQ_result_spec_variable_size ("coin_ev",                                             (void **) &rrc->coin_ev,                                             &rrc->coin_ev_size), -      TALER_PQ_result_spec_denom_sig ("ev_sig", -                                      &rrc->coin_sig), +      TALER_PQ_result_spec_blinded_denom_sig ("ev_sig", +                                              &rrc->coin_sig),        GNUNET_PQ_result_spec_end      }; @@ -6309,7 +6309,7 @@ cleanup:      struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrc = &grctx.rrcs[i];      TALER_denom_pub_free (&rrc->denom_pub); -    TALER_denom_sig_free (&rrc->coin_sig); +    TALER_blinded_denom_sig_free (&rrc->coin_sig);      GNUNET_free (rrc->coin_ev);    }    GNUNET_free (grctx.rrcs); diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index af567ba0..69acfa0b 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -524,6 +524,34 @@ struct TALER_DenominationSignature  /** + * @brief Type for *blinded* denomination signatures for Taler. + * Must be unblinded before it becomes valid. + */ +struct TALER_BlindedDenominationSignature +{ + +  /** +   * Type of the signature. +   */ +  enum TALER_DenominationCipher cipher; + +  /** +   * Details, depending on @e cipher. +   */ +  union +  { + +    /** +     * If we use #TALER_DENOMINATION_RSA in @a cipher. +     */ +    struct GNUNET_CRYPTO_RsaSignature *blinded_rsa_signature; + +  } details; + +}; + + +/**   * @brief Type of public signing keys for verifying blindly signed coins.   */  struct TALER_DenominationPublicKey @@ -663,6 +691,16 @@ TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig);  /** + * Free internals of @a denom_sig, but not @a denom_sig itself. + * + * @param[in] denom_sig signature to free + */ +void +TALER_blinded_denom_sig_free ( +  struct TALER_BlindedDenominationSignature *denom_sig); + + +/**   * Compute the hash of the given @a denom_pub.   *   * @param denom_pub public key to hash @@ -698,6 +736,19 @@ TALER_denom_sig_deep_copy (struct TALER_DenominationSignature *denom_dst,  /** + * Make a (deep) copy of the given @a denom_src to + * @a denom_dst. + * + * @param[out] denom_dst target to copy to + * @param denom_str public key to copy + */ +void +TALER_blinded_denom_sig_deep_copy ( +  struct TALER_BlindedDenominationSignature *denom_dst, +  const struct TALER_BlindedDenominationSignature *denom_src); + + +/**   * Compare two denomination public keys.   *   * @param denom1 first key @@ -1014,11 +1065,12 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,   * @return #GNUNET_OK on success   */  enum GNUNET_GenericReturnValue -TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk, -                        const struct GNUNET_CRYPTO_RsaSignature *blind_sig, -                        const struct TALER_PlanchetSecretsP *ps, -                        const struct TALER_CoinPubHash *c_hash, -                        struct TALER_FreshCoin *coin); +TALER_planchet_to_coin ( +  const struct TALER_DenominationPublicKey *dk, +  const struct TALER_BlindedDenominationSignature *blind_sig, +  const struct TALER_PlanchetSecretsP *ps, +  const struct TALER_CoinPubHash *c_hash, +  struct TALER_FreshCoin *coin);  /* ****************** Refresh crypto primitives ************* */ @@ -1215,7 +1267,7 @@ TALER_CRYPTO_helper_denom_poll (struct TALER_CRYPTO_DenominationHelper *dh);   * @return signature, the value inside the structure will be NULL on failure,   *         see @a ec for details about the failure   */ -struct TALER_DenominationSignature +struct TALER_BlindedDenominationSignature  TALER_CRYPTO_helper_denom_sign (    struct TALER_CRYPTO_DenominationHelper *dh,    const struct TALER_DenominationHash *h_denom_pub, diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 6daa120d..361956cb 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1387,7 +1387,7 @@ typedef void  (*TALER_EXCHANGE_Withdraw2Callback) (    void *cls,    const struct TALER_EXCHANGE_HttpResponse *hr, -  const struct GNUNET_CRYPTO_RsaSignature *blind_sig); +  const struct TALER_BlindedDenominationSignature *blind_sig);  /** diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index aa67092e..17df7528 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -696,9 +696,9 @@ struct TALER_EXCHANGEDB_CollectableBlindcoin  {    /** -   * Our signature over the (blinded) coin. +   * Our (blinded) signature over the (blinded) coin.     */ -  struct TALER_DenominationSignature sig; +  struct TALER_BlindedDenominationSignature sig;    /**     * Hash of the denomination key (which coin was generated). @@ -1616,7 +1616,7 @@ struct TALER_EXCHANGEDB_RefreshRevealedCoin    /**     * Signature generated by the exchange over the coin (in blinded format).     */ -  struct TALER_DenominationSignature coin_sig; +  struct TALER_BlindedDenominationSignature coin_sig;  }; diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index e381a7a1..26df1f11 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -160,6 +160,21 @@ TALER_JSON_pack_denom_sig (  /**   * Generate packer instruction for a JSON field of type + * blinded denomination signature (that needs to be + * unblinded before it becomes valid). + * + * @param name name of the field to add to the object + * @param sig signature + * @return json pack specification + */ +struct GNUNET_JSON_PackSpec +TALER_JSON_pack_blinded_denom_sig ( +  const char *name, +  const struct TALER_BlindedDenominationSignature *sig); + + +/** + * Generate packer instruction for a JSON field of type   * amount.   *   * @param name name of the field to add to the object @@ -328,6 +343,20 @@ TALER_JSON_spec_denom_sig (const char *field,  /** + * Generate line in parser specification for a + * blinded denomination signature. + * + * @param field name of the field + * @param sig the blinded signature to initialize + * @return corresponding field spec + */ +struct GNUNET_JSON_Specification +TALER_JSON_spec_blinded_denom_sig ( +  const char *field, +  struct TALER_BlindedDenominationSignature *sig); + + +/**   * The expected field stores a possibly internationalized string.   * Internationalization means that there is another field "$name_i18n"   * which is an object where the keys are languages.  If this is diff --git a/src/include/taler_pq_lib.h b/src/include/taler_pq_lib.h index 07057722..6e69cdf6 100644 --- a/src/include/taler_pq_lib.h +++ b/src/include/taler_pq_lib.h @@ -78,6 +78,18 @@ TALER_PQ_query_param_denom_sig (  /** + * Generate query parameter for a blinded denomination signature.  Internally, + * the various attributes of the signature will be serialized into on + * variable-size BLOB. + * + * @param x pointer to the query parameter to pass + */ +struct GNUNET_PQ_QueryParam +TALER_PQ_query_param_blinded_denom_sig ( +  const struct TALER_BlindedDenominationSignature *denom_sig); + + +/**   * Generate query parameter for a JSON object (stored as a string   * in the DB).  Note that @a x must really be a JSON object or array,   * passing just a value (string, integer) is not supported and will @@ -169,6 +181,19 @@ TALER_PQ_result_spec_denom_sig (const char *name,  /** + * Blinded denomination signature expected. + * + * @param name name of the field in the table + * @param[out] denom_sig where to store the denomination signature + * @return array entry for the result specification to use + */ +struct GNUNET_PQ_ResultSpec +TALER_PQ_result_spec_blinded_denom_sig ( +  const char *name, +  struct TALER_BlindedDenominationSignature *denom_sig); + + +/**   * json_t expected.   *   * @param name name of the field in the table diff --git a/src/json/json_helper.c b/src/json/json_helper.c index d509f4ef..1684e7f3 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c @@ -433,7 +433,7 @@ TALER_JSON_spec_relative_time (const char *name,   * @param[out] spec where to write the data   * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error   */ -static int +static enum GNUNET_GenericReturnValue  parse_denom_pub (void *cls,                   json_t *root,                   struct GNUNET_JSON_Specification *spec) @@ -528,7 +528,7 @@ TALER_JSON_spec_denom_pub (const char *field,   * @param[out] spec where to write the data   * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error   */ -static int +static enum GNUNET_GenericReturnValue  parse_denom_sig (void *cls,                   json_t *root,                   struct GNUNET_JSON_Specification *spec) @@ -614,6 +614,100 @@ TALER_JSON_spec_denom_sig (const char *field,  /** + * Parse given JSON object to blinded denomination signature. + * + * @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_blinded_denom_sig (void *cls, +                         json_t *root, +                         struct GNUNET_JSON_Specification *spec) +{ +  struct TALER_BlindedDenominationSignature *denom_sig = spec->ptr; +  uint32_t cipher; +  struct GNUNET_JSON_Specification dspec[] = { +    GNUNET_JSON_spec_uint32 ("cipher", +                             &cipher), +    GNUNET_JSON_spec_end () +  }; +  const char *emsg; +  unsigned int eline; + +  if (GNUNET_OK != +      GNUNET_JSON_parse (root, +                         dspec, +                         &emsg, +                         &eline)) +  { +    GNUNET_break_op (0); +    return GNUNET_SYSERR; +  } +  denom_sig->cipher = (enum TALER_DenominationCipher) cipher; +  switch (denom_sig->cipher) +  { +  case TALER_DENOMINATION_RSA: +    { +      struct GNUNET_JSON_Specification ispec[] = { +        GNUNET_JSON_spec_rsa_signature ( +          "blinded_rsa_signature", +          &denom_sig->details.blinded_rsa_signature), +        GNUNET_JSON_spec_end () +      }; + +      if (GNUNET_OK != +          GNUNET_JSON_parse (root, +                             ispec, +                             &emsg, +                             &eline)) +      { +        GNUNET_break_op (0); +        return GNUNET_SYSERR; +      } +      return GNUNET_OK; +    } +  default: +    GNUNET_break_op (0); +    return GNUNET_SYSERR; +  } +} + + +/** + * Cleanup data left from parsing denomination public key. + * + * @param cls closure, NULL + * @param[out] spec where to free the data + */ +static void +clean_blinded_denom_sig (void *cls, +                         struct GNUNET_JSON_Specification *spec) +{ +  struct TALER_BlindedDenominationSignature *denom_sig = spec->ptr; + +  TALER_blinded_denom_sig_free (denom_sig); +} + + +struct GNUNET_JSON_Specification +TALER_JSON_spec_blinded_denom_sig ( +  const char *field, +  struct TALER_BlindedDenominationSignature *sig) +{ +  struct GNUNET_JSON_Specification ret = { +    .parser = &parse_blinded_denom_sig, +    .cleaner = &clean_blinded_denom_sig, +    .field = field, +    .ptr = sig +  }; + +  return ret; +} + + +/**   * Closure for #parse_i18n_string.   */  struct I18nContext diff --git a/src/json/json_pack.c b/src/json/json_pack.c index 0d1c9570..59e3afb7 100644 --- a/src/json/json_pack.c +++ b/src/json/json_pack.c @@ -142,6 +142,32 @@ TALER_JSON_pack_denom_sig (  struct GNUNET_JSON_PackSpec +TALER_JSON_pack_blinded_denom_sig ( +  const char *name, +  const struct TALER_BlindedDenominationSignature *sig) +{ +  struct GNUNET_JSON_PackSpec ps = { +    .field_name = name, +  }; + +  switch (sig->cipher) +  { +  case TALER_DENOMINATION_RSA: +    ps.object +      = GNUNET_JSON_PACK ( +          GNUNET_JSON_pack_uint64 ("cipher", +                                   TALER_DENOMINATION_RSA), +          GNUNET_JSON_pack_rsa_signature ("blinded_rsa_signature", +                                          sig->details.blinded_rsa_signature)); +    break; +  default: +    GNUNET_assert (0); +  } +  return ps; +} + + +struct GNUNET_JSON_PackSpec  TALER_JSON_pack_amount (const char *name,                          const struct TALER_Amount *amount)  { diff --git a/src/lib/exchange_api_refreshes_reveal.c b/src/lib/exchange_api_refreshes_reveal.c index 0af37c02..c275e0a4 100644 --- a/src/lib/exchange_api_refreshes_reveal.c +++ b/src/lib/exchange_api_refreshes_reveal.c @@ -137,12 +137,12 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,      const struct TALER_PlanchetSecretsP *fc;      struct TALER_DenominationPublicKey *pk;      json_t *jsonai; -    struct GNUNET_CRYPTO_RsaSignature *blind_sig; +    struct TALER_BlindedDenominationSignature blind_sig;      struct TALER_CoinSpendPublicKeyP coin_pub;      struct TALER_CoinPubHash coin_hash;      struct GNUNET_JSON_Specification spec[] = { -      GNUNET_JSON_spec_rsa_signature ("ev_sig", -                                      &blind_sig), +      TALER_JSON_spec_blinded_denom_sig ("ev_sig", +                                         &blind_sig),        GNUNET_JSON_spec_end ()      };      struct TALER_FreshCoin coin; @@ -170,17 +170,17 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,                           &coin_hash);      if (GNUNET_OK !=          TALER_planchet_to_coin (pk, -                                blind_sig, +                                &blind_sig,                                  fc,                                  &coin_hash,                                  &coin))      {        GNUNET_break_op (0); -      GNUNET_CRYPTO_rsa_signature_free (blind_sig); +      GNUNET_JSON_parse_free (spec);        GNUNET_JSON_parse_free (outer_spec);        return GNUNET_SYSERR;      } -    GNUNET_CRYPTO_rsa_signature_free (blind_sig); +    GNUNET_JSON_parse_free (spec);      sigs[i] = coin.sig;    }    GNUNET_JSON_parse_free (outer_spec); diff --git a/src/lib/exchange_api_withdraw.c b/src/lib/exchange_api_withdraw.c index 8e00cfcd..5e823ee6 100644 --- a/src/lib/exchange_api_withdraw.c +++ b/src/lib/exchange_api_withdraw.c @@ -88,7 +88,7 @@ static void  handle_reserve_withdraw_finished (    void *cls,    const struct TALER_EXCHANGE_HttpResponse *hr, -  const struct GNUNET_CRYPTO_RsaSignature *blind_sig) +  const struct TALER_BlindedDenominationSignature *blind_sig)  {    struct TALER_EXCHANGE_WithdrawHandle *wh = cls;    struct TALER_EXCHANGE_WithdrawResponse wr = { diff --git a/src/lib/exchange_api_withdraw2.c b/src/lib/exchange_api_withdraw2.c index e001a315..d50892e5 100644 --- a/src/lib/exchange_api_withdraw2.c +++ b/src/lib/exchange_api_withdraw2.c @@ -99,10 +99,10 @@ static enum GNUNET_GenericReturnValue  reserve_withdraw_ok (struct TALER_EXCHANGE_Withdraw2Handle *wh,                       const json_t *json)  { -  struct GNUNET_CRYPTO_RsaSignature *blind_sig; +  struct TALER_BlindedDenominationSignature blind_sig;    struct GNUNET_JSON_Specification spec[] = { -    GNUNET_JSON_spec_rsa_signature ("ev_sig", -                                    &blind_sig), +    TALER_JSON_spec_blinded_denom_sig ("ev_sig", +                                       &blind_sig),      GNUNET_JSON_spec_end ()    };    struct TALER_EXCHANGE_HttpResponse hr = { @@ -122,7 +122,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_Withdraw2Handle *wh,    /* signature is valid, return it to the application */    wh->cb (wh->cb_cls,            &hr, -          blind_sig); +          &blind_sig);    /* make sure callback isn't called again after return */    wh->cb = NULL;    GNUNET_JSON_parse_free (spec); diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index 3f51ddbe..61887760 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -265,7 +265,7 @@ qconv_denom_sig (void *cls,    const struct TALER_DenominationSignature *denom_sig = data;    size_t tlen;    size_t len; -  uint32_t be; +  uint32_t be[2];    char *buf;    void *tbuf; @@ -273,7 +273,8 @@ qconv_denom_sig (void *cls,    GNUNET_assert (1 == param_length);    GNUNET_assert (scratch_length > 0);    GNUNET_break (NULL == cls); -  be = htonl ((uint32_t) denom_sig->cipher); +  be[0] = htonl ((uint32_t) denom_sig->cipher); +  be[1] = htonl (0x00); /* magic marker: unblinded */    switch (denom_sig->cipher)    {    case TALER_DENOMINATION_RSA: @@ -329,6 +330,95 @@ TALER_PQ_query_param_denom_sig (   * Function called to convert input argument into SQL parameters.   *   * @param cls closure + * @param data pointer to input argument + * @param data_len number of bytes in @a data (if applicable) + * @param[out] param_values SQL data to set + * @param[out] param_lengths SQL length data to set + * @param[out] param_formats SQL format data to set + * @param param_length number of entries available in the @a param_values, @a param_lengths and @a param_formats arrays + * @param[out] scratch buffer for dynamic allocations (to be done via #GNUNET_malloc() + * @param scratch_length number of entries left in @a scratch + * @return -1 on error, number of offsets used in @a scratch otherwise + */ +static int +qconv_blinded_denom_sig (void *cls, +                         const void *data, +                         size_t data_len, +                         void *param_values[], +                         int param_lengths[], +                         int param_formats[], +                         unsigned int param_length, +                         void *scratch[], +                         unsigned int scratch_length) +{ +  const struct TALER_BlindedDenominationSignature *denom_sig = data; +  size_t tlen; +  size_t len; +  uint32_t be[2]; +  char *buf; +  void *tbuf; + +  (void) cls; +  GNUNET_assert (1 == param_length); +  GNUNET_assert (scratch_length > 0); +  GNUNET_break (NULL == cls); +  be[0] = htonl ((uint32_t) denom_sig->cipher); +  be[1] = htonl (0x01); /* magic marker: blinded */ +  switch (denom_sig->cipher) +  { +  case TALER_DENOMINATION_RSA: +    tlen = GNUNET_CRYPTO_rsa_signature_encode ( +      denom_sig->details.blinded_rsa_signature, +      &tbuf); +    break; +  // TODO: add case for Clause-Schnorr +  default: +    GNUNET_assert (0); +  } +  len = tlen + sizeof (be); +  buf = GNUNET_malloc (len); +  memcpy (buf, +          &be, +          sizeof (be)); +  switch (denom_sig->cipher) +  { +  case TALER_DENOMINATION_RSA: +    memcpy (&buf[sizeof (be)], +            tbuf, +            tlen); +    GNUNET_free (tbuf); +    break; +  // TODO: add case for Clause-Schnorr +  default: +    GNUNET_assert (0); +  } + +  scratch[0] = buf; +  param_values[0] = (void *) buf; +  param_lengths[0] = len; +  param_formats[0] = 1; +  return 1; +} + + +struct GNUNET_PQ_QueryParam +TALER_PQ_query_param_blinded_denom_sig ( +  const struct TALER_BlindedDenominationSignature *denom_sig) +{ +  struct GNUNET_PQ_QueryParam res = { +    .conv = &qconv_blinded_denom_sig, +    .data = denom_sig, +    .num_params = 1 +  }; + +  return res; +} + + +/** + * Function called to convert input argument into SQL parameters. + * + * @param cls closure   * @param data pointer to input argument, here a `json_t *`   * @param data_len number of bytes in @a data (if applicable)   * @param[out] param_values SQL data to set diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 57bcf6dd..2f570b6b 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -630,7 +630,7 @@ extract_denom_sig (void *cls,    size_t len;    const char *res;    int fnum; -  uint32_t be; +  uint32_t be[2];    (void) cls;    fnum = PQfnumber (result, @@ -661,9 +661,14 @@ extract_denom_sig (void *cls,    memcpy (&be,            res,            sizeof (be)); +  if (0x00 != ntohl (be[1])) +  { +    GNUNET_break (0); +    return GNUNET_SYSERR; +  }    res += sizeof (be);    len -= sizeof (be); -  sig->cipher = ntohl (be); +  sig->cipher = ntohl (be[0]);    switch (sig->cipher)    {    case TALER_DENOMINATION_RSA: @@ -717,4 +722,122 @@ TALER_PQ_result_spec_denom_sig (const char *name,  } +/** + * Extract data from a Postgres database @a result at row @a row. + * + * @param cls closure + * @param result where to extract data from + * @param int row to extract data from + * @param fname name (or prefix) of the fields to extract from + * @param[in,out] dst_size where to store size of result, may be NULL + * @param[out] dst where to store the result + * @return + *   #GNUNET_YES if all results could be extracted + *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL) + */ +static enum GNUNET_GenericReturnValue +extract_blinded_denom_sig (void *cls, +                           PGresult *result, +                           int row, +                           const char *fname, +                           size_t *dst_size, +                           void *dst) +{ +  struct TALER_BlindedDenominationSignature *sig = dst; +  size_t len; +  const char *res; +  int fnum; +  uint32_t be[2]; + +  (void) cls; +  fnum = PQfnumber (result, +                    fname); +  if (fnum < 0) +  { +    GNUNET_break (0); +    return GNUNET_SYSERR; +  } +  if (PQgetisnull (result, +                   row, +                   fnum)) +    return GNUNET_NO; + +  /* if a field is null, continue but +   * remember that we now return a different result */ +  len = PQgetlength (result, +                     row, +                     fnum); +  res = PQgetvalue (result, +                    row, +                    fnum); +  if (len < sizeof (be)) +  { +    GNUNET_break (0); +    return GNUNET_SYSERR; +  } +  memcpy (&be, +          res, +          sizeof (be)); +  if (0x01 != ntohl (be[1])) /* magic marker: blinded */ +  { +    GNUNET_break (0); +    return GNUNET_SYSERR; +  } +  res += sizeof (be); +  len -= sizeof (be); +  sig->cipher = ntohl (be[0]); +  switch (sig->cipher) +  { +  case TALER_DENOMINATION_RSA: +    sig->details.blinded_rsa_signature +      = GNUNET_CRYPTO_rsa_signature_decode (res, +                                            len); +    if (NULL == sig->details.blinded_rsa_signature) +    { +      GNUNET_break (0); +      return GNUNET_SYSERR; +    } +    return GNUNET_OK; +  // FIXME: add CS case! +  default: +    GNUNET_break (0); +  } +  return GNUNET_SYSERR; +} + + +/** + * Function called to clean up memory allocated + * by a #GNUNET_PQ_ResultConverter. + * + * @param cls closure + * @param rd result data to clean up + */ +static void +clean_blinded_denom_sig (void *cls, +                         void *rd) +{ +  struct TALER_BlindedDenominationSignature *denom_sig = rd; + +  (void) cls; +  TALER_blinded_denom_sig_free (denom_sig); +} + + +struct GNUNET_PQ_ResultSpec +TALER_PQ_result_spec_blinded_denom_sig ( +  const char *name, +  struct TALER_BlindedDenominationSignature *denom_sig) +{ +  struct GNUNET_PQ_ResultSpec res = { +    .conv = &extract_blinded_denom_sig, +    .cleaner = &clean_blinded_denom_sig, +    .dst = (void *) denom_sig, +    .fname = name +  }; + +  return res; +} + +  /* end of pq_result_helper.c */ diff --git a/src/util/crypto.c b/src/util/crypto.c index c7b45945..99744304 100644 --- a/src/util/crypto.c +++ b/src/util/crypto.c @@ -212,21 +212,23 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,  enum GNUNET_GenericReturnValue -TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk, -                        const struct GNUNET_CRYPTO_RsaSignature *blind_sig, -                        const struct TALER_PlanchetSecretsP *ps, -                        const struct TALER_CoinPubHash *c_hash, -                        struct TALER_FreshCoin *coin) +TALER_planchet_to_coin ( +  const struct TALER_DenominationPublicKey *dk, +  const struct TALER_BlindedDenominationSignature *blind_sig, +  const struct TALER_PlanchetSecretsP *ps, +  const struct TALER_CoinPubHash *c_hash, +  struct TALER_FreshCoin *coin)  {    struct TALER_DenominationSignature sig; -  // FIXME-Gian/Lucien: this will be the bigger +  // FIXME-Gian/Lucien: this may need a bigger    // change, as you have the extra round trip    // => to be discussed!    GNUNET_assert (TALER_DENOMINATION_RSA == dk->cipher); +  GNUNET_assert (TALER_DENOMINATION_RSA == blind_sig->cipher);    sig.cipher = TALER_DENOMINATION_RSA;    sig.details.rsa_signature -    = TALER_rsa_unblind (blind_sig, +    = TALER_rsa_unblind (blind_sig->details.blinded_rsa_signature,                           &ps->blinding_key.bks,                           dk->details.rsa_public_key);    if (GNUNET_OK != diff --git a/src/util/crypto_helper_denom.c b/src/util/crypto_helper_denom.c index ba56a4e7..4dfd32fb 100644 --- a/src/util/crypto_helper_denom.c +++ b/src/util/crypto_helper_denom.c @@ -541,7 +541,7 @@ TALER_CRYPTO_helper_denom_poll (struct TALER_CRYPTO_DenominationHelper *dh)  } -struct TALER_DenominationSignature +struct TALER_BlindedDenominationSignature  TALER_CRYPTO_helper_denom_sign (    struct TALER_CRYPTO_DenominationHelper *dh,    const struct TALER_DenominationHash *h_denom_pub, @@ -549,8 +549,8 @@ TALER_CRYPTO_helper_denom_sign (    size_t msg_size,    enum TALER_ErrorCode *ec)  { -  struct TALER_DenominationSignature ds = { -    .details.rsa_signature = NULL +  struct TALER_BlindedDenominationSignature ds = { +    .details.blinded_rsa_signature = NULL    };    {      char buf[sizeof (struct TALER_CRYPTO_SignRequest) + msg_size]; @@ -652,7 +652,7 @@ TALER_CRYPTO_helper_denom_sign (          }          *ec = TALER_EC_NONE;          ds.cipher = TALER_DENOMINATION_RSA; -        ds.details.rsa_signature = rsa_signature; +        ds.details.blinded_rsa_signature = rsa_signature;          return ds;        }      case TALER_HELPER_RSA_MT_RES_SIGN_FAILURE: diff --git a/src/util/denom.c b/src/util/denom.c index 33b50763..8d6ddd5e 100644 --- a/src/util/denom.c +++ b/src/util/denom.c @@ -169,6 +169,27 @@ TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig)  } +void +TALER_blinded_denom_sig_free ( +  struct TALER_BlindedDenominationSignature *denom_sig) +{ +  switch (denom_sig->cipher) +  { +  case TALER_DENOMINATION_RSA: +    if (NULL != denom_sig->details.blinded_rsa_signature) +    { +      GNUNET_CRYPTO_rsa_signature_free ( +        denom_sig->details.blinded_rsa_signature); +      denom_sig->details.blinded_rsa_signature = NULL; +    } +    return; +  // TODO: add case for Clause-Schnorr +  default: +    GNUNET_assert (0); +  } +} + +  /**   * Make a (deep) copy of the given @a denom_src to   * @a denom_dst. @@ -214,13 +235,26 @@ TALER_denom_sig_deep_copy (struct TALER_DenominationSignature *denom_dst,  } -/** - * Compare two denomination public keys. - * - * @param denom1 first key - * @param denom2 second key - * @return 0 if the keys are equal, otherwise -1 or 1 - */ +void +TALER_blinded_denom_sig_deep_copy ( +  struct TALER_BlindedDenominationSignature *denom_dst, +  const struct TALER_BlindedDenominationSignature *denom_src) +{ +  *denom_dst = *denom_src; /* shallow copy */ +  switch (denom_src->cipher) +  { +  case TALER_DENOMINATION_RSA: +    denom_dst->details.blinded_rsa_signature +      = GNUNET_CRYPTO_rsa_signature_dup ( +          denom_src->details.blinded_rsa_signature); +    return; +  // TODO: add case for Clause-Schnorr +  default: +    GNUNET_assert (0); +  } +} + +  int  TALER_denom_pub_cmp (const struct TALER_DenominationPublicKey *denom1,                       const struct TALER_DenominationPublicKey *denom2) | 
