LCOV - code coverage report
Current view: top level - util - crypto_contract.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 139 198 70.2 %
Date: 2025-06-05 21:03:14 Functions: 9 9 100.0 %

          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 "platform.h"
      22             : #include "taler_util.h"
      23             : #include <zlib.h>
      24             : #include "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 1.16