summaryrefslogtreecommitdiff
path: root/src/util/crypto_contract.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto_contract.c')
-rw-r--r--src/util/crypto_contract.c239
1 files changed, 180 insertions, 59 deletions
diff --git a/src/util/crypto_contract.c b/src/util/crypto_contract.c
index fe6b1e6af..bec34c983 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);
+ GNUNET_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;
@@ -271,21 +274,21 @@ TALER_CRYPTO_contract_encrypt_for_merge (
hdr->header.ctype = htonl (TALER_EXCHANGE_CONTRACT_PAYMENT_OFFER);
hdr->header.clen = htonl ((uint32_t) clen);
hdr->merge_priv = *merge_priv;
- memcpy (&hdr[1],
- xbuf,
- cbuf_size);
+ GNUNET_memcpy (&hdr[1],
+ xbuf,
+ cbuf_size);
GNUNET_free (xbuf);
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);
@@ -419,30 +423,30 @@ TALER_CRYPTO_contract_encrypt_for_deposit (
hdr = GNUNET_malloc (sizeof (*hdr) + cbuf_size);
hdr->ctype = htonl (TALER_EXCHANGE_CONTRACT_PAYMENT_REQUEST);
hdr->clen = htonl ((uint32_t) clen);
- memcpy (&hdr[1],
- xbuf,
- cbuf_size);
+ GNUNET_memcpy (&hdr[1],
+ xbuf,
+ cbuf_size);
GNUNET_free (xbuf);
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));
- memcpy (*econtract,
- purse_pub,
- sizeof (*purse_pub));
- memcpy (sizeof (*purse_pub) + *econtract,
- xecontract,
- xecontract_size);
+ GNUNET_memcpy (*econtract,
+ purse_pub,
+ sizeof (*purse_pub));
+ GNUNET_memcpy (sizeof (*purse_pub) + *econtract,
+ xecontract,
+ xecontract_size);
*econtract_size = xecontract_size + sizeof (*purse_pub);
GNUNET_free (xecontract);
}
@@ -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);
+ GNUNET_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;
+ }
+ GNUNET_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;
+}