exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

tokens.c (7621B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2024 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file tokens.c
     18  * @brief token family utility functions
     19  * @author Christian Blättler
     20  */
     21 #include "taler/platform.h"
     22 #include "taler/taler_util.h"
     23 
     24 
     25 void
     26 TALER_token_issue_sig_free (struct TALER_TokenIssueSignature *issue_sig)
     27 {
     28   if (NULL != issue_sig->signature)
     29   {
     30     GNUNET_CRYPTO_unblinded_sig_decref (issue_sig->signature);
     31     issue_sig->signature = NULL;
     32   }
     33 }
     34 
     35 
     36 void
     37 TALER_blinded_issue_sig_free (
     38   struct TALER_BlindedTokenIssueSignature *issue_sig)
     39 {
     40   if (NULL != issue_sig->signature)
     41   {
     42     GNUNET_CRYPTO_blinded_sig_decref (issue_sig->signature);
     43     issue_sig->signature = NULL;
     44   }
     45 }
     46 
     47 
     48 void
     49 TALER_token_use_setup_random (struct TALER_TokenUseMasterSecretP *master)
     50 {
     51   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
     52                               master,
     53                               sizeof (*master));
     54 }
     55 
     56 
     57 void
     58 TALER_token_use_setup_priv (
     59   const struct TALER_TokenUseMasterSecretP *master,
     60   const struct TALER_TokenUseMerchantValues *alg_values,
     61   struct TALER_TokenUsePrivateKeyP *token_priv)
     62 {
     63   const struct GNUNET_CRYPTO_BlindingInputValues *bi
     64     = alg_values->blinding_inputs;
     65 
     66   switch (bi->cipher)
     67   {
     68   case GNUNET_CRYPTO_BSA_INVALID:
     69     GNUNET_break (0);
     70     memset (token_priv,
     71             0,
     72             sizeof (*token_priv));
     73     return;
     74   case GNUNET_CRYPTO_BSA_RSA:
     75     GNUNET_assert (GNUNET_YES ==
     76                    GNUNET_CRYPTO_hkdf_gnunet (
     77                      token_priv,
     78                      sizeof (*token_priv),
     79                      "token",
     80                      strlen ("token"),
     81                      master,
     82                      sizeof(*master)));
     83     return;
     84   case GNUNET_CRYPTO_BSA_CS:
     85     GNUNET_assert (GNUNET_YES ==
     86                    GNUNET_CRYPTO_hkdf_gnunet (
     87                      token_priv,
     88                      sizeof (*token_priv),
     89                      "token",
     90                      strlen ("token"),
     91                      master,
     92                      sizeof(*master),
     93                      GNUNET_CRYPTO_kdf_arg_auto (&bi->details.cs_values)));
     94     return;
     95   }
     96   GNUNET_assert (0);
     97 }
     98 
     99 
    100 void
    101 TALER_token_use_blinding_secret_create (
    102   const struct TALER_TokenUseMasterSecretP *master,
    103   const struct TALER_TokenUseMerchantValues *alg_values,
    104   union GNUNET_CRYPTO_BlindingSecretP *bks)
    105 {
    106   const struct GNUNET_CRYPTO_BlindingInputValues *bi =
    107     alg_values->blinding_inputs;
    108 
    109   switch (bi->cipher)
    110   {
    111   case GNUNET_CRYPTO_BSA_INVALID:
    112     GNUNET_break (0);
    113     return;
    114   case GNUNET_CRYPTO_BSA_RSA:
    115     GNUNET_assert (GNUNET_YES ==
    116                    GNUNET_CRYPTO_hkdf_gnunet (
    117                      &bks->rsa_bks,
    118                      sizeof (bks->rsa_bks),
    119                      "bks",
    120                      strlen ("bks"),
    121                      master,
    122                      sizeof(*master)));
    123     return;
    124   case GNUNET_CRYPTO_BSA_CS:
    125     GNUNET_assert (GNUNET_YES ==
    126                    GNUNET_CRYPTO_hkdf_gnunet (
    127                      &bks->nonce,
    128                      sizeof (bks->nonce),
    129                      "bseed",
    130                      strlen ("bseed"),
    131                      master,
    132                      sizeof(*master),
    133                      GNUNET_CRYPTO_kdf_arg_auto (&bi->details.cs_values)));
    134     return;
    135   }
    136   GNUNET_assert (0);
    137 }
    138 
    139 
    140 const struct TALER_TokenUseMerchantValues *
    141 TALER_token_blind_input_rsa_singleton ()
    142 {
    143   static struct GNUNET_CRYPTO_BlindingInputValues bi = {
    144     .cipher = GNUNET_CRYPTO_BSA_RSA
    145   };
    146   static struct TALER_TokenUseMerchantValues alg_values = {
    147     .blinding_inputs = &bi
    148   };
    149   return &alg_values;
    150 }
    151 
    152 
    153 void
    154 TALER_token_blind_input_copy (struct TALER_TokenUseMerchantValues *bi_dst,
    155                               const struct TALER_TokenUseMerchantValues *bi_src)
    156 {
    157   if (bi_src == TALER_token_blind_input_rsa_singleton ())
    158   {
    159     *bi_dst = *bi_src;
    160     return;
    161   }
    162   bi_dst->blinding_inputs
    163     = GNUNET_CRYPTO_blinding_input_values_incref (bi_src->blinding_inputs);
    164 }
    165 
    166 
    167 enum GNUNET_GenericReturnValue
    168 TALER_token_issue_sign (const struct TALER_TokenIssuePrivateKey *issue_priv,
    169                         const struct TALER_TokenEnvelope *envelope,
    170                         struct TALER_BlindedTokenIssueSignature *issue_sig)
    171 {
    172   issue_sig->signature
    173     = GNUNET_CRYPTO_blind_sign (issue_priv->private_key,
    174                                 "tk",
    175                                 envelope->blinded_pub);
    176   if (NULL == issue_sig->signature)
    177     return GNUNET_SYSERR;
    178   return GNUNET_OK;
    179 }
    180 
    181 
    182 enum GNUNET_GenericReturnValue
    183 TALER_token_issue_verify (const struct TALER_TokenUsePublicKeyP *use_pub,
    184                           const struct TALER_TokenIssuePublicKey *issue_pub,
    185                           const struct TALER_TokenIssueSignature *ub_sig)
    186 {
    187   struct GNUNET_HashCode h_use_pub;
    188 
    189   GNUNET_CRYPTO_hash (&use_pub->public_key,
    190                       sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
    191                       &h_use_pub);
    192 
    193   if (GNUNET_OK !=
    194       GNUNET_CRYPTO_blind_sig_verify (issue_pub->public_key,
    195                                       ub_sig->signature,
    196                                       &h_use_pub,
    197                                       sizeof (h_use_pub)))
    198   {
    199     GNUNET_break_op (0);
    200     return GNUNET_SYSERR;
    201   }
    202   return GNUNET_OK;
    203 }
    204 
    205 
    206 enum GNUNET_GenericReturnValue
    207 TALER_token_issue_sig_unblind (
    208   struct TALER_TokenIssueSignature *issue_sig,
    209   const struct TALER_BlindedTokenIssueSignature *blinded_sig,
    210   const union GNUNET_CRYPTO_BlindingSecretP *secret,
    211   const struct TALER_TokenUsePublicKeyHashP *use_pub_hash,
    212   const struct TALER_TokenUseMerchantValues *alg_values,
    213   const struct TALER_TokenIssuePublicKey *issue_pub)
    214 {
    215   issue_sig->signature
    216     = GNUNET_CRYPTO_blind_sig_unblind (blinded_sig->signature,
    217                                        secret,
    218                                        &use_pub_hash->hash,
    219                                        sizeof (use_pub_hash->hash),
    220                                        alg_values->blinding_inputs,
    221                                        issue_pub->public_key);
    222   if (NULL == issue_sig->signature)
    223   {
    224     GNUNET_break_op (0);
    225     return GNUNET_SYSERR;
    226   }
    227   return GNUNET_OK;
    228 }
    229 
    230 
    231 void
    232 TALER_token_issue_pub_free (struct TALER_TokenIssuePublicKey *token_pub)
    233 {
    234   if (NULL != token_pub->public_key)
    235   {
    236     GNUNET_CRYPTO_blind_sign_pub_decref (token_pub->public_key);
    237     token_pub->public_key = NULL;
    238   }
    239 }
    240 
    241 
    242 int
    243 TALER_token_issue_pub_cmp (
    244   struct TALER_TokenIssuePublicKey *tip1,
    245   const struct TALER_TokenIssuePublicKey *tip2)
    246 {
    247   if (tip1->public_key->cipher !=
    248       tip2->public_key->cipher)
    249     return (tip1->public_key->cipher >
    250             tip2->public_key->cipher) ? 1 : -1;
    251   return GNUNET_CRYPTO_bsign_pub_cmp (tip1->public_key,
    252                                       tip2->public_key);
    253 }
    254 
    255 
    256 void
    257 TALER_token_issue_pub_copy (
    258   struct TALER_TokenIssuePublicKey *tip_dst,
    259   const struct TALER_TokenIssuePublicKey *tip_src)
    260 {
    261   tip_dst->public_key
    262     = GNUNET_CRYPTO_bsign_pub_incref (tip_src->public_key);
    263 }