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

Generated by: LCOV version 2.0-1