LCOV - code coverage report
Current view: top level - util - crypto_contract.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 70.2 % 198 139
Test Date: 2026-03-20 20:15:26 Functions: 100.0 % 9 9

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2022 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 util/crypto_contract.c
      18              :  * @brief functions for encrypting and decrypting contracts for P2P payments
      19              :  * @author Christian Grothoff <christian@grothoff.org>
      20              :  */
      21              : #include "taler/platform.h"
      22              : #include "taler/taler_util.h"
      23              : #include <zlib.h>
      24              : #include "taler/taler_exchange_service.h"
      25              : 
      26              : 
      27              : /**
      28              :  * Different types of contracts supported.
      29              :  */
      30              : enum ContractFormats
      31              : {
      32              :   /**
      33              :    * The encrypted contract represents a payment offer. The receiver
      34              :    * can merge it into a reserve/account to accept the contract and
      35              :    * obtain the payment.
      36              :    */
      37              :   TALER_EXCHANGE_CONTRACT_PAYMENT_OFFER = 0,
      38              : 
      39              :   /**
      40              :    * The encrypted contract represents a payment request.
      41              :    */
      42              :   TALER_EXCHANGE_CONTRACT_PAYMENT_REQUEST = 1
      43              : };
      44              : 
      45              : 
      46              : /**
      47              :  * Nonce used for encryption, 24 bytes.
      48              :  */
      49              : struct NonceP
      50              : {
      51              :   uint8_t nonce[crypto_secretbox_NONCEBYTES];
      52              : };
      53              : 
      54              : /**
      55              :  * Specifies a key used for symmetric encryption, 32 bytes.
      56              :  */
      57              : struct SymKeyP
      58              : {
      59              :   uint32_t key[8];
      60              : };
      61              : 
      62              : 
      63              : /**
      64              :  * Compute @a key.
      65              :  *
      66              :  * @param key_material key for calculation
      67              :  * @param key_m_len length of key
      68              :  * @param nonce nonce for calculation
      69              :  * @param salt salt value for calculation
      70              :  * @param[out] key where to write the en-/description key
      71              :  */
      72              : static void
      73           57 : derive_key (const void *key_material,
      74              :             size_t key_m_len,
      75              :             const struct NonceP *nonce,
      76              :             const char *salt,
      77              :             struct SymKeyP *key)
      78              : {
      79           57 :   GNUNET_assert (GNUNET_YES ==
      80              :                  GNUNET_CRYPTO_hkdf_gnunet (
      81              :                    key,
      82              :                    sizeof (*key),
      83              :                    /* salt / XTS */
      84              :                    nonce,
      85              :                    sizeof (*nonce),
      86              :                    /* ikm */
      87              :                    key_material,
      88              :                    key_m_len,
      89              :                    /* info chunks */
      90              :                    /* The "salt" passed here is actually not something random,
      91              :                       but a protocol-specific identifier string.  Thus
      92              :                       we pass it as a context info to the HKDF */
      93              :                    GNUNET_CRYPTO_kdf_arg_string (salt)));
      94           57 : }
      95              : 
      96              : 
      97              : /**
      98              :  * Encryption of data.
      99              :  *
     100              :  * @param nonce value to use for the nonce
     101              :  * @param key key which is used to derive a key/iv pair from
     102              :  * @param key_len length of key
     103              :  * @param data data to encrypt
     104              :  * @param data_size size of the data
     105              :  * @param salt salt value which is used for key derivation
     106              :  * @param[out] res ciphertext output
     107              :  * @param[out] res_size size of the ciphertext
     108              :  */
     109              : static void
     110           37 : blob_encrypt (const struct NonceP *nonce,
     111              :               const void *key,
     112              :               size_t key_len,
     113              :               const void *data,
     114              :               size_t data_size,
     115              :               const char *salt,
     116              :               void **res,
     117              :               size_t *res_size)
     118              : {
     119              :   size_t ciphertext_size;
     120              :   struct SymKeyP skey;
     121              : 
     122           37 :   derive_key (key,
     123              :               key_len,
     124              :               nonce,
     125              :               salt,
     126              :               &skey);
     127           37 :   ciphertext_size = crypto_secretbox_NONCEBYTES
     128              :                     + crypto_secretbox_MACBYTES
     129              :                     + data_size;
     130           37 :   *res_size = ciphertext_size;
     131           37 :   *res = GNUNET_malloc (ciphertext_size);
     132           37 :   GNUNET_memcpy (*res,
     133              :                  nonce,
     134              :                  crypto_secretbox_NONCEBYTES);
     135           37 :   GNUNET_assert (0 ==
     136              :                  crypto_secretbox_easy (*res + crypto_secretbox_NONCEBYTES,
     137              :                                         data,
     138              :                                         data_size,
     139              :                                         (void *) nonce,
     140              :                                         (void *) &skey));
     141           37 : }
     142              : 
     143              : 
     144              : /**
     145              :  * Decryption of data like encrypted recovery document etc.
     146              :  *
     147              :  * @param key key which is used to derive a key/iv pair from
     148              :  * @param key_len length of key
     149              :  * @param data data to decrypt
     150              :  * @param data_size size of the data
     151              :  * @param salt salt value which is used for key derivation
     152              :  * @param[out] res plaintext output
     153              :  * @param[out] res_size size of the plaintext
     154              :  * @return #GNUNET_OK on success
     155              :  */
     156              : static enum GNUNET_GenericReturnValue
     157           20 : blob_decrypt (const void *key,
     158              :               size_t key_len,
     159              :               const void *data,
     160              :               size_t data_size,
     161              :               const char *salt,
     162              :               void **res,
     163              :               size_t *res_size)
     164              : {
     165              :   const struct NonceP *nonce;
     166              :   struct SymKeyP skey;
     167              :   size_t plaintext_size;
     168              : 
     169           20 :   if (data_size < crypto_secretbox_NONCEBYTES + crypto_secretbox_MACBYTES)
     170              :   {
     171            0 :     GNUNET_break (0);
     172            0 :     return GNUNET_SYSERR;
     173              :   }
     174           20 :   nonce = data;
     175           20 :   derive_key (key,
     176              :               key_len,
     177              :               nonce,
     178              :               salt,
     179              :               &skey);
     180           20 :   plaintext_size = data_size - (crypto_secretbox_NONCEBYTES
     181              :                                 + crypto_secretbox_MACBYTES);
     182           20 :   *res = GNUNET_malloc (plaintext_size);
     183           20 :   *res_size = plaintext_size;
     184           20 :   if (0 != crypto_secretbox_open_easy (*res,
     185           20 :                                        data + crypto_secretbox_NONCEBYTES,
     186           20 :                                        data_size - crypto_secretbox_NONCEBYTES,
     187              :                                        (void *) nonce,
     188              :                                        (void *) &skey))
     189              :   {
     190            0 :     GNUNET_break (0);
     191            0 :     GNUNET_free (*res);
     192            0 :     return GNUNET_SYSERR;
     193              :   }
     194           20 :   return GNUNET_OK;
     195              : }
     196              : 
     197              : 
     198              : /**
     199              :  * Header for encrypted contracts.
     200              :  */
     201              : struct ContractHeaderP
     202              : {
     203              :   /**
     204              :    * Type of the contract, in NBO.
     205              :    */
     206              :   uint32_t ctype;
     207              : 
     208              :   /**
     209              :    * Length of the encrypted contract, in NBO.
     210              :    */
     211              :   uint32_t clen;
     212              : };
     213              : 
     214              : 
     215              : /**
     216              :  * Header for encrypted contracts.
     217              :  */
     218              : struct ContractHeaderMergeP
     219              : {
     220              :   /**
     221              :    * Generic header.
     222              :    */
     223              :   struct ContractHeaderP header;
     224              : 
     225              :   /**
     226              :    * Private key with the merge capability.
     227              :    */
     228              :   struct TALER_PurseMergePrivateKeyP merge_priv;
     229              : };
     230              : 
     231              : 
     232              : /**
     233              :  * Salt we use when encrypting contracts for merge.
     234              :  */
     235              : #define MERGE_SALT "p2p-merge-contract"
     236              : 
     237              : 
     238              : void
     239           12 : TALER_CRYPTO_contract_encrypt_for_merge (
     240              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
     241              :   const struct TALER_ContractDiffiePrivateP *contract_priv,
     242              :   const struct TALER_PurseMergePrivateKeyP *merge_priv,
     243              :   const json_t *contract_terms,
     244              :   void **econtract,
     245              :   size_t *econtract_size)
     246              : {
     247              :   struct GNUNET_HashCode key;
     248              :   char *cstr;
     249              :   size_t clen;
     250              :   void *xbuf;
     251              :   struct ContractHeaderMergeP *hdr;
     252              :   struct NonceP nonce;
     253              :   uLongf cbuf_size;
     254              :   int ret;
     255              : 
     256           12 :   GNUNET_assert (GNUNET_OK ==
     257              :                  GNUNET_CRYPTO_ecdh_eddsa (&contract_priv->ecdhe_priv,
     258              :                                            &purse_pub->eddsa_pub,
     259              :                                            &key));
     260           12 :   cstr = json_dumps (contract_terms,
     261              :                      JSON_COMPACT | JSON_SORT_KEYS);
     262           12 :   clen = strlen (cstr);
     263           12 :   cbuf_size = compressBound (clen);
     264           12 :   xbuf = GNUNET_malloc (cbuf_size);
     265           12 :   ret = compress (xbuf,
     266              :                   &cbuf_size,
     267              :                   (const Bytef *) cstr,
     268              :                   clen);
     269           12 :   GNUNET_assert (Z_OK == ret);
     270           12 :   free (cstr);
     271           12 :   hdr = GNUNET_malloc (sizeof (*hdr) + cbuf_size);
     272           12 :   hdr->header.ctype = htonl (TALER_EXCHANGE_CONTRACT_PAYMENT_OFFER);
     273           12 :   hdr->header.clen = htonl ((uint32_t) clen);
     274           12 :   hdr->merge_priv = *merge_priv;
     275           12 :   GNUNET_memcpy (&hdr[1],
     276              :                  xbuf,
     277              :                  cbuf_size);
     278           12 :   GNUNET_free (xbuf);
     279           12 :   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
     280              :                               &nonce,
     281              :                               sizeof (nonce));
     282           12 :   blob_encrypt (&nonce,
     283              :                 &key,
     284              :                 sizeof (key),
     285              :                 hdr,
     286              :                 sizeof (*hdr) + cbuf_size,
     287              :                 MERGE_SALT,
     288              :                 econtract,
     289              :                 econtract_size);
     290           12 :   GNUNET_free (hdr);
     291           12 : }
     292              : 
     293              : 
     294              : json_t *
     295            4 : TALER_CRYPTO_contract_decrypt_for_merge (
     296              :   const struct TALER_ContractDiffiePrivateP *contract_priv,
     297              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
     298              :   const void *econtract,
     299              :   size_t econtract_size,
     300              :   struct TALER_PurseMergePrivateKeyP *merge_priv)
     301              : {
     302              :   struct GNUNET_HashCode key;
     303              :   void *xhdr;
     304              :   size_t hdr_size;
     305              :   const struct ContractHeaderMergeP *hdr;
     306              :   char *cstr;
     307              :   uLongf clen;
     308              :   json_error_t json_error;
     309              :   json_t *ret;
     310              : 
     311            4 :   if (GNUNET_OK !=
     312            4 :       GNUNET_CRYPTO_ecdh_eddsa (&contract_priv->ecdhe_priv,
     313              :                                 &purse_pub->eddsa_pub,
     314              :                                 &key))
     315              :   {
     316            0 :     GNUNET_break (0);
     317            0 :     return NULL;
     318              :   }
     319            4 :   if (GNUNET_OK !=
     320            4 :       blob_decrypt (&key,
     321              :                     sizeof (key),
     322              :                     econtract,
     323              :                     econtract_size,
     324              :                     MERGE_SALT,
     325              :                     &xhdr,
     326              :                     &hdr_size))
     327              :   {
     328            0 :     GNUNET_break_op (0);
     329            0 :     return NULL;
     330              :   }
     331            4 :   if (hdr_size < sizeof (*hdr))
     332              :   {
     333            0 :     GNUNET_break_op (0);
     334            0 :     GNUNET_free (xhdr);
     335            0 :     return NULL;
     336              :   }
     337            4 :   hdr = xhdr;
     338            4 :   if (TALER_EXCHANGE_CONTRACT_PAYMENT_OFFER != ntohl (hdr->header.ctype))
     339              :   {
     340            0 :     GNUNET_break_op (0);
     341            0 :     GNUNET_free (xhdr);
     342            0 :     return NULL;
     343              :   }
     344            4 :   clen = ntohl (hdr->header.clen);
     345            4 :   if (clen >= GNUNET_MAX_MALLOC_CHECKED)
     346              :   {
     347            0 :     GNUNET_break_op (0);
     348            0 :     GNUNET_free (xhdr);
     349            0 :     return NULL;
     350              :   }
     351            4 :   cstr = GNUNET_malloc (clen + 1);
     352            4 :   if (Z_OK !=
     353            4 :       uncompress ((Bytef *) cstr,
     354              :                   &clen,
     355            4 :                   (const Bytef *) &hdr[1],
     356              :                   hdr_size - sizeof (*hdr)))
     357              :   {
     358            0 :     GNUNET_break_op (0);
     359            0 :     GNUNET_free (cstr);
     360            0 :     GNUNET_free (xhdr);
     361            0 :     return NULL;
     362              :   }
     363            4 :   *merge_priv = hdr->merge_priv;
     364            4 :   GNUNET_free (xhdr);
     365            4 :   ret = json_loadb ((char *) cstr,
     366              :                     clen,
     367              :                     JSON_DECODE_ANY,
     368              :                     &json_error);
     369            4 :   if (NULL == ret)
     370              :   {
     371            0 :     GNUNET_break_op (0);
     372            0 :     GNUNET_free (cstr);
     373            0 :     return NULL;
     374              :   }
     375            4 :   GNUNET_free (cstr);
     376            4 :   return ret;
     377              : }
     378              : 
     379              : 
     380              : /**
     381              :  * Salt we use when encrypting contracts for merge.
     382              :  */
     383              : #define DEPOSIT_SALT "p2p-deposit-contract"
     384              : 
     385              : 
     386              : void
     387           14 : TALER_CRYPTO_contract_encrypt_for_deposit (
     388              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
     389              :   const struct TALER_ContractDiffiePrivateP *contract_priv,
     390              :   const json_t *contract_terms,
     391              :   void **econtract,
     392              :   size_t *econtract_size)
     393              : {
     394              :   struct GNUNET_HashCode key;
     395              :   char *cstr;
     396              :   size_t clen;
     397              :   void *xbuf;
     398              :   struct ContractHeaderP *hdr;
     399              :   struct NonceP nonce;
     400              :   uLongf cbuf_size;
     401              :   int ret;
     402              :   void *xecontract;
     403              :   size_t xecontract_size;
     404              : 
     405           14 :   GNUNET_assert (GNUNET_OK ==
     406              :                  GNUNET_CRYPTO_ecdh_eddsa (&contract_priv->ecdhe_priv,
     407              :                                            &purse_pub->eddsa_pub,
     408              :                                            &key));
     409           14 :   cstr = json_dumps (contract_terms,
     410              :                      JSON_COMPACT | JSON_SORT_KEYS);
     411           14 :   GNUNET_assert (NULL != cstr);
     412           14 :   clen = strlen (cstr);
     413           14 :   cbuf_size = compressBound (clen);
     414           14 :   xbuf = GNUNET_malloc (cbuf_size);
     415           14 :   ret = compress (xbuf,
     416              :                   &cbuf_size,
     417              :                   (const Bytef *) cstr,
     418              :                   clen);
     419           14 :   GNUNET_assert (Z_OK == ret);
     420           14 :   free (cstr);
     421           14 :   hdr = GNUNET_malloc (sizeof (*hdr) + cbuf_size);
     422           14 :   hdr->ctype = htonl (TALER_EXCHANGE_CONTRACT_PAYMENT_REQUEST);
     423           14 :   hdr->clen = htonl ((uint32_t) clen);
     424           14 :   GNUNET_memcpy (&hdr[1],
     425              :                  xbuf,
     426              :                  cbuf_size);
     427           14 :   GNUNET_free (xbuf);
     428           14 :   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
     429              :                               &nonce,
     430              :                               sizeof (nonce));
     431           14 :   blob_encrypt (&nonce,
     432              :                 &key,
     433              :                 sizeof (key),
     434              :                 hdr,
     435              :                 sizeof (*hdr) + cbuf_size,
     436              :                 DEPOSIT_SALT,
     437              :                 &xecontract,
     438              :                 &xecontract_size);
     439           14 :   GNUNET_free (hdr);
     440              :   /* prepend purse_pub */
     441           14 :   *econtract = GNUNET_malloc (xecontract_size + sizeof (*purse_pub));
     442           14 :   GNUNET_memcpy (*econtract,
     443              :                  purse_pub,
     444              :                  sizeof (*purse_pub));
     445           14 :   GNUNET_memcpy (sizeof (*purse_pub) + *econtract,
     446              :                  xecontract,
     447              :                  xecontract_size);
     448           14 :   *econtract_size = xecontract_size + sizeof (*purse_pub);
     449           14 :   GNUNET_free (xecontract);
     450           14 : }
     451              : 
     452              : 
     453              : json_t *
     454            3 : TALER_CRYPTO_contract_decrypt_for_deposit (
     455              :   const struct TALER_ContractDiffiePrivateP *contract_priv,
     456              :   const void *econtract,
     457              :   size_t econtract_size)
     458              : {
     459            3 :   const struct TALER_PurseContractPublicKeyP *purse_pub = econtract;
     460              :   struct GNUNET_HashCode key;
     461              :   void *xhdr;
     462              :   size_t hdr_size;
     463              :   const struct ContractHeaderP *hdr;
     464              :   char *cstr;
     465              :   uLongf clen;
     466              :   json_error_t json_error;
     467              :   json_t *ret;
     468              : 
     469            3 :   if (econtract_size < sizeof (*purse_pub))
     470              :   {
     471            0 :     GNUNET_break_op (0);
     472            0 :     return NULL;
     473              :   }
     474            3 :   if (GNUNET_OK !=
     475            3 :       GNUNET_CRYPTO_ecdh_eddsa (&contract_priv->ecdhe_priv,
     476              :                                 &purse_pub->eddsa_pub,
     477              :                                 &key))
     478              :   {
     479            0 :     GNUNET_break (0);
     480            0 :     return NULL;
     481              :   }
     482            3 :   econtract += sizeof (*purse_pub);
     483            3 :   econtract_size -= sizeof (*purse_pub);
     484            3 :   if (GNUNET_OK !=
     485            3 :       blob_decrypt (&key,
     486              :                     sizeof (key),
     487              :                     econtract,
     488              :                     econtract_size,
     489              :                     DEPOSIT_SALT,
     490              :                     &xhdr,
     491              :                     &hdr_size))
     492              :   {
     493            0 :     GNUNET_break_op (0);
     494            0 :     return NULL;
     495              :   }
     496            3 :   if (hdr_size < sizeof (*hdr))
     497              :   {
     498            0 :     GNUNET_break_op (0);
     499            0 :     GNUNET_free (xhdr);
     500            0 :     return NULL;
     501              :   }
     502            3 :   hdr = xhdr;
     503            3 :   if (TALER_EXCHANGE_CONTRACT_PAYMENT_REQUEST != ntohl (hdr->ctype))
     504              :   {
     505            0 :     GNUNET_break_op (0);
     506            0 :     GNUNET_free (xhdr);
     507            0 :     return NULL;
     508              :   }
     509            3 :   clen = ntohl (hdr->clen);
     510            3 :   if (clen >= GNUNET_MAX_MALLOC_CHECKED)
     511              :   {
     512            0 :     GNUNET_break_op (0);
     513            0 :     GNUNET_free (xhdr);
     514            0 :     return NULL;
     515              :   }
     516            3 :   cstr = GNUNET_malloc (clen + 1);
     517            3 :   if (Z_OK !=
     518            3 :       uncompress ((Bytef *) cstr,
     519              :                   &clen,
     520            3 :                   (const Bytef *) &hdr[1],
     521              :                   hdr_size - sizeof (*hdr)))
     522              :   {
     523            0 :     GNUNET_break_op (0);
     524            0 :     GNUNET_free (cstr);
     525            0 :     GNUNET_free (xhdr);
     526            0 :     return NULL;
     527              :   }
     528            3 :   GNUNET_free (xhdr);
     529            3 :   ret = json_loadb ((char *) cstr,
     530              :                     clen,
     531              :                     JSON_DECODE_ANY,
     532              :                     &json_error);
     533            3 :   if (NULL == ret)
     534              :   {
     535            0 :     GNUNET_break_op (0);
     536            0 :     GNUNET_free (cstr);
     537            0 :     return NULL;
     538              :   }
     539            3 :   GNUNET_free (cstr);
     540            3 :   return ret;
     541              : }
     542              : 
     543              : 
     544              : /**
     545              :  * Salt we use when encrypting KYC attributes.
     546              :  */
     547              : #define ATTRIBUTE_SALT "kyc-attributes"
     548              : 
     549              : 
     550              : void
     551           11 : TALER_CRYPTO_kyc_attributes_encrypt (
     552              :   const struct TALER_AttributeEncryptionKeyP *key,
     553              :   const json_t *attr,
     554              :   void **enc_attr,
     555              :   size_t *enc_attr_size)
     556              : {
     557              :   uLongf cbuf_size;
     558              :   char *cstr;
     559              :   uLongf clen;
     560              :   void *xbuf;
     561              :   int ret;
     562              :   uint32_t belen;
     563              :   struct NonceP nonce;
     564              : 
     565           11 :   cstr = json_dumps (attr,
     566              :                      JSON_COMPACT | JSON_SORT_KEYS);
     567           11 :   GNUNET_assert (NULL != cstr);
     568           11 :   clen = strlen (cstr);
     569           11 :   GNUNET_assert (clen <= UINT32_MAX);
     570           11 :   cbuf_size = compressBound (clen);
     571           11 :   xbuf = GNUNET_malloc (cbuf_size + sizeof (uint32_t));
     572           11 :   belen = htonl ((uint32_t) clen);
     573           11 :   GNUNET_memcpy (xbuf,
     574              :                  &belen,
     575              :                  sizeof (belen));
     576           11 :   ret = compress (xbuf + 4,
     577              :                   &cbuf_size,
     578              :                   (const Bytef *) cstr,
     579              :                   clen);
     580           11 :   GNUNET_assert (Z_OK == ret);
     581           11 :   free (cstr);
     582           11 :   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
     583              :                               &nonce,
     584              :                               sizeof (nonce));
     585           11 :   blob_encrypt (&nonce,
     586              :                 key,
     587              :                 sizeof (*key),
     588              :                 xbuf,
     589              :                 cbuf_size + sizeof (uint32_t),
     590              :                 ATTRIBUTE_SALT,
     591              :                 enc_attr,
     592              :                 enc_attr_size);
     593           11 :   GNUNET_free (xbuf);
     594           11 : }
     595              : 
     596              : 
     597              : json_t *
     598           13 : TALER_CRYPTO_kyc_attributes_decrypt (
     599              :   const struct TALER_AttributeEncryptionKeyP *key,
     600              :   const void *enc_attr,
     601              :   size_t enc_attr_size)
     602              : {
     603              :   void *xhdr;
     604              :   size_t hdr_size;
     605              :   char *cstr;
     606              :   uLongf clen;
     607              :   json_error_t json_error;
     608              :   json_t *ret;
     609              :   uint32_t belen;
     610              : 
     611           13 :   if (GNUNET_OK !=
     612           13 :       blob_decrypt (key,
     613              :                     sizeof (*key),
     614              :                     enc_attr,
     615              :                     enc_attr_size,
     616              :                     ATTRIBUTE_SALT,
     617              :                     &xhdr,
     618              :                     &hdr_size))
     619              :   {
     620            0 :     GNUNET_break_op (0);
     621            0 :     return NULL;
     622              :   }
     623           13 :   GNUNET_memcpy (&belen,
     624              :                  xhdr,
     625              :                  sizeof (belen));
     626           13 :   clen = ntohl (belen);
     627           13 :   if (clen >= GNUNET_MAX_MALLOC_CHECKED)
     628              :   {
     629            0 :     GNUNET_break_op (0);
     630            0 :     GNUNET_free (xhdr);
     631            0 :     return NULL;
     632              :   }
     633           13 :   cstr = GNUNET_malloc (clen + 1);
     634           13 :   if (Z_OK !=
     635           13 :       uncompress ((Bytef *) cstr,
     636              :                   &clen,
     637           13 :                   (const Bytef *) (xhdr + sizeof (uint32_t)),
     638              :                   hdr_size - sizeof (uint32_t)))
     639              :   {
     640            0 :     GNUNET_break_op (0);
     641            0 :     GNUNET_free (cstr);
     642            0 :     GNUNET_free (xhdr);
     643            0 :     return NULL;
     644              :   }
     645           13 :   GNUNET_free (xhdr);
     646           13 :   ret = json_loadb ((char *) cstr,
     647              :                     clen,
     648              :                     JSON_DECODE_ANY,
     649              :                     &json_error);
     650           13 :   if (NULL == ret)
     651              :   {
     652            0 :     GNUNET_break_op (0);
     653            0 :     GNUNET_free (cstr);
     654            0 :     return NULL;
     655              :   }
     656           13 :   GNUNET_free (cstr);
     657           13 :   return ret;
     658              : }
        

Generated by: LCOV version 2.0-1