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

Generated by: LCOV version 2.0-1