exchange

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

tokens.c (7593B)


      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/taler_util.h"
     22 
     23 
     24 void
     25 TALER_token_issue_sig_free (struct TALER_TokenIssueSignature *issue_sig)
     26 {
     27   if (NULL != issue_sig->signature)
     28   {
     29     GNUNET_CRYPTO_unblinded_sig_decref (issue_sig->signature);
     30     issue_sig->signature = NULL;
     31   }
     32 }
     33 
     34 
     35 void
     36 TALER_blinded_issue_sig_free (
     37   struct TALER_BlindedTokenIssueSignature *issue_sig)
     38 {
     39   if (NULL != issue_sig->signature)
     40   {
     41     GNUNET_CRYPTO_blinded_sig_decref (issue_sig->signature);
     42     issue_sig->signature = NULL;
     43   }
     44 }
     45 
     46 
     47 void
     48 TALER_token_use_setup_random (struct TALER_TokenUseMasterSecretP *master)
     49 {
     50   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
     51                               master,
     52                               sizeof (*master));
     53 }
     54 
     55 
     56 void
     57 TALER_token_use_setup_priv (
     58   const struct TALER_TokenUseMasterSecretP *master,
     59   const struct TALER_TokenUseMerchantValues *alg_values,
     60   struct TALER_TokenUsePrivateKeyP *token_priv)
     61 {
     62   const struct GNUNET_CRYPTO_BlindingInputValues *bi
     63     = alg_values->blinding_inputs;
     64 
     65   switch (bi->cipher)
     66   {
     67   case GNUNET_CRYPTO_BSA_INVALID:
     68     GNUNET_break (0);
     69     memset (token_priv,
     70             0,
     71             sizeof (*token_priv));
     72     return;
     73   case GNUNET_CRYPTO_BSA_RSA:
     74     GNUNET_assert (GNUNET_YES ==
     75                    GNUNET_CRYPTO_hkdf_gnunet (
     76                      token_priv,
     77                      sizeof (*token_priv),
     78                      "token",
     79                      strlen ("token"),
     80                      master,
     81                      sizeof(*master)));
     82     return;
     83   case GNUNET_CRYPTO_BSA_CS:
     84     GNUNET_assert (GNUNET_YES ==
     85                    GNUNET_CRYPTO_hkdf_gnunet (
     86                      token_priv,
     87                      sizeof (*token_priv),
     88                      "token",
     89                      strlen ("token"),
     90                      master,
     91                      sizeof(*master),
     92                      GNUNET_CRYPTO_kdf_arg_auto (&bi->details.cs_values)));
     93     return;
     94   }
     95   GNUNET_assert (0);
     96 }
     97 
     98 
     99 void
    100 TALER_token_use_blinding_secret_create (
    101   const struct TALER_TokenUseMasterSecretP *master,
    102   const struct TALER_TokenUseMerchantValues *alg_values,
    103   union GNUNET_CRYPTO_BlindingSecretP *bks)
    104 {
    105   const struct GNUNET_CRYPTO_BlindingInputValues *bi =
    106     alg_values->blinding_inputs;
    107 
    108   switch (bi->cipher)
    109   {
    110   case GNUNET_CRYPTO_BSA_INVALID:
    111     GNUNET_break (0);
    112     return;
    113   case GNUNET_CRYPTO_BSA_RSA:
    114     GNUNET_assert (GNUNET_YES ==
    115                    GNUNET_CRYPTO_hkdf_gnunet (
    116                      &bks->rsa_bks,
    117                      sizeof (bks->rsa_bks),
    118                      "bks",
    119                      strlen ("bks"),
    120                      master,
    121                      sizeof(*master)));
    122     return;
    123   case GNUNET_CRYPTO_BSA_CS:
    124     GNUNET_assert (GNUNET_YES ==
    125                    GNUNET_CRYPTO_hkdf_gnunet (
    126                      &bks->nonce,
    127                      sizeof (bks->nonce),
    128                      "bseed",
    129                      strlen ("bseed"),
    130                      master,
    131                      sizeof(*master),
    132                      GNUNET_CRYPTO_kdf_arg_auto (&bi->details.cs_values)));
    133     return;
    134   }
    135   GNUNET_assert (0);
    136 }
    137 
    138 
    139 const struct TALER_TokenUseMerchantValues *
    140 TALER_token_blind_input_rsa_singleton ()
    141 {
    142   static struct GNUNET_CRYPTO_BlindingInputValues bi = {
    143     .cipher = GNUNET_CRYPTO_BSA_RSA
    144   };
    145   static struct TALER_TokenUseMerchantValues alg_values = {
    146     .blinding_inputs = &bi
    147   };
    148   return &alg_values;
    149 }
    150 
    151 
    152 void
    153 TALER_token_blind_input_copy (struct TALER_TokenUseMerchantValues *bi_dst,
    154                               const struct TALER_TokenUseMerchantValues *bi_src)
    155 {
    156   if (bi_src == TALER_token_blind_input_rsa_singleton ())
    157   {
    158     *bi_dst = *bi_src;
    159     return;
    160   }
    161   bi_dst->blinding_inputs
    162     = GNUNET_CRYPTO_blinding_input_values_incref (bi_src->blinding_inputs);
    163 }
    164 
    165 
    166 enum GNUNET_GenericReturnValue
    167 TALER_token_issue_sign (const struct TALER_TokenIssuePrivateKey *issue_priv,
    168                         const struct TALER_TokenEnvelope *envelope,
    169                         struct TALER_BlindedTokenIssueSignature *issue_sig)
    170 {
    171   issue_sig->signature
    172     = GNUNET_CRYPTO_blind_sign (issue_priv->private_key,
    173                                 "tk",
    174                                 envelope->blinded_pub);
    175   if (NULL == issue_sig->signature)
    176     return GNUNET_SYSERR;
    177   return GNUNET_OK;
    178 }
    179 
    180 
    181 enum GNUNET_GenericReturnValue
    182 TALER_token_issue_verify (const struct TALER_TokenUsePublicKeyP *use_pub,
    183                           const struct TALER_TokenIssuePublicKey *issue_pub,
    184                           const struct TALER_TokenIssueSignature *ub_sig)
    185 {
    186   struct GNUNET_HashCode h_use_pub;
    187 
    188   GNUNET_CRYPTO_hash (&use_pub->public_key,
    189                       sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
    190                       &h_use_pub);
    191 
    192   if (GNUNET_OK !=
    193       GNUNET_CRYPTO_blind_sig_verify (issue_pub->public_key,
    194                                       ub_sig->signature,
    195                                       &h_use_pub,
    196                                       sizeof (h_use_pub)))
    197   {
    198     GNUNET_break_op (0);
    199     return GNUNET_SYSERR;
    200   }
    201   return GNUNET_OK;
    202 }
    203 
    204 
    205 enum GNUNET_GenericReturnValue
    206 TALER_token_issue_sig_unblind (
    207   struct TALER_TokenIssueSignature *issue_sig,
    208   const struct TALER_BlindedTokenIssueSignature *blinded_sig,
    209   const union GNUNET_CRYPTO_BlindingSecretP *secret,
    210   const struct TALER_TokenUsePublicKeyHashP *use_pub_hash,
    211   const struct TALER_TokenUseMerchantValues *alg_values,
    212   const struct TALER_TokenIssuePublicKey *issue_pub)
    213 {
    214   issue_sig->signature
    215     = GNUNET_CRYPTO_blind_sig_unblind (blinded_sig->signature,
    216                                        secret,
    217                                        &use_pub_hash->hash,
    218                                        sizeof (use_pub_hash->hash),
    219                                        alg_values->blinding_inputs,
    220                                        issue_pub->public_key);
    221   if (NULL == issue_sig->signature)
    222   {
    223     GNUNET_break_op (0);
    224     return GNUNET_SYSERR;
    225   }
    226   return GNUNET_OK;
    227 }
    228 
    229 
    230 void
    231 TALER_token_issue_pub_free (struct TALER_TokenIssuePublicKey *token_pub)
    232 {
    233   if (NULL != token_pub->public_key)
    234   {
    235     GNUNET_CRYPTO_blind_sign_pub_decref (token_pub->public_key);
    236     token_pub->public_key = NULL;
    237   }
    238 }
    239 
    240 
    241 int
    242 TALER_token_issue_pub_cmp (
    243   struct TALER_TokenIssuePublicKey *tip1,
    244   const struct TALER_TokenIssuePublicKey *tip2)
    245 {
    246   if (tip1->public_key->cipher !=
    247       tip2->public_key->cipher)
    248     return (tip1->public_key->cipher >
    249             tip2->public_key->cipher) ? 1 : -1;
    250   return GNUNET_CRYPTO_bsign_pub_cmp (tip1->public_key,
    251                                       tip2->public_key);
    252 }
    253 
    254 
    255 void
    256 TALER_token_issue_pub_copy (
    257   struct TALER_TokenIssuePublicKey *tip_dst,
    258   const struct TALER_TokenIssuePublicKey *tip_src)
    259 {
    260   tip_dst->public_key
    261     = GNUNET_CRYPTO_bsign_pub_incref (tip_src->public_key);
    262 }