gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated: write KYC attribute encryption l


From: gnunet
Subject: [taler-exchange] branch master updated: write KYC attribute encryption logic
Date: Sat, 31 Dec 2022 15:10:39 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new c5ad98da write KYC attribute encryption logic
c5ad98da is described below

commit c5ad98da9812a05d078b6b017a545959ada96a3d
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sat Dec 31 15:10:35 2022 +0100

    write KYC attribute encryption logic
---
 src/include/taler_crypto_lib.h |  44 +++++++++
 src/util/crypto_contract.c     | 215 ++++++++++++++++++++++++++++++++---------
 src/util/test_crypto.c         |  45 ++++++++-
 3 files changed, 255 insertions(+), 49 deletions(-)

diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 5e7ea605..ca80c6cc 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -603,6 +603,19 @@ struct TALER_RefreshCommitmentP
 };
 
 
+/**
+ * Symmetric key we use to encrypt KYC attributes
+ * in our database.
+ */
+struct TALER_AttributeEncryptionKeyP
+{
+  /**
+   * The key is a hash code.
+   */
+  struct GNUNET_HashCode hash;
+};
+
+
 /**
  * Token used for access control to the merchant's unclaimed
  * orders.
@@ -1791,6 +1804,37 @@ TALER_denom_pub_verify (const struct 
TALER_DenominationPublicKey *denom_pub,
                         const struct TALER_CoinPubHashP *c_hash);
 
 
+/**
+ * Encrypts KYC attributes for storage in the database.
+ *
+ * @param key encryption key to use
+ * @param attr set of attributes to encrypt
+ * @param[out] enc_attr encrypted attribute data
+ * @param[out] enc_attr_size number of bytes in @a enc_attr
+ */
+void
+TALER_CRYPTO_kyc_attributes_encrypt (
+  const struct TALER_AttributeEncryptionKeyP *key,
+  const json_t *attr,
+  void **enc_attr,
+  size_t *enc_attr_size);
+
+
+/**
+ * Encrypts KYC attributes for storage in the database.
+ *
+ * @param key encryption key to use
+ * @param enc_attr encrypted attribute data
+ * @param enc_attr_size number of bytes in @a enc_attr
+ * @return set of decrypted attributes, NULL on failure
+ */
+json_t *
+TALER_CRYPTO_kyc_attributes_decrypt (
+  const struct TALER_AttributeEncryptionKeyP *key,
+  const void *enc_attr,
+  size_t enc_attr_size);
+
+
 /**
  * Check if a coin is valid; that is, whether the denomination key exists,
  * is not expired, and the signature is correct.
diff --git a/src/util/crypto_contract.c b/src/util/crypto_contract.c
index fe6b1e6a..3bfe9eb8 100644
--- a/src/util/crypto_contract.c
+++ b/src/util/crypto_contract.c
@@ -109,14 +109,14 @@ derive_key (const void *key_material,
  * @param[out] res_size size of the ciphertext
  */
 static void
-contract_encrypt (const struct NonceP *nonce,
-                  const void *key,
-                  size_t key_len,
-                  const void *data,
-                  size_t data_size,
-                  const char *salt,
-                  void **res,
-                  size_t *res_size)
+blob_encrypt (const struct NonceP *nonce,
+              const void *key,
+              size_t key_len,
+              const void *data,
+              size_t data_size,
+              const char *salt,
+              void **res,
+              size_t *res_size)
 {
   size_t ciphertext_size;
   struct SymKeyP skey;
@@ -127,10 +127,13 @@ contract_encrypt (const struct NonceP *nonce,
               salt,
               &skey);
   ciphertext_size = crypto_secretbox_NONCEBYTES
-                    + crypto_secretbox_MACBYTES + data_size;
+                    + crypto_secretbox_MACBYTES
+                    + data_size;
   *res_size = ciphertext_size;
   *res = GNUNET_malloc (ciphertext_size);
-  memcpy (*res, nonce, crypto_secretbox_NONCEBYTES);
+  memcpy (*res,
+          nonce,
+          crypto_secretbox_NONCEBYTES);
   GNUNET_assert (0 ==
                  crypto_secretbox_easy (*res + crypto_secretbox_NONCEBYTES,
                                         data,
@@ -153,13 +156,13 @@ contract_encrypt (const struct NonceP *nonce,
  * @return #GNUNET_OK on success
  */
 static enum GNUNET_GenericReturnValue
-contract_decrypt (const void *key,
-                  size_t key_len,
-                  const void *data,
-                  size_t data_size,
-                  const char *salt,
-                  void **res,
-                  size_t *res_size)
+blob_decrypt (const void *key,
+              size_t key_len,
+              const void *data,
+              size_t data_size,
+              const char *salt,
+              void **res,
+              size_t *res_size)
 {
   const struct NonceP *nonce;
   struct SymKeyP skey;
@@ -278,14 +281,14 @@ TALER_CRYPTO_contract_encrypt_for_merge (
   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
                               &nonce,
                               sizeof (nonce));
-  contract_encrypt (&nonce,
-                    &key,
-                    sizeof (key),
-                    hdr,
-                    sizeof (*hdr) + cbuf_size,
-                    MERGE_SALT,
-                    econtract,
-                    econtract_size);
+  blob_encrypt (&nonce,
+                &key,
+                sizeof (key),
+                hdr,
+                sizeof (*hdr) + cbuf_size,
+                MERGE_SALT,
+                econtract,
+                econtract_size);
   GNUNET_free (hdr);
 }
 
@@ -316,13 +319,13 @@ TALER_CRYPTO_contract_decrypt_for_merge (
     return NULL;
   }
   if (GNUNET_OK !=
-      contract_decrypt (&key,
-                        sizeof (key),
-                        econtract,
-                        econtract_size,
-                        MERGE_SALT,
-                        &xhdr,
-                        &hdr_size))
+      blob_decrypt (&key,
+                    sizeof (key),
+                    econtract,
+                    econtract_size,
+                    MERGE_SALT,
+                    &xhdr,
+                    &hdr_size))
   {
     GNUNET_break_op (0);
     return NULL;
@@ -407,6 +410,7 @@ TALER_CRYPTO_contract_encrypt_for_deposit (
                                            &key));
   cstr = json_dumps (contract_terms,
                      JSON_COMPACT | JSON_SORT_KEYS);
+  GNUNET_assert (NULL != cstr);
   clen = strlen (cstr);
   cbuf_size = compressBound (clen);
   xbuf = GNUNET_malloc (cbuf_size);
@@ -426,14 +430,14 @@ TALER_CRYPTO_contract_encrypt_for_deposit (
   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
                               &nonce,
                               sizeof (nonce));
-  contract_encrypt (&nonce,
-                    &key,
-                    sizeof (key),
-                    hdr,
-                    sizeof (*hdr) + cbuf_size,
-                    DEPOSIT_SALT,
-                    &xecontract,
-                    &xecontract_size);
+  blob_encrypt (&nonce,
+                &key,
+                sizeof (key),
+                hdr,
+                sizeof (*hdr) + cbuf_size,
+                DEPOSIT_SALT,
+                &xecontract,
+                &xecontract_size);
   GNUNET_free (hdr);
   /* prepend purse_pub */
   *econtract = GNUNET_malloc (xecontract_size + sizeof (*purse_pub));
@@ -481,13 +485,13 @@ TALER_CRYPTO_contract_decrypt_for_deposit (
   econtract += sizeof (*purse_pub);
   econtract_size -= sizeof (*purse_pub);
   if (GNUNET_OK !=
-      contract_decrypt (&key,
-                        sizeof (key),
-                        econtract,
-                        econtract_size,
-                        DEPOSIT_SALT,
-                        &xhdr,
-                        &hdr_size))
+      blob_decrypt (&key,
+                    sizeof (key),
+                    econtract,
+                    econtract_size,
+                    DEPOSIT_SALT,
+                    &xhdr,
+                    &hdr_size))
   {
     GNUNET_break_op (0);
     return NULL;
@@ -538,3 +542,120 @@ TALER_CRYPTO_contract_decrypt_for_deposit (
   GNUNET_free (cstr);
   return ret;
 }
+
+
+/**
+ * Salt we use when encrypting KYC attributes.
+ */
+#define ATTRIBUTE_SALT "kyc-attributes"
+
+
+void
+TALER_CRYPTO_kyc_attributes_encrypt (
+  const struct TALER_AttributeEncryptionKeyP *key,
+  const json_t *attr,
+  void **enc_attr,
+  size_t *enc_attr_size)
+{
+  uLongf cbuf_size;
+  char *cstr;
+  uLongf clen;
+  void *xbuf;
+  int ret;
+  uint32_t belen;
+  struct NonceP nonce;
+
+  cstr = json_dumps (attr,
+                     JSON_COMPACT | JSON_SORT_KEYS);
+  GNUNET_assert (NULL != cstr);
+  clen = strlen (cstr);
+  GNUNET_assert (clen <= UINT32_MAX);
+  cbuf_size = compressBound (clen);
+  xbuf = GNUNET_malloc (cbuf_size + sizeof (uint32_t));
+  belen = htonl ((uint32_t) clen);
+  memcpy (xbuf,
+          &belen,
+          sizeof (belen));
+  ret = compress (xbuf + 4,
+                  &cbuf_size,
+                  (const Bytef *) cstr,
+                  clen);
+  GNUNET_assert (Z_OK == ret);
+  free (cstr);
+  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
+                              &nonce,
+                              sizeof (nonce));
+  blob_encrypt (&nonce,
+                key,
+                sizeof (*key),
+                xbuf,
+                cbuf_size + sizeof (uint32_t),
+                ATTRIBUTE_SALT,
+                enc_attr,
+                enc_attr_size);
+  GNUNET_free (xbuf);
+}
+
+
+json_t *
+TALER_CRYPTO_kyc_attributes_decrypt (
+  const struct TALER_AttributeEncryptionKeyP *key,
+  const void *enc_attr,
+  size_t enc_attr_size)
+{
+  void *xhdr;
+  size_t hdr_size;
+  char *cstr;
+  uLongf clen;
+  json_error_t json_error;
+  json_t *ret;
+  uint32_t belen;
+
+  if (GNUNET_OK !=
+      blob_decrypt (key,
+                    sizeof (*key),
+                    enc_attr,
+                    enc_attr_size,
+                    ATTRIBUTE_SALT,
+                    &xhdr,
+                    &hdr_size))
+  {
+    GNUNET_break_op (0);
+    return NULL;
+  }
+  memcpy (&belen,
+          xhdr,
+          sizeof (belen));
+  clen = ntohl (belen);
+  if (clen >= GNUNET_MAX_MALLOC_CHECKED)
+  {
+    GNUNET_break_op (0);
+    GNUNET_free (xhdr);
+    return NULL;
+  }
+  cstr = GNUNET_malloc (clen + 1);
+  if (Z_OK !=
+      uncompress ((Bytef *) cstr,
+                  &clen,
+                  (const Bytef *) (xhdr + sizeof (uint32_t)),
+                  hdr_size - sizeof (uint32_t)))
+  {
+    GNUNET_break_op (0);
+    GNUNET_free (cstr);
+    GNUNET_free (xhdr);
+    return NULL;
+  }
+  GNUNET_free (xhdr);
+  ret = json_loadb ((char *) cstr,
+                    clen,
+                    JSON_DECODE_ANY,
+                    &json_error);
+  if (NULL == ret)
+  {
+    GNUNET_break_op (0);
+    GNUNET_free (cstr);
+    return NULL;
+  }
+  GNUNET_free (cstr);
+  return ret;
+}
diff --git a/src/util/test_crypto.c b/src/util/test_crypto.c
index ce4181ff..b1c3c8e8 100644
--- a/src/util/test_crypto.c
+++ b/src/util/test_crypto.c
@@ -150,12 +150,12 @@ test_planchets_rsa (uint8_t age)
   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
                               &ps,
                               sizeof (ps));
-
+  GNUNET_log_skip (1, GNUNET_YES);
   GNUNET_assert (GNUNET_SYSERR ==
                  TALER_denom_priv_create (&dk_priv,
                                           &dk_pub,
                                           TALER_DENOMINATION_INVALID));
-
+  GNUNET_log_skip (1, GNUNET_YES);
   GNUNET_assert (GNUNET_SYSERR ==
                  TALER_denom_priv_create (&dk_priv,
                                           &dk_pub,
@@ -481,12 +481,51 @@ test_contracts (void)
 }
 
 
+static int
+test_attributes (void)
+{
+  struct TALER_AttributeEncryptionKeyP key;
+  void *eattr;
+  size_t eattr_size;
+  json_t *c;
+
+  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
+                              &key,
+                              sizeof (key));
+  c = json_pack ("{s:s}", "test", "value");
+  GNUNET_assert (NULL != c);
+  TALER_CRYPTO_kyc_attributes_encrypt (&key,
+                                       c,
+                                       &eattr,
+                                       &eattr_size);
+  json_decref (c);
+  c = TALER_CRYPTO_kyc_attributes_decrypt (&key,
+                                           eattr,
+                                           eattr_size);
+  GNUNET_free (eattr);
+  if (NULL == c)
+  {
+    GNUNET_break (0);
+    return 1;
+  }
+  GNUNET_assert (0 ==
+                 strcmp ("value",
+                         json_string_value (json_object_get (c,
+                                                             "test"))));
+  json_decref (c);
+  return 0;
+}
+
+
 int
 main (int argc,
       const char *const argv[])
 {
   (void) argc;
   (void) argv;
+  GNUNET_log_setup ("test-crypto",
+                    "WARNING",
+                    NULL);
   if (0 != test_high_level ())
     return 1;
   if (0 != test_planchets (0))
@@ -499,6 +538,8 @@ main (int argc,
     return 5;
   if (0 != test_contracts ())
     return 6;
+  if (0 != test_attributes ())
+    return 7;
   return 0;
 }
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]