summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authort3sserakt <t3ss@posteo.de>2022-02-03 09:46:58 +0100
committert3sserakt <t3ss@posteo.de>2022-02-03 09:47:55 +0100
commit16c9959d9b395b179446ee4a2cb70f3563c4fb20 (patch)
treecc5a848e4eb105dd2a649b3c96c8ef455322cc4e /src
parentb3f73eba9b7e5456464da6e9b44386b97e2748e3 (diff)
parent650d46465cb97229c6fc8f171b082fc3cb2003aa (diff)
Merge branch 'master' of ssh://git.gnunet.org/gnunet
Diffstat (limited to 'src')
-rw-r--r--src/gnsrecord/Makefile.am9
-rw-r--r--src/gnsrecord/gnsrecord_crypto.c535
-rw-r--r--src/gnsrecord/gnsrecord_crypto.h87
-rw-r--r--src/gnsrecord/gnsrecord_misc.c19
-rw-r--r--src/gnsrecord/gnsrecord_serialization.c56
-rw-r--r--src/gnsrecord/gnunet-gnsrecord-tvg.c223
-rw-r--r--src/gnsrecord/test_gnsrecord_crypto.c12
-rw-r--r--src/gnsrecord/test_gnsrecord_testvectors.c128
-rw-r--r--src/identity/identity_api.c75
-rw-r--r--src/include/gnunet_gnsrecord_lib.h76
-rw-r--r--src/include/gnunet_identity_service.h59
-rw-r--r--src/namestore/gnunet-service-namestore.c10
-rw-r--r--src/revocation/gnunet-revocation-tvg.c58
-rw-r--r--src/revocation/revocation.h8
-rw-r--r--src/revocation/revocation_api.c53
-rw-r--r--src/util/.gitignore3
-rw-r--r--src/util/gnunet-crypto-tvg.c401
-rw-r--r--src/zonemaster/gnunet-service-zonemaster-monitor.c22
-rw-r--r--src/zonemaster/gnunet-service-zonemaster.c10
19 files changed, 1428 insertions, 416 deletions
diff --git a/src/gnsrecord/Makefile.am b/src/gnsrecord/Makefile.am
index 42ac4ede4..4308d9c1a 100644
--- a/src/gnsrecord/Makefile.am
+++ b/src/gnsrecord/Makefile.am
@@ -20,6 +20,7 @@ check_PROGRAMS = \
test_gnsrecord_crypto \
test_gnsrecord_serialization \
test_gnsrecord_block_expiration \
+ test_gnsrecord_testvectors \
perf_gnsrecord_crypto
if ENABLE_TEST_RUN
@@ -85,6 +86,14 @@ libgnunet_plugin_gnsrecord_dns_la_LDFLAGS = \
EXTRA_DIST = \
$(check_SCRIPTS)
+test_gnsrecord_testvectors_SOURCES = \
+ test_gnsrecord_testvectors.c
+test_gnsrecord_testvectors_LDADD = \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/identity/libgnunetidentity.la \
+ libgnunetgnsrecord.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
test_gnsrecord_serialization_SOURCES = \
test_gnsrecord_serialization.c
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c
index fe7db88b9..890ddb011 100644
--- a/src/gnsrecord/gnsrecord_crypto.c
+++ b/src/gnsrecord/gnsrecord_crypto.c
@@ -25,15 +25,7 @@
* @author Matthias Wachs
* @author Christian Grothoff
*/
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_constants.h"
-#include "gnunet_signatures.h"
-#include "gnunet_arm_service.h"
-#include "gnunet_gnsrecord_lib.h"
-#include "gnunet_dnsparser_lib.h"
-#include "gnunet_tun_lib.h"
-
+#include "gnsrecord_crypto.h"
#define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
@@ -103,8 +95,8 @@ eddsa_symmetric_decrypt (
if (ctlen < 0)
return GNUNET_SYSERR;
if (0 != crypto_secretbox_open_detached (result,
- block, // Ciphertext
- ((unsigned char*)block) + ctlen, // TAG
+ ((unsigned char*) block) + crypto_secretbox_MACBYTES, // Ciphertext
+ block, // Tag
ctlen,
nonce, key))
{
@@ -124,27 +116,19 @@ eddsa_symmetric_encrypt (
{
if (size > crypto_secretbox_MESSAGEBYTES_MAX)
return GNUNET_SYSERR;
- crypto_secretbox_detached (result, // Ciphertext
- result + size, // TAG
+ crypto_secretbox_detached (result + crypto_secretbox_MACBYTES, // Ciphertext
+ result, // TAG
block, size, nonce, key);
return GNUNET_OK;
}
-/**
- * Derive session key and iv from label and public key.
- *
- * @param iv initialization vector to initialize
- * @param skey session key to initialize
- * @param label label to use for KDF
- * @param pub public key to use for KDF
- */
-static void
-derive_block_aes_key (unsigned char *ctr,
- unsigned char *key,
- const char *label,
- uint64_t exp,
- const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
+void
+GNR_derive_block_aes_key (unsigned char *ctr,
+ unsigned char *key,
+ const char *label,
+ uint64_t exp,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
{
static const char ctx_key[] = "gns-aes-ctx-key";
static const char ctx_iv[] = "gns-aes-ctx-iv";
@@ -168,23 +152,15 @@ derive_block_aes_key (unsigned char *ctr,
}
-/**
- * Derive session key and iv from label and public key.
- *
- * @param nonce initialization vector to initialize
- * @param skey session key to initialize
- * @param label label to use for KDF
- * @param pub public key to use for KDF
- */
-static void
-derive_block_xsalsa_key (unsigned char *nonce,
- unsigned char *key,
- const char *label,
- uint64_t exp,
- const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
+void
+GNR_derive_block_xsalsa_key (unsigned char *nonce,
+ unsigned char *key,
+ const char *label,
+ uint64_t exp,
+ const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
{
- static const char ctx_key[] = "gns-aes-ctx-key";
- static const char ctx_iv[] = "gns-aes-ctx-iv";
+ static const char ctx_key[] = "gns-xsalsa-ctx-key";
+ static const char ctx_iv[] = "gns-xsalsa-ctx-iv";
GNUNET_CRYPTO_kdf (key, crypto_secretbox_KEYBYTES,
ctx_key, strlen (ctx_key),
@@ -204,6 +180,20 @@ derive_block_xsalsa_key (unsigned char *nonce,
}
+static ssize_t
+block_get_size_ecdsa (const struct GNUNET_GNSRECORD_Data *rd,
+ unsigned int rd_count)
+{
+ ssize_t len;
+
+ len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
+ if (len < 0)
+ return -1;
+ len += sizeof(struct GNUNET_GNSRECORD_Block);
+ return len;
+}
+
+
/**
* Sign name and records
*
@@ -213,20 +203,22 @@ derive_block_xsalsa_key (unsigned char *nonce,
* @param label the name for the records
* @param rd record data
* @param rd_count number of records
- * @return NULL on error (block too large)
+ * @param block the block result. Must be allocated sufficiently.
+ * @return GNUNET_SYSERR on error (otherwise GNUNET_OK)
*/
-static struct GNUNET_GNSRECORD_Block *
+static enum GNUNET_GenericReturnValue
block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey,
struct GNUNET_TIME_Absolute expire,
const char *label,
const struct GNUNET_GNSRECORD_Data *rd,
- unsigned int rd_count)
+ unsigned int rd_count,
+ struct GNUNET_GNSRECORD_Block **block)
{
ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
rd);
- struct GNUNET_GNSRECORD_Block *block;
struct GNUNET_GNSRECORD_EcdsaBlock *ecblock;
+ struct GNRBlockPS *gnr_block;
struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey;
unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
@@ -237,12 +229,12 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
if (payload_len < 0)
{
GNUNET_break (0);
- return NULL;
+ return GNUNET_SYSERR;
}
if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
{
GNUNET_break (0);
- return NULL;
+ return GNUNET_SYSERR;
}
/* convert relative to absolute times */
now = GNUNET_TIME_absolute_get ();
@@ -260,62 +252,70 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
}
}
/* serialize */
+ *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
+ (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
rd_count_nbo = htonl (rd_count);
{
- char payload[sizeof(uint32_t) + payload_len];
+ char payload[payload_len];
- GNUNET_memcpy (payload,
- &rd_count_nbo,
- sizeof(uint32_t));
GNUNET_assert (payload_len ==
GNUNET_GNSRECORD_records_serialize (rd_count,
rdc,
payload_len,
- &payload[sizeof(uint32_t)
- ]));
- block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block)
- + sizeof(uint32_t)
- + payload_len);
- ecblock = &block->ecdsa_block;
- block->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
- ecblock->purpose.size = htonl (sizeof(uint32_t)
- + payload_len
- + sizeof(struct
- GNUNET_CRYPTO_EccSignaturePurpose)
- + sizeof(struct GNUNET_TIME_AbsoluteNBO));
- ecblock->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
- ecblock->expiration_time = GNUNET_TIME_absolute_hton (expire);
+ payload));
+ gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
+ ecblock = &(*block)->ecdsa_block;
+ (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
+ gnr_block->purpose.size = htonl (sizeof(struct GNRBlockPS) + payload_len);
+ gnr_block->purpose.purpose =
+ htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
+ gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire);
+ ecblock->expiration_time = gnr_block->expiration_time;
/* encrypt and sign */
dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key,
label,
"gns");
GNUNET_CRYPTO_ecdsa_key_get_public (dkey,
&ecblock->derived_key);
- derive_block_aes_key (ctr,
- skey,
- label,
- ecblock->expiration_time.abs_value_us__,
- pkey);
- GNUNET_break (payload_len + sizeof(uint32_t) ==
+ GNR_derive_block_aes_key (ctr,
+ skey,
+ label,
+ ecblock->expiration_time.abs_value_us__,
+ pkey);
+ GNUNET_break (payload_len ==
ecdsa_symmetric_encrypt (payload,
- payload_len
- + sizeof(uint32_t),
+ payload_len,
skey,
ctr,
&ecblock[1]));
+ GNUNET_memcpy (&gnr_block[1], &ecblock[1], payload_len);
}
if (GNUNET_OK !=
GNUNET_CRYPTO_ecdsa_sign_ (dkey,
- &ecblock->purpose,
+ &gnr_block->purpose,
&ecblock->signature))
{
GNUNET_break (0);
+ GNUNET_free (*block);
GNUNET_free (dkey);
- GNUNET_free (block);
- return NULL;
+ return GNUNET_SYSERR;
}
GNUNET_free (dkey);
- return block;
+ return GNUNET_OK;
+}
+
+static ssize_t
+block_get_size_eddsa (const struct GNUNET_GNSRECORD_Data *rd,
+ unsigned int rd_count)
+{
+ ssize_t len;
+
+ len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
+ if (len < 0)
+ return -1;
+ len += sizeof(struct GNUNET_GNSRECORD_Block);
+ len += crypto_secretbox_MACBYTES;
+ return len;
}
@@ -328,20 +328,22 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
* @param label the name for the records
* @param rd record data
* @param rd_count number of records
- * @return NULL on error (block too large)
+ * @param block where to store the block. Must be allocated sufficiently.
+ * @return GNUNET_SYSERR on error (otherwise GNUNET_OK)
*/
-static struct GNUNET_GNSRECORD_Block *
+enum GNUNET_GenericReturnValue
block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
const struct GNUNET_CRYPTO_EddsaPublicKey *pkey,
struct GNUNET_TIME_Absolute expire,
const char *label,
const struct GNUNET_GNSRECORD_Data *rd,
- unsigned int rd_count)
+ unsigned int rd_count,
+ struct GNUNET_GNSRECORD_Block **block)
{
ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
rd);
- struct GNUNET_GNSRECORD_Block *block;
struct GNUNET_GNSRECORD_EddsaBlock *edblock;
+ struct GNRBlockPS *gnr_block;
struct GNUNET_CRYPTO_EddsaPrivateScalar dkey;
unsigned char nonce[crypto_secretbox_NONCEBYTES];
unsigned char skey[crypto_secretbox_KEYBYTES];
@@ -352,12 +354,12 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
if (payload_len < 0)
{
GNUNET_break (0);
- return NULL;
+ return GNUNET_SYSERR;
}
if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
{
GNUNET_break (0);
- return NULL;
+ return GNUNET_SYSERR;
}
/* convert relative to absolute times */
now = GNUNET_TIME_absolute_get ();
@@ -375,33 +377,32 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
}
}
/* serialize */
+ *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block)
+ + payload_len + crypto_secretbox_MACBYTES);
+ (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block)
+ + payload_len + crypto_secretbox_MACBYTES);
rd_count_nbo = htonl (rd_count);
{
- char payload[sizeof(uint32_t) + payload_len];
+ char payload[payload_len];
- GNUNET_memcpy (payload,
- &rd_count_nbo,
- sizeof(uint32_t));
GNUNET_assert (payload_len ==
GNUNET_GNSRECORD_records_serialize (rd_count,
rdc,
payload_len,
- &payload[sizeof(uint32_t)
- ]));
- block = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Block)
- + sizeof(uint32_t)
- + payload_len
- + crypto_secretbox_MACBYTES);
- edblock = &block->eddsa_block;
- block->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
- edblock->purpose.size = htonl (sizeof(uint32_t)
- + payload_len
- + sizeof(struct
- GNUNET_CRYPTO_EccSignaturePurpose)
- + sizeof(struct GNUNET_TIME_AbsoluteNBO)
- + crypto_secretbox_MACBYTES);
- edblock->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
- edblock->expiration_time = GNUNET_TIME_absolute_hton (expire);
+ payload));
+ gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS)
+ + payload_len
+ + crypto_secretbox_MACBYTES);
+ edblock = &(*block)->eddsa_block;
+ (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
+ gnr_block->purpose.size =
+ htonl (sizeof(struct GNRBlockPS)
+ + payload_len
+ + crypto_secretbox_MACBYTES);
+ gnr_block->purpose.purpose =
+ htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
+ gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire);
+ edblock->expiration_time = gnr_block->expiration_time;
/* encrypt and sign */
GNUNET_CRYPTO_eddsa_private_key_derive (key,
label,
@@ -409,45 +410,63 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
&dkey);
GNUNET_CRYPTO_eddsa_key_get_public_from_scalar (&dkey,
&edblock->derived_key);
- derive_block_xsalsa_key (nonce,
- skey,
- label,
- edblock->expiration_time.abs_value_us__,
- pkey);
+ GNR_derive_block_xsalsa_key (nonce,
+ skey,
+ label,
+ edblock->expiration_time.abs_value_us__,
+ pkey);
GNUNET_break (GNUNET_OK ==
eddsa_symmetric_encrypt (payload,
- payload_len
- + sizeof(uint32_t),
+ payload_len,
skey,
nonce,
&edblock[1]));
+ GNUNET_memcpy (&gnr_block[1], &edblock[1],
+ payload_len + crypto_secretbox_MACBYTES);
+
+ GNUNET_CRYPTO_eddsa_sign_with_scalar (&dkey,
+ &gnr_block->purpose,
+ &edblock->signature);
}
- GNUNET_CRYPTO_eddsa_sign_with_scalar (&dkey,
- &edblock->purpose,
- &edblock->signature);
- return block;
+ return GNUNET_OK;
}
+ssize_t
+GNUNET_GNSRECORD_block_calculate_size (const struct
+ GNUNET_IDENTITY_PrivateKey *key,
+ const struct GNUNET_GNSRECORD_Data *rd,
+ unsigned int rd_count)
+{
+ struct GNUNET_IDENTITY_PublicKey pkey;
+ ssize_t res;
-/**
- * Sign name and records
- *
- * @param key the private key
- * @param expire block expiration
- * @param label the name for the records
- * @param rd record data
- * @param rd_count number of records
- * @return NULL on error (block too large)
- */
-struct GNUNET_GNSRECORD_Block *
+ GNUNET_IDENTITY_key_get_public (key,
+ &pkey);
+ switch (ntohl (key->type))
+ {
+ case GNUNET_GNSRECORD_TYPE_PKEY:
+ res = block_get_size_ecdsa (rd, rd_count);
+ break;
+ case GNUNET_GNSRECORD_TYPE_EDKEY:
+ res = block_get_size_eddsa (rd, rd_count);
+ break;
+ default:
+ GNUNET_assert (0);
+ }
+ return -1;
+
+}
+
+enum GNUNET_GenericReturnValue
GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
struct GNUNET_TIME_Absolute expire,
const char *label,
const struct GNUNET_GNSRECORD_Data *rd,
- unsigned int rd_count)
+ unsigned int rd_count,
+ struct GNUNET_GNSRECORD_Block **result)
{
struct GNUNET_IDENTITY_PublicKey pkey;
- struct GNUNET_GNSRECORD_Block *res = NULL;
+ enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
char *norm_label;
GNUNET_IDENTITY_key_get_public (key,
@@ -456,24 +475,26 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
switch (ntohl (key->type))
{
- case GNUNET_GNSRECORD_TYPE_PKEY:
- res = block_create_ecdsa (&key->ecdsa_key,
- &pkey.ecdsa_key,
- expire,
- norm_label,
- rd,
- rd_count);
- break;
- case GNUNET_GNSRECORD_TYPE_EDKEY:
- res = block_create_eddsa (&key->eddsa_key,
- &pkey.eddsa_key,
- expire,
- norm_label,
- rd,
- rd_count);
- break;
- default:
- GNUNET_assert (0);
+ case GNUNET_GNSRECORD_TYPE_PKEY:
+ res = block_create_ecdsa (&key->ecdsa_key,
+ &pkey.ecdsa_key,
+ expire,
+ norm_label,
+ rd,
+ rd_count,
+ result);
+ break;
+ case GNUNET_GNSRECORD_TYPE_EDKEY:
+ res = block_create_eddsa (&key->eddsa_key,
+ &pkey.eddsa_key,
+ expire,
+ norm_label,
+ rd,
+ rd_count,
+ result);
+ break;
+ default:
+ GNUNET_assert (0);
}
GNUNET_free (norm_label);
return res;
@@ -497,28 +518,17 @@ struct KeyCacheLine
};
-/**
- * Sign name and records, cache derived public key (also keeps the
- * private key in static memory, so do not use this function if
- * keeping the private key in the process'es RAM is a major issue).
- *
- * @param key the private key
- * @param expire block expiration
- * @param label the name for the records
- * @param rd record data
- * @param rd_count number of records
- * @return NULL on error (block too large)
- */
-struct GNUNET_GNSRECORD_Block *
+enum GNUNET_GenericReturnValue
GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
struct GNUNET_TIME_Absolute expire,
const char *label,
const struct GNUNET_GNSRECORD_Data *rd,
- unsigned int rd_count)
+ unsigned int rd_count,
+ struct GNUNET_GNSRECORD_Block **result)
{
const struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
struct GNUNET_CRYPTO_EddsaPublicKey edpubkey;
- struct GNUNET_GNSRECORD_Block *res = NULL;
+ enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
char *norm_label;
norm_label = GNUNET_GNSRECORD_string_normalize (label);
@@ -546,7 +556,8 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
expire,
norm_label,
rd,
- rd_count);
+ rd_count,
+ result);
}
else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type))
{
@@ -557,7 +568,8 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
expire,
norm_label,
rd,
- rd_count);
+ rd_count,
+ result);
}
GNUNET_free (norm_label);
return res;
@@ -574,64 +586,76 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
enum GNUNET_GenericReturnValue
GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block)
{
+ struct GNRBlockPS *purp;
+ size_t payload_len = ntohl (block->size)
+ - sizeof (struct GNUNET_GNSRECORD_Block);
+ enum GNUNET_GenericReturnValue res = GNUNET_NO;
+ purp = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
+ purp->purpose.size = htonl (sizeof (struct GNRBlockPS) + payload_len);
+ purp->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
+ GNUNET_memcpy (&purp[1], &block[1], payload_len);
+
switch (ntohl (block->type))
{
- case GNUNET_GNSRECORD_TYPE_PKEY:
- return GNUNET_CRYPTO_ecdsa_verify_ (
- GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
- &block->ecdsa_block.purpose,
- &block->ecdsa_block.signature,
- &block->ecdsa_block.derived_key);
- case GNUNET_GNSRECORD_TYPE_EDKEY:
- return GNUNET_CRYPTO_eddsa_verify_ (
- GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
- &block->eddsa_block.purpose,
- &block->eddsa_block.signature,
- &block->eddsa_block.derived_key);
- default:
- return GNUNET_NO;
+ case GNUNET_GNSRECORD_TYPE_PKEY:
+ purp->expiration_time = block->ecdsa_block.expiration_time;
+ res = GNUNET_CRYPTO_ecdsa_verify_ (
+ GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
+ &purp->purpose,
+ &block->ecdsa_block.signature,
+ &block->ecdsa_block.derived_key);
+ break;
+ case GNUNET_GNSRECORD_TYPE_EDKEY:
+ purp->expiration_time = block->eddsa_block.expiration_time;
+ res = GNUNET_CRYPTO_eddsa_verify_ (
+ GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
+ &purp->purpose,
+ &block->eddsa_block.signature,
+ &block->eddsa_block.derived_key);
+ break;
+ default:
+ res = GNUNET_NO;
}
+ GNUNET_free (purp);
+ return res;
}
enum GNUNET_GenericReturnValue
-block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block,
+block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_Block *block,
const struct
GNUNET_CRYPTO_EcdsaPublicKey *zone_key,
const char *label,
GNUNET_GNSRECORD_RecordCallback proc,
void *proc_cls)
{
- size_t payload_len = ntohl (block->purpose.size)
- - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
- - sizeof(struct GNUNET_TIME_AbsoluteNBO);
+ size_t payload_len = ntohl (block->size) - sizeof (struct
+ GNUNET_GNSRECORD_Block);
unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
unsigned char key[GNUNET_CRYPTO_AES_KEY_LENGTH];
- if (ntohl (block->purpose.size) <
+ if (ntohl (block->size) <
sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
+ sizeof(struct GNUNET_TIME_AbsoluteNBO))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- derive_block_aes_key (ctr,
- key,
- label,
- block->expiration_time.abs_value_us__,
- zone_key);
+ GNR_derive_block_aes_key (ctr,
+ key,
+ label,
+ block->ecdsa_block.expiration_time.abs_value_us__,
+ zone_key);
{
char payload[payload_len];
- uint32_t rd_count;
+ unsigned int rd_count;
GNUNET_break (payload_len ==
ecdsa_symmetric_decrypt (&block[1], payload_len,
key, ctr,
payload));
- GNUNET_memcpy (&rd_count,
- payload,
- sizeof(uint32_t));
- rd_count = ntohl (rd_count);
+ rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
+ payload);
if (rd_count > 2048)
{
/* limit to sane value */
@@ -644,8 +668,8 @@ block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block,
struct GNUNET_TIME_Absolute now;
if (GNUNET_OK !=
- GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof(uint32_t),
- &payload[sizeof(uint32_t)],
+ GNUNET_GNSRECORD_records_deserialize (payload_len,
+ payload,
rd_count,
rd))
{
@@ -723,43 +747,42 @@ block_decrypt_ecdsa (const struct GNUNET_GNSRECORD_EcdsaBlock *block,
enum GNUNET_GenericReturnValue
-block_decrypt_eddsa (const struct GNUNET_GNSRECORD_EddsaBlock *block,
+block_decrypt_eddsa (const struct GNUNET_GNSRECORD_Block *block,
const struct
GNUNET_CRYPTO_EddsaPublicKey *zone_key,
const char *label,
GNUNET_GNSRECORD_RecordCallback proc,
void *proc_cls)
{
- size_t payload_len = ntohl (block->purpose.size)
- - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
- - sizeof(struct GNUNET_TIME_AbsoluteNBO);
+ const struct GNUNET_GNSRECORD_EddsaBlock *edblock = &block->eddsa_block;
+ size_t payload_len = ntohl (block->size) - sizeof (struct
+ GNUNET_GNSRECORD_Block);
unsigned char nonce[crypto_secretbox_NONCEBYTES];
unsigned char key[crypto_secretbox_KEYBYTES];
- if (ntohl (block->purpose.size) <
+ if (ntohl (block->size) <
sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
+ sizeof(struct GNUNET_TIME_AbsoluteNBO))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- derive_block_xsalsa_key (nonce,
- key,
- label,
- block->expiration_time.abs_value_us__,
- zone_key);
+ GNR_derive_block_xsalsa_key (nonce,
+ key,
+ label,
+ block->eddsa_block.expiration_time.abs_value_us__,
+ zone_key);
{
char payload[payload_len];
- uint32_t rd_count;
+ unsigned int rd_count;
GNUNET_break (GNUNET_OK ==
eddsa_symmetric_decrypt (&block[1], payload_len,
key, nonce,
payload));
- GNUNET_memcpy (&rd_count,
- payload,
- sizeof(uint32_t));
- rd_count = ntohl (rd_count);
+ payload_len -= crypto_secretbox_MACBYTES;
+ rd_count = GNUNET_GNSRECORD_records_deserialize_get_size (payload_len,
+ payload);
if (rd_count > 2048)
{
/* limit to sane value */
@@ -772,8 +795,8 @@ block_decrypt_eddsa (const struct GNUNET_GNSRECORD_EddsaBlock *block,
struct GNUNET_TIME_Absolute now;
if (GNUNET_OK !=
- GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof(uint32_t),
- &payload[sizeof(uint32_t)],
+ GNUNET_GNSRECORD_records_deserialize (payload_len,
+ payload,
rd_count,
rd))
{
@@ -875,16 +898,18 @@ GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block,
norm_label = GNUNET_GNSRECORD_string_normalize (label);
switch (ntohl (zone_key->type))
{
- case GNUNET_IDENTITY_TYPE_ECDSA:
- res = block_decrypt_ecdsa (&block->ecdsa_block,
- &zone_key->ecdsa_key, norm_label, proc, proc_cls);
- break;
- case GNUNET_IDENTITY_TYPE_EDDSA:
- res = block_decrypt_eddsa (&block->eddsa_block,
- &zone_key->eddsa_key, norm_label, proc, proc_cls);
- break;
- default:
- return GNUNET_SYSERR;
+ case GNUNET_IDENTITY_TYPE_ECDSA:
+ res = block_decrypt_ecdsa (block,
+ &zone_key->ecdsa_key, norm_label, proc,
+ proc_cls);
+ break;
+ case GNUNET_IDENTITY_TYPE_EDDSA:
+ res = block_decrypt_eddsa (block,
+ &zone_key->eddsa_key, norm_label, proc,
+ proc_cls);
+ break;
+ default:
+ return GNUNET_SYSERR;
}
GNUNET_free (norm_label);
return res;
@@ -910,17 +935,17 @@ GNUNET_GNSRECORD_query_from_private_key (const struct
norm_label = GNUNET_GNSRECORD_string_normalize (label);
switch (ntohl (zone->type))
{
- case GNUNET_GNSRECORD_TYPE_PKEY:
- case GNUNET_GNSRECORD_TYPE_EDKEY:
-
- GNUNET_IDENTITY_key_get_public (zone,
- &pub);
- GNUNET_GNSRECORD_query_from_public_key (&pub,
- norm_label,
- query);
- break;
- default:
- GNUNET_assert (0);
+ case GNUNET_GNSRECORD_TYPE_PKEY:
+ case GNUNET_GNSRECORD_TYPE_EDKEY:
+
+ GNUNET_IDENTITY_key_get_public (zone,
+ &pub);
+ GNUNET_GNSRECORD_query_from_public_key (&pub,
+ norm_label,
+ query);
+ break;
+ default:
+ GNUNET_assert (0);
}
GNUNET_free (norm_label);
}
@@ -947,28 +972,28 @@ GNUNET_GNSRECORD_query_from_public_key (const struct
switch (ntohl (pub->type))
{
- case GNUNET_GNSRECORD_TYPE_PKEY:
- pd.type = pub->type;
- GNUNET_CRYPTO_ecdsa_public_key_derive (&pub->ecdsa_key,
- norm_label,
- "gns",
- &pd.ecdsa_key);
- GNUNET_CRYPTO_hash (&pd.ecdsa_key,
- sizeof (pd.ecdsa_key),
- query);
- break;
- case GNUNET_GNSRECORD_TYPE_EDKEY:
- pd.type = pub->type;
- GNUNET_CRYPTO_eddsa_public_key_derive (&pub->eddsa_key,
- norm_label,
- "gns",
- &(pd.eddsa_key));
- GNUNET_CRYPTO_hash (&pd.eddsa_key,
- sizeof (pd.eddsa_key),
- query);
- break;
- default:
- GNUNET_assert (0);
+ case GNUNET_GNSRECORD_TYPE_PKEY:
+ pd.type = pub->type;
+ GNUNET_CRYPTO_ecdsa_public_key_derive (&pub->ecdsa_key,
+ norm_label,
+ "gns",
+ &pd.ecdsa_key);
+ GNUNET_CRYPTO_hash (&pd.ecdsa_key,
+ sizeof (pd.ecdsa_key),
+ query);
+ break;
+ case GNUNET_GNSRECORD_TYPE_EDKEY:
+ pd.type = pub->type;
+ GNUNET_CRYPTO_eddsa_public_key_derive (&pub->eddsa_key,
+ norm_label,
+ "gns",
+ &(pd.eddsa_key));
+ GNUNET_CRYPTO_hash (&pd.eddsa_key,
+ sizeof (pd.eddsa_key),
+ query);
+ break;
+ default:
+ GNUNET_assert (0);
}
GNUNET_free (norm_label);
}
diff --git a/src/gnsrecord/gnsrecord_crypto.h b/src/gnsrecord/gnsrecord_crypto.h
new file mode 100644
index 000000000..79a7e6fb9
--- /dev/null
+++ b/src/gnsrecord/gnsrecord_crypto.h
@@ -0,0 +1,87 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2009-2013, 2018 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file gnsrecord/gnsrecord_crypto.h
+ * @brief API for GNS record-related crypto
+ * @author Martin Schanzenbach
+ * @author Matthias Wachs
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_constants.h"
+#include "gnunet_signatures.h"
+#include "gnunet_arm_service.h"
+#include "gnunet_gnsrecord_lib.h"
+#include "gnunet_dnsparser_lib.h"
+#include "gnunet_tun_lib.h"
+
+/**
+ * Information we have in an encrypted block with record data (i.e. in the DHT).
+ */
+struct GNRBlockPS
+{
+ /**
+ * Number of bytes signed; also specifies the number of bytes
+ * of encrypted data that follow.
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * Expiration time of the block.
+ */
+ struct GNUNET_TIME_AbsoluteNBO expiration_time;
+
+ /* followed by encrypted data */
+};
+
+
+/**
+ * Derive session key and iv from label and public key.
+ *
+ * @param iv initialization vector to initialize
+ * @param skey session key to initialize
+ * @param label label to use for KDF
+ * @param pub public key to use for KDF
+ */
+void
+GNR_derive_block_aes_key (unsigned char *ctr,
+ unsigned char *key,
+ const char *label,
+ uint64_t exp,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *pub);
+
+
+/**
+ * Derive session key and iv from label and public key.
+ *
+ * @param nonce initialization vector to initialize
+ * @param skey session key to initialize
+ * @param label label to use for KDF
+ * @param pub public key to use for KDF
+ */
+void
+GNR_derive_block_xsalsa_key (unsigned char *nonce,
+ unsigned char *key,
+ const char *label,
+ uint64_t exp,
+ const struct GNUNET_CRYPTO_EddsaPublicKey *pub);
+
diff --git a/src/gnsrecord/gnsrecord_misc.c b/src/gnsrecord/gnsrecord_misc.c
index c6f07ccd0..61604c730 100644
--- a/src/gnsrecord/gnsrecord_misc.c
+++ b/src/gnsrecord/gnsrecord_misc.c
@@ -334,24 +334,7 @@ GNUNET_GNSRECORD_is_zonekey_type (uint32_t type)
size_t
GNUNET_GNSRECORD_block_get_size (const struct GNUNET_GNSRECORD_Block *block)
{
- switch (ntohl (block->type))
- {
- case GNUNET_GNSRECORD_TYPE_PKEY:
- return sizeof (uint32_t) /* zone type */
- + sizeof (block->ecdsa_block) /* EcdsaBlock */
- + ntohl (block->ecdsa_block.purpose.size) /* Length of signed data */
- - sizeof (block->ecdsa_block.purpose); /* Purpose already in EcdsaBlock */
- break;
- case GNUNET_GNSRECORD_TYPE_EDKEY:
- return sizeof (uint32_t) /* zone type */
- + sizeof (block->eddsa_block) /* EddsaBlock */
- + ntohl (block->eddsa_block.purpose.size) /* Length of signed data */
- - sizeof (block->ecdsa_block.purpose); /* Purpose already in EcdsaBlock */
-
- default:
- return 0;
- }
- return 0;
+ return ntohl (block->size);
}
diff --git a/src/gnsrecord/gnsrecord_serialization.c b/src/gnsrecord/gnsrecord_serialization.c
index cb6957605..eaa3a9ab2 100644
--- a/src/gnsrecord/gnsrecord_serialization.c
+++ b/src/gnsrecord/gnsrecord_serialization.c
@@ -60,17 +60,18 @@ struct NetworkRecord
/**
* Number of bytes in 'data', network byte order.
*/
- uint32_t data_size GNUNET_PACKED;
+ uint16_t data_size GNUNET_PACKED;
/**
- * Type of the GNS/DNS record, network byte order.
+ * Flags for the record, network byte order.
*/
- uint32_t record_type GNUNET_PACKED;
+ uint16_t flags GNUNET_PACKED;
/**
- * Flags for the record, network byte order.
+ * Type of the GNS/DNS record, network byte order.
*/
- uint32_t flags GNUNET_PACKED;
+ uint32_t record_type GNUNET_PACKED;
+
};
GNUNET_NETWORK_STRUCT_END
@@ -169,9 +170,9 @@ GNUNET_GNSRECORD_records_serialize (unsigned int rd_count,
rd[i].flags,
(unsigned long long) rd[i].expiration_time);
rec.expiration_time = GNUNET_htonll (rd[i].expiration_time);
- rec.data_size = htonl ((uint32_t) rd[i].data_size);
+ rec.data_size = htons ((uint16_t) rd[i].data_size);
rec.record_type = htonl (rd[i].record_type);
- rec.flags = htonl (rd[i].flags);
+ rec.flags = htons (rd[i].flags);
if ((off + sizeof(rec) > dest_size) ||
(off + sizeof(rec) < off))
{
@@ -214,13 +215,48 @@ GNUNET_GNSRECORD_records_serialize (unsigned int rd_count,
return dest_size;
}
+unsigned int
+GNUNET_GNSRECORD_records_deserialize_get_size (size_t len,
+ const char *src)
+{
+ struct NetworkRecord rec;
+ struct NetworkRecord rec_zero;
+ size_t off;
+ unsigned int rd_count = 0;
+
+ memset (&rec_zero, 0, sizeof (rec_zero));
+
+ off = 0;
+ for (off = 0; (off + sizeof(rec) <= len) && (off + sizeof(rec) >= off);)
+ {
+ /*
+ * If we have found a byte string of zeroes, we have reached
+ * the padding
+ */
+ if (0 == GNUNET_memcmp (&rec, &rec_zero))
+ break;
+ GNUNET_memcpy (&rec,
+ &src[off],
+ sizeof(rec));
+ off += sizeof(rec);
+ if ((off + ntohs ((uint16_t) rec.data_size) > len) ||
+ (off + ntohs ((uint16_t) rec.data_size) < off))
+ {
+ GNUNET_break_op (0);
+ return 0;
+ }
+ off += ntohs ((uint16_t) rec.data_size);
+ rd_count++;
+ }
+ return rd_count;
+}
/**
* Deserialize the given records to the given destination.
*
* @param len size of the serialized record data
* @param src the serialized record data
- * @param rd_count number of records in the rd array
+ * @param rd_count number of records parsed
* @param dest where to put the data
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
@@ -246,9 +282,9 @@ GNUNET_GNSRECORD_records_deserialize (size_t len,
&src[off],
sizeof(rec));
dest[i].expiration_time = GNUNET_ntohll (rec.expiration_time);
- dest[i].data_size = ntohl ((uint32_t) rec.data_size);
+ dest[i].data_size = ntohs ((uint16_t) rec.data_size);
dest[i].record_type = ntohl (rec.record_type);
- dest[i].flags = ntohl (rec.flags);
+ dest[i].flags = ntohs (rec.flags);
off += sizeof(rec);
if ((off + dest[i].data_size > len) ||
(off + dest[i].data_size < off))
diff --git a/src/gnsrecord/gnunet-gnsrecord-tvg.c b/src/gnsrecord/gnunet-gnsrecord-tvg.c
index 16a360bdc..f9b83e48b 100644
--- a/src/gnsrecord/gnunet-gnsrecord-tvg.c
+++ b/src/gnsrecord/gnunet-gnsrecord-tvg.c
@@ -31,15 +31,43 @@
#include "gnunet_dnsparser_lib.h"
#include "gnunet_testing_lib.h"
#include <inttypes.h>
+#include "gnsrecord_crypto.h"
#define TEST_RECORD_LABEL "test"
#define TEST_RECORD_A "1.2.3.4"
#define TEST_RRCOUNT 2
+static char *d_pkey =
+ "50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98";
+
+static char *d_edkey =
+ "5af7020ee19160328832352bbc6a68a8d71a7cbe1b929969a7c66d415a0d8f65";
+
+int parsehex (char *src, char *dst, size_t dstlen, int invert)
+{
+ char *line = src;
+ char *data = line;
+ int off;
+ int read_byte;
+ int data_len = 0;
+
+ while (sscanf (data, " %02x%n", &read_byte, &off) == 1)
+ {
+ if (invert)
+ dst[dstlen - 1 - data_len++] = read_byte;
+ else
+ dst[data_len++] = read_byte;
+ data += off;
+ }
+ return data_len;
+}
+
+
static void
-print_bytes (void *buf,
- size_t buf_len,
- int fold)
+print_bytes_ (void *buf,
+ size_t buf_len,
+ int fold,
+ int in_be)
{
int i;
@@ -47,11 +75,22 @@ print_bytes (void *buf,
{
if ((0 != i) && (0 != fold) && (i % fold == 0))
printf ("\n");
- printf ("%02x", ((unsigned char*) buf)[i]);
+ if (in_be)
+ printf ("%02x", ((unsigned char*) buf)[buf_len - 1 - i]);
+ else
+ printf ("%02x", ((unsigned char*) buf)[i]);
}
printf ("\n");
}
+static void
+print_bytes (void *buf,
+ size_t buf_len,
+ int fold)
+{
+ print_bytes_ (buf, buf_len, fold, 0);
+}
+
static void
print_record (const struct GNUNET_GNSRECORD_Data *rd)
@@ -84,28 +123,51 @@ static void
run_pkey (void)
{
struct GNUNET_GNSRECORD_Data rd[2];
- struct GNUNET_TIME_Absolute exp_abs = GNUNET_TIME_absolute_get ();
+ struct GNUNET_TIME_Absolute expire;
+ struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
+ struct GNUNET_TIME_Absolute exp1;
+ struct GNUNET_TIME_Absolute exp2;
+ struct GNUNET_TIME_Relative delta1;
+ struct GNUNET_TIME_Relative delta2;
struct GNUNET_GNSRECORD_Block *rrblock;
char *bdata;
struct GNUNET_IDENTITY_PrivateKey id_priv;
struct GNUNET_IDENTITY_PublicKey id_pub;
struct GNUNET_IDENTITY_PrivateKey pkey_data_p;
struct GNUNET_IDENTITY_PublicKey pkey_data;
+ struct GNUNET_HashCode query;
void *data;
size_t data_size;
char *rdata;
size_t rdata_size;
+ uint32_t rd_count_nbo;
char ztld[128];
+ unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
+ unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
+
+ /*
+ * Make two different expiration times
+ */
+ GNUNET_STRINGS_fancy_time_to_absolute ("2048-01-23 10:51:34",
+ &exp1);
+ GNUNET_STRINGS_fancy_time_to_absolute ("3540-05-22 07:55:01",
+ &exp2);
+
id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key);
+ parsehex (d_pkey,
+ (char*) &id_priv.ecdsa_key,
+ sizeof (id_priv.ecdsa_key), 1);
+
GNUNET_IDENTITY_key_get_public (&id_priv,
&id_pub);
fprintf (stdout,
- "Zone private key (d, little-endian, with ztype prepended):\n");
- print_bytes (&id_priv, GNUNET_IDENTITY_key_get_length (&id_pub), 8); // FIXME length for privkey?
+ "Zone private key (d, big-endian):\n");
+ print_bytes_ (&id_priv.ecdsa_key,
+ sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), 8, 1);
fprintf (stdout, "\n");
- fprintf (stdout, "Zone identifier (zid):\n");
+ fprintf (stdout, "Zone identifier (ztype|zkey):\n");
print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8);
GNUNET_STRINGS_data_to_string (&id_pub,
GNUNET_IDENTITY_key_get_length (&id_pub),
@@ -127,20 +189,20 @@ run_pkey (void)
GNUNET_DNSPARSER_TYPE_A, TEST_RECORD_A, &data, &data_size));
rd[0].data = data;
rd[0].data_size = data_size;
- rd[0].expiration_time = exp_abs.abs_value_us;
+ rd[0].expiration_time = exp1.abs_value_us;
rd[0].record_type = GNUNET_DNSPARSER_TYPE_A;
fprintf (stdout, "Record #0\n");
print_record (&rd[0]);
- rd[1].data = &pkey_data;
- rd[1].data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
- rd[1].expiration_time = exp_abs.abs_value_us;
- rd[1].record_type = GNUNET_GNSRECORD_TYPE_PKEY;
+ rd[1].data = "Some nick";
+ rd[1].data_size = sizeof (struct GNUNET_IDENTITY_PublicKey);
+ rd[1].expiration_time = exp2.abs_value_us;
+ rd[1].record_type = GNUNET_GNSRECORD_TYPE_NICK;
rd[1].flags = GNUNET_GNSRECORD_RF_PRIVATE;
fprintf (stdout, "Record #1\n");
print_record (&rd[1]);
- rdata_size = GNUNET_GNSRECORD_records_get_size (2,
+ rdata_size = GNUNET_GNSRECORD_records_get_size (TEST_RRCOUNT,
rd);
rdata = GNUNET_malloc (rdata_size);
GNUNET_GNSRECORD_records_serialize (2,
@@ -150,25 +212,40 @@ run_pkey (void)
fprintf (stdout, "RDATA:\n");
print_bytes (rdata, rdata_size, 8);
fprintf (stdout, "\n");
- rrblock = GNUNET_GNSRECORD_block_create (&id_priv,
- exp_abs,
- TEST_RECORD_LABEL,
- rd,
- TEST_RRCOUNT);
- size_t bdata_size = ntohl (rrblock->ecdsa_block.purpose.size)
- - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
- - sizeof(struct GNUNET_TIME_AbsoluteNBO);
- size_t ecblock_size = ntohl (rrblock->ecdsa_block.purpose.size)
- + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
- + sizeof(struct GNUNET_CRYPTO_EcdsaSignature);
- size_t block_size = ecblock_size + sizeof (uint32_t);
+ expire = GNUNET_GNSRECORD_record_get_expiration_time (TEST_RRCOUNT, rd);
+ GNR_derive_block_aes_key (ctr,
+ skey,
+ TEST_RECORD_LABEL,
+ GNUNET_TIME_absolute_hton (
+ expire).abs_value_us__,
+ &id_pub.ecdsa_key);
+
+ fprintf (stdout, "Encryption NONCE|EXPIRATION|BLOCK COUNTER:\n");
+ print_bytes (ctr, sizeof (ctr), 8);
+ fprintf (stdout, "\n");
+ fprintf (stdout, "Encryption key (K):\n");
+ print_bytes (skey, sizeof (skey), 8);
+ fprintf (stdout, "\n");
+ GNUNET_GNSRECORD_query_from_public_key (&id_pub,
+ TEST_RECORD_LABEL,
+ &query);
+ fprintf (stdout, "Storage key (q):\n");
+ print_bytes (&query, sizeof (query), 8);
+ fprintf (stdout, "\n");
+ GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv,
+ expire,
+ TEST_RECORD_LABEL,
+ rd,
+ TEST_RRCOUNT,
+ &rrblock));
+ size_t bdata_size = ntohl(rrblock->size) - sizeof (struct GNUNET_GNSRECORD_Block);
bdata = (char*) &(&rrblock->ecdsa_block)[1];
fprintf (stdout, "BDATA:\n");
print_bytes (bdata, bdata_size, 8);
fprintf (stdout, "\n");
fprintf (stdout, "RRBLOCK:\n");
- print_bytes (rrblock, block_size, 8);
+ print_bytes (rrblock, ntohl(rrblock->size), 8);
fprintf (stdout, "\n");
GNUNET_free (rdata);
}
@@ -186,28 +263,54 @@ static void
run_edkey (void)
{
struct GNUNET_GNSRECORD_Data rd[2];
- struct GNUNET_TIME_Absolute exp_abs = GNUNET_TIME_absolute_get ();
+ struct GNUNET_TIME_Absolute expire;
+ struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
+ struct GNUNET_TIME_Absolute exp1;
+ struct GNUNET_TIME_Absolute exp2;
+ struct GNUNET_TIME_Relative delta1;
+ struct GNUNET_TIME_Relative delta2;
struct GNUNET_GNSRECORD_Block *rrblock;
char *bdata;
struct GNUNET_IDENTITY_PrivateKey id_priv;
struct GNUNET_IDENTITY_PublicKey id_pub;
struct GNUNET_IDENTITY_PrivateKey pkey_data_p;
struct GNUNET_IDENTITY_PublicKey pkey_data;
+ struct GNUNET_HashCode query;
void *data;
size_t data_size;
char *rdata;
size_t rdata_size;
+ uint32_t rd_count_nbo;
char ztld[128];
+ unsigned char nonce[crypto_secretbox_NONCEBYTES];
+ unsigned char skey[crypto_secretbox_KEYBYTES];
+
+ /*
+ * Make two different expiration times
+ */
+ GNUNET_STRINGS_fancy_time_to_absolute ("%2048-01-23 10:51:34",
+ &exp1);
+ GNUNET_STRINGS_fancy_time_to_absolute ("3540-05-22 07:55:01",
+ &exp2);
+
+ id_priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
+ GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key);
+ GNUNET_IDENTITY_key_get_public (&id_priv,
+ &id_pub);
id_priv.type = htonl (GNUNET_IDENTITY_TYPE_EDDSA);
GNUNET_CRYPTO_eddsa_key_create (&id_priv.eddsa_key);
+ parsehex (d_edkey,
+ (char*) &id_priv.eddsa_key,
+ sizeof (id_priv.eddsa_key), 0);
GNUNET_IDENTITY_key_get_public (&id_priv,
&id_pub);
fprintf (stdout,
- "Zone private key (d, little-endian, with ztype prepended):\n");
- print_bytes (&id_priv, GNUNET_IDENTITY_key_get_length (&id_pub), 8); // FIXME length for privkey?
+ "Zone private key (d):\n");
+ print_bytes (&id_priv.eddsa_key, sizeof (struct
+ GNUNET_CRYPTO_EddsaPrivateKey), 8);
fprintf (stdout, "\n");
- fprintf (stdout, "Zone identifier (zid):\n");
+ fprintf (stdout, "Zone identifier (ztype|zkey):\n");
print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8);
GNUNET_STRINGS_data_to_string (&id_pub,
GNUNET_IDENTITY_key_get_length (&id_pub),
@@ -229,21 +332,23 @@ run_edkey (void)
GNUNET_DNSPARSER_TYPE_A, TEST_RECORD_A, &data, &data_size));
rd[0].data = data;
rd[0].data_size = data_size;
- rd[0].expiration_time = exp_abs.abs_value_us;
+ rd[0].expiration_time = exp1.abs_value_us;
rd[0].record_type = GNUNET_DNSPARSER_TYPE_A;
fprintf (stdout, "Record #0\n");
print_record (&rd[0]);
- rd[1].data = &pkey_data;
- rd[1].data_size = sizeof (struct GNUNET_CRYPTO_EddsaPublicKey);
- rd[1].expiration_time = exp_abs.abs_value_us;
- rd[1].record_type = GNUNET_GNSRECORD_TYPE_EDKEY;
+ rd[1].data = "My Nick";
+ rd[1].data_size = sizeof (struct GNUNET_IDENTITY_PublicKey);
+ rd[1].expiration_time = exp2.abs_value_us;
+ rd[1].record_type = GNUNET_GNSRECORD_TYPE_NICK;
rd[1].flags = GNUNET_GNSRECORD_RF_PRIVATE;
fprintf (stdout, "Record #1\n");
print_record (&rd[1]);
- rdata_size = GNUNET_GNSRECORD_records_get_size (2,
+ rdata_size = GNUNET_GNSRECORD_records_get_size (TEST_RRCOUNT,
rd);
+ expire = GNUNET_GNSRECORD_record_get_expiration_time (TEST_RRCOUNT,
+ rd);
rdata = GNUNET_malloc (rdata_size);
GNUNET_GNSRECORD_records_serialize (2,
rd,
@@ -252,25 +357,39 @@ run_edkey (void)
fprintf (stdout, "RDATA:\n");
print_bytes (rdata, rdata_size, 8);
fprintf (stdout, "\n");
- rrblock = GNUNET_GNSRECORD_block_create (&id_priv,
- exp_abs,
- TEST_RECORD_LABEL,
- rd,
- TEST_RRCOUNT);
- size_t bdata_size = ntohl (rrblock->eddsa_block.purpose.size)
- - sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
- - sizeof(struct GNUNET_TIME_AbsoluteNBO);
- size_t ecblock_size = ntohl (rrblock->eddsa_block.purpose.size)
- + sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)
- + sizeof(struct GNUNET_CRYPTO_EddsaSignature);
- size_t block_size = ecblock_size + sizeof (uint32_t);
+ GNR_derive_block_xsalsa_key (nonce,
+ skey,
+ TEST_RECORD_LABEL,
+ GNUNET_TIME_absolute_hton (
+ expire).abs_value_us__,
+ &id_pub.eddsa_key);
+ fprintf (stdout, "Encryption NONCE|EXPIRATION:\n");
+ print_bytes (nonce, sizeof (nonce), 8);
+ fprintf (stdout, "\n");
+ fprintf (stdout, "Encryption key (K):\n");
+ print_bytes (skey, sizeof (skey), 8);
+ fprintf (stdout, "\n");
+ GNUNET_GNSRECORD_query_from_public_key (&id_pub,
+ TEST_RECORD_LABEL,
+ &query);
+ fprintf (stdout, "Storage key (q):\n");
+ print_bytes (&query, sizeof (query), 8);
+ fprintf (stdout, "\n");
+
+ GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (&id_priv,
+ expire,
+ TEST_RECORD_LABEL,
+ rd,
+ TEST_RRCOUNT,
+ &rrblock));
+ size_t bdata_size = ntohl(rrblock->size) - sizeof (struct GNUNET_GNSRECORD_Block);
bdata = (char*) &(&rrblock->eddsa_block)[1];
fprintf (stdout, "BDATA:\n");
print_bytes (bdata, bdata_size, 8);
fprintf (stdout, "\n");
fprintf (stdout, "RRBLOCK:\n");
- print_bytes (rrblock, block_size, 8);
+ print_bytes (rrblock, ntohl(rrblock->size), 8);
fprintf (stdout, "\n");
GNUNET_free (rdata);
}
@@ -290,8 +409,8 @@ run (void *cls,
const char *cfgfile,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
- run_pkey();
- run_edkey();
+ run_pkey ();
+ run_edkey ();
}
diff --git a/src/gnsrecord/test_gnsrecord_crypto.c b/src/gnsrecord/test_gnsrecord_crypto.c
index 9e5a1aa7e..ee14fa904 100644
--- a/src/gnsrecord/test_gnsrecord_crypto.c
+++ b/src/gnsrecord/test_gnsrecord_crypto.c
@@ -123,12 +123,12 @@ test_with_type (struct GNUNET_IDENTITY_PrivateKey *privkey)
s_rd = create_record (RECORDS);
/* Create block */
- GNUNET_assert (NULL != (block =
- GNUNET_GNSRECORD_block_create (privkey,
- expire,
- s_name,
- s_rd,
- RECORDS)));
+ GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (privkey,
+ expire,
+ s_name,
+ s_rd,
+ RECORDS,
+ &block));
GNUNET_assert (GNUNET_OK ==
GNUNET_GNSRECORD_query_from_block (block,
&query_block));
diff --git a/src/gnsrecord/test_gnsrecord_testvectors.c b/src/gnsrecord/test_gnsrecord_testvectors.c
new file mode 100644
index 000000000..153c56261
--- /dev/null
+++ b/src/gnsrecord/test_gnsrecord_testvectors.c
@@ -0,0 +1,128 @@
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_signatures.h"
+#include "gnunet_gns_service.h"
+#include "gnunet_gnsrecord_lib.h"
+#include "gnunet_dnsparser_lib.h"
+#include "gnunet_testing_lib.h"
+#include <inttypes.h>
+
+
+
+static char *d =
+"50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98";
+
+
+static char *zid =
+"00010000677c477d2d93097c85b195c6f96d84ff61f5982c2c4fe02d5a11fedfb0c2901f";
+
+#define RRCOUNT 2
+#define LABEL "test"
+
+#define R0_EXPIRATION 14888744139323793
+#define R0_DATA_SIZE 4
+#define R0_TYPE 1
+#define R0_FLAGS 0
+#define R0_DATA "01020304"
+
+/* Record #1*/
+#define R1_EXPIRATION 26147096139323793
+#define R1_DATA_SIZE 36
+#define R1_TYPE 65536
+#define R1_FLAGS 2
+#define R1_DATA \
+"000100000e601be42eb57fb4697610cf3a3b18347b65a33f025b5b174abefb30807bfecf"
+
+#define R1_RRBLOCK \
+"000100008e16da87203b5159c5538e9b765742e968c54af9afbc0890dc80205ad14c84e107b0c115fc0089aa38b9c7ab9cbe1d77040d282a51a2ad493f61f3495f02d8170fe473a55ec6bdf9a509ab1701ffc37ea3bb4cac4a672520986df96e67cc1a73000000940000000f0034e53be193799100e4837eb5d04f92903de4b5234e8ccac5736c9793379a59c33375fc8951aca2eb7aad067bf9af60bf26758646a17f5e5c3b6215f94079545b1c4d4f1b2ebb22c2b4dad44126817b6f001530d476401dd67ac0148554e806353da9e4298079f3e1b16942c48d90c4360c61238c40d9d52911aea52cc0037ac7160bb3cf5b2f4a722fd96b"
+
+int parsehex(char *src, char *dst, size_t dstlen, int invert)
+{
+ char *line = src;
+ char *data = line;
+ int off;
+ int read_byte;
+ int data_len = 0;
+
+ while (sscanf(data, " %02x%n", &read_byte, &off) == 1) {
+ if (invert)
+ dst[dstlen - 1 - data_len++] = read_byte;
+ else
+ dst[data_len++] = read_byte;
+ data += off;
+ }
+ return data_len;
+}
+
+void
+res_checker (void *cls,
+ unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
+{
+ int r0_found = 0;
+ int r1_found = 0;
+ char r0_data[R0_DATA_SIZE];
+ char r1_data[R1_DATA_SIZE];
+ parsehex(R0_DATA, (char*)r0_data, 0, 0);
+ parsehex(R1_DATA, (char*)r1_data, 0, 0);
+ GNUNET_assert (rd_count == RRCOUNT);
+ for (int i = 0; i < RRCOUNT; i++)
+ {
+ if (rd[i].record_type == R0_TYPE)
+ {
+ if (0 != memcmp (rd[i].data, r0_data, R0_DATA_SIZE))
+ {
+ printf ("R0 Data mismatch\n");
+ continue;
+ }
+ if (rd[i].expiration_time != R0_EXPIRATION)
+ {
+ printf ("R0 expiration mismatch\n");
+ continue;
+ }
+ r0_found = 1;
+ }
+ if (rd[i].record_type == R1_TYPE)
+ {
+ if (0 != memcmp (rd[i].data, r1_data, R1_DATA_SIZE))
+ {
+ printf ("R1 Data mismatch\n");
+ continue;
+ }
+ if (rd[i].expiration_time != R1_EXPIRATION)
+ {
+ printf ("R1 expiration mismatch\n");
+ continue;
+ }
+
+ r1_found = 1;
+ }
+
+ }
+ GNUNET_assert (r0_found);
+ GNUNET_assert (r1_found);
+}
+
+
+int
+main()
+{
+ struct GNUNET_IDENTITY_PrivateKey priv;
+ struct GNUNET_IDENTITY_PublicKey pub;
+ struct GNUNET_IDENTITY_PublicKey pub_parsed;
+ struct GNUNET_GNSRECORD_Block *rrblock;
+ char *bdata;
+
+ parsehex(d,(char*)&priv.ecdsa_key, sizeof (priv.ecdsa_key), 1);
+ priv.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
+ parsehex(zid,(char*)&pub_parsed, 0, 0);
+ GNUNET_IDENTITY_key_get_public(&priv, &pub);
+ GNUNET_assert (0 == memcmp (&pub, &pub_parsed, sizeof (pub)));
+ rrblock = GNUNET_malloc (strlen (R1_RRBLOCK) / 2);
+ parsehex(R1_RRBLOCK, (char*)rrblock, 0, 0);
+ GNUNET_GNSRECORD_block_decrypt (rrblock,
+ &pub_parsed,
+ LABEL,
+ &res_checker,
+ NULL);
+ return 0;
+}
diff --git a/src/identity/identity_api.c b/src/identity/identity_api.c
index 4a7a69211..471569cb3 100644
--- a/src/identity/identity_api.c
+++ b/src/identity/identity_api.c
@@ -1063,6 +1063,25 @@ GNUNET_IDENTITY_signature_get_length (const struct
ssize_t
+GNUNET_IDENTITY_signature_get_raw_length_by_type (uint32_t type)
+{
+ switch (ntohl (type))
+ {
+ case GNUNET_IDENTITY_TYPE_ECDSA:
+ return sizeof (struct GNUNET_CRYPTO_EcdsaSignature);
+ break;
+ case GNUNET_IDENTITY_TYPE_EDDSA:
+ return sizeof (struct GNUNET_CRYPTO_EddsaSignature);
+ break;
+ default:
+ GNUNET_break (0);
+ }
+ return -1;
+}
+
+
+
+ssize_t
GNUNET_IDENTITY_read_signature_from_buffer (struct
GNUNET_IDENTITY_Signature *sig,
const void*buffer,
@@ -1099,6 +1118,31 @@ GNUNET_IDENTITY_write_signature_to_buffer (const struct
return length;
}
+enum GNUNET_GenericReturnValue
+GNUNET_IDENTITY_sign_raw_ (const struct
+ GNUNET_IDENTITY_PrivateKey *priv,
+ const struct
+ GNUNET_CRYPTO_EccSignaturePurpose *purpose,
+ unsigned char *sig)
+{
+ switch (ntohl (priv->type))
+ {
+ case GNUNET_IDENTITY_TYPE_ECDSA:
+ return GNUNET_CRYPTO_ecdsa_sign_ (&(priv->ecdsa_key), purpose,
+ (struct GNUNET_CRYPTO_EcdsaSignature*)sig);
+ break;
+ case GNUNET_IDENTITY_TYPE_EDDSA:
+ return GNUNET_CRYPTO_eddsa_sign_ (&(priv->eddsa_key), purpose,
+ (struct GNUNET_CRYPTO_EddsaSignature*)sig);
+ break;
+ default:
+ GNUNET_break (0);
+ }
+
+ return GNUNET_SYSERR;
+}
+
+
enum GNUNET_GenericReturnValue
GNUNET_IDENTITY_sign_ (const struct
@@ -1155,6 +1199,37 @@ GNUNET_IDENTITY_signature_verify_ (uint32_t purpose,
}
+enum GNUNET_GenericReturnValue
+GNUNET_IDENTITY_signature_verify_raw_ (uint32_t purpose,
+ const struct
+ GNUNET_CRYPTO_EccSignaturePurpose *
+ validate,
+ const unsigned char *sig,
+ const struct
+ GNUNET_IDENTITY_PublicKey *pub)
+{
+ switch (ntohl (pub->type))
+ {
+ case GNUNET_IDENTITY_TYPE_ECDSA:
+ return GNUNET_CRYPTO_ecdsa_verify_ (purpose, validate,
+ (struct GNUNET_CRYPTO_EcdsaSignature*)sig,
+ &(pub->ecdsa_key));
+ break;
+ case GNUNET_IDENTITY_TYPE_EDDSA:
+ return GNUNET_CRYPTO_eddsa_verify_ (purpose, validate,
+ (struct GNUNET_CRYPTO_EddsaSignature*)sig,
+ &(pub->eddsa_key));
+ break;
+ default:
+ GNUNET_break (0);
+ }
+
+ return GNUNET_SYSERR;
+}
+
+
+
+
ssize_t
GNUNET_IDENTITY_encrypt (const void *block,
size_t size,
diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h
index 94e20323d..fdbac3cf5 100644
--- a/src/include/gnunet_gnsrecord_lib.h
+++ b/src/include/gnunet_gnsrecord_lib.h
@@ -61,6 +61,7 @@ extern "C" {
/**
* Flags that can be set for a record.
+ * MUST fit into 16 bit.
*/
enum GNUNET_GNSRECORD_Flags
{
@@ -70,10 +71,17 @@ enum GNUNET_GNSRECORD_Flags
GNUNET_GNSRECORD_RF_NONE = 0,
/**
- * This is a private record of this peer and it should
- * thus not be handed out to other peers.
+ * This record is critical. If it cannot be processed
+ * (for example beacuse the record type is unknown)
+ * resolution MUST fail
*/
- GNUNET_GNSRECORD_RF_PRIVATE = 2,
+ GNUNET_GNSRECORD_RF_CRITICAL = 1,
+
+ /**
+ * This record should not be used unless all (other) records with an absolute
+ * expiration time have expired.
+ */
+ GNUNET_GNSRECORD_RF_SHADOW_RECORD = 2,
/**
* This is a supplemental record.
@@ -84,13 +92,14 @@ enum GNUNET_GNSRECORD_Flags
* This expiration time of the record is a relative
* time (not an absolute time).
*/
- GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION = 8,
+ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION = 16384, /* 2^14 */
/**
- * This record should not be used unless all (other) records with an absolute
- * expiration time have expired.
+ * This is a private record of this peer and it should
+ * thus not be handed out to other peers.
*/
- GNUNET_GNSRECORD_RF_SHADOW_RECORD = 16
+ GNUNET_GNSRECORD_RF_PRIVATE = 32768, /* 2^15 */
+
/**
* When comparing flags for record equality for removal,
@@ -184,12 +193,6 @@ struct GNUNET_GNSRECORD_EcdsaBlock
struct GNUNET_CRYPTO_EcdsaSignature signature;
/**
- * Number of bytes signed; also specifies the number of bytes
- * of encrypted data that follow.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
* Expiration time of the block.
*/
struct GNUNET_TIME_AbsoluteNBO expiration_time;
@@ -214,22 +217,25 @@ struct GNUNET_GNSRECORD_EddsaBlock
struct GNUNET_CRYPTO_EddsaSignature signature;
/**
- * Number of bytes signed; also specifies the number of bytes
- * of encrypted data that follow.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
* Expiration time of the block.
*/
struct GNUNET_TIME_AbsoluteNBO expiration_time;
+
/* followed by encrypted data */
};
struct GNUNET_GNSRECORD_Block
{
+ /**
+ * Size of the block.
+ */
+ uint32_t size;
+
+ /**
+ * The zone type (GNUNET_GNSRECORD_TYPE_PKEY)
+ */
uint32_t type;
union
@@ -387,6 +393,9 @@ GNUNET_GNSRECORD_records_serialize (unsigned int rd_count,
const struct GNUNET_GNSRECORD_Data *rd,
size_t dest_size, char *dest);
+unsigned int
+GNUNET_GNSRECORD_records_deserialize_get_size (size_t len,
+ const char *src);
/**
* Deserialize the given records to the given destination.
@@ -503,6 +512,21 @@ GNUNET_GNSRECORD_query_from_public_key (
/**
+ * Get size of buffer for block creation.
+ *
+ * @param key the zone key
+ * @param rd record data
+ * @param rd_count number of records
+ * @return -1 on error (otherwise the length of the block)
+ */
+ssize_t
+GNUNET_GNSRECORD_block_calculate_size (const struct
+ GNUNET_IDENTITY_PrivateKey *key,
+ const struct GNUNET_GNSRECORD_Data *rd,
+ unsigned int rd_count);
+
+
+/**
* Sign name and records
*
* @param key the private key
@@ -510,13 +534,16 @@ GNUNET_GNSRECORD_query_from_public_key (
* @param label the name for the records
* @param rd record data
* @param rd_count number of records in @a rd
+ * @param result the block buffer. Will be allocated.
+ * @return GNUNET_OK on success
*/
-struct GNUNET_GNSRECORD_Block *
+enum GNUNET_GenericReturnValue
GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
struct GNUNET_TIME_Absolute expire,
const char *label,
const struct GNUNET_GNSRECORD_Data *rd,
- unsigned int rd_count);
+ unsigned int rd_count,
+ struct GNUNET_GNSRECORD_Block **block);
/**
@@ -529,13 +556,16 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
* @param label the name for the records
* @param rd record data
* @param rd_count number of records in @a rd
+ * @param result the block buffer. Will be allocated.
+ * @return GNUNET_OK on success.
*/
-struct GNUNET_GNSRECORD_Block *
+enum GNUNET_GenericReturnValue
GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *key,
struct GNUNET_TIME_Absolute expire,
const char *label,
const struct GNUNET_GNSRECORD_Data *rd,
- unsigned int rd_count);
+ unsigned int rd_count,
+ struct GNUNET_GNSRECORD_Block **result);
/**
diff --git a/src/include/gnunet_identity_service.h b/src/include/gnunet_identity_service.h
index b2a45577f..227c7f486 100644
--- a/src/include/gnunet_identity_service.h
+++ b/src/include/gnunet_identity_service.h
@@ -459,6 +459,21 @@ GNUNET_IDENTITY_signature_get_length (const struct
/**
+ * Get the compacted length of a signature by type.
+ * Compacted means that it returns the minimum number of bytes this
+ * signature is long, as opposed to the union structure inside
+ * #GNUNET_IDENTITY_Signature.
+ * Useful for compact serializations.
+ *
+ * @param sig the signature.
+ * @return -1 on error, else the compacted length of the signature.
+ */
+ssize_t
+GNUNET_IDENTITY_signature_get_raw_length_by_type (const uint32_t type);
+
+
+
+/**
* Reads a #GNUNET_IDENTITY_Signature from a compact buffer.
* The buffer has to contain at least the compacted length of
* a #GNUNET_IDENTITY_Signature in bytes.
@@ -516,6 +531,26 @@ GNUNET_IDENTITY_sign_ (const struct
GNUNET_CRYPTO_EccSignaturePurpose *purpose,
struct GNUNET_IDENTITY_Signature *sig);
+/**
+ * @brief Sign a given block.
+ *
+ * The @a purpose data is the beginning of the data of which the signature is
+ * to be created. The `size` field in @a purpose must correctly indicate the
+ * number of bytes of the data structure, including its header.
+ * The signature payload and length depends on the key type.
+ *
+ * @param priv private key to use for the signing
+ * @param purpose what to sign (size, purpose)
+ * @param[out] sig where to write the signature
+ * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
+ */
+enum GNUNET_GenericReturnValue
+GNUNET_IDENTITY_sign_raw_ (const struct
+ GNUNET_IDENTITY_PrivateKey *priv,
+ const struct
+ GNUNET_CRYPTO_EccSignaturePurpose *purpose,
+ unsigned char *sig);
+
/**
* @brief Sign a given block with #GNUNET_IDENTITY_PrivateKey.
@@ -566,6 +601,30 @@ GNUNET_IDENTITY_signature_verify_ (uint32_t purpose,
const struct
GNUNET_IDENTITY_PublicKey *pub);
+/**
+ * @brief Verify a given signature.
+ *
+ * The @a validate data is the beginning of the data of which the signature
+ * is to be verified. The `size` field in @a validate must correctly indicate
+ * the number of bytes of the data structure, including its header. If @a
+ * purpose does not match the purpose given in @a validate (the latter must be
+ * in big endian), signature verification fails.
+ *
+ * @param purpose what is the purpose that the signature should have?
+ * @param validate block to validate (size, purpose, data)
+ * @param sig signature that is being validated
+ * @param pub public key of the signer
+ * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
+ */
+enum GNUNET_GenericReturnValue
+GNUNET_IDENTITY_signature_verify_raw_ (uint32_t purpose,
+ const struct
+ GNUNET_CRYPTO_EccSignaturePurpose *
+ validate,
+ const unsigned char *sig,
+ const struct
+ GNUNET_IDENTITY_PublicKey *pub);
+
/**
* @brief Verify a given signature with #GNUNET_IDENTITY_PublicKey.
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index cf1b555a5..9b2d9b6f3 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -950,11 +950,13 @@ refresh_block (struct NamestoreClient *nc,
}
exp_time = GNUNET_GNSRECORD_record_get_expiration_time (res_count, res);
if (cache_keys)
- block =
- GNUNET_GNSRECORD_block_create2 (zone_key, exp_time, name, res, res_count);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_GNSRECORD_block_create2 (zone_key, exp_time, name,
+ res, res_count, &block));
else
- block =
- GNUNET_GNSRECORD_block_create (zone_key, exp_time, name, res, res_count);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_GNSRECORD_block_create (zone_key, exp_time, name,
+ res, res_count, &block));
GNUNET_assert (NULL != block);
GNUNET_IDENTITY_key_get_public (zone_key, &pkey);
GNUNET_log (
diff --git a/src/revocation/gnunet-revocation-tvg.c b/src/revocation/gnunet-revocation-tvg.c
index cb5e31fcd..3ba5b56fa 100644
--- a/src/revocation/gnunet-revocation-tvg.c
+++ b/src/revocation/gnunet-revocation-tvg.c
@@ -29,15 +29,39 @@
#include "gnunet_revocation_service.h"
#include "gnunet_dnsparser_lib.h"
#include "gnunet_testing_lib.h"
+#include "revocation.h"
#include <inttypes.h>
#define TEST_EPOCHS 2
#define TEST_DIFFICULTY 5
+static char* d_pkey =
+"6fea32c05af58bfa979553d188605fd57d8bf9cc263b78d5f7478c07b998ed70";
+
+int parsehex(char *src, char *dst, size_t dstlen, int invert)
+{
+ char *line = src;
+ char *data = line;
+ int off;
+ int read_byte;
+ int data_len = 0;
+
+ while (sscanf(data, " %02x%n", &read_byte, &off) == 1) {
+ if (invert)
+ dst[dstlen - 1 - data_len++] = read_byte;
+ else
+ dst[data_len++] = read_byte;
+ data += off;
+ }
+ return data_len;
+}
+
+
static void
-print_bytes (void *buf,
+print_bytes_ (void *buf,
size_t buf_len,
- int fold)
+ int fold,
+ int in_be)
{
int i;
@@ -45,11 +69,23 @@ print_bytes (void *buf,
{
if ((0 != i) && (0 != fold) && (i % fold == 0))
printf ("\n");
- printf ("%02x", ((unsigned char*) buf)[i]);
+ if (in_be)
+ printf ("%02x", ((unsigned char*) buf)[buf_len - 1 - i]);
+ else
+ printf ("%02x", ((unsigned char*) buf)[i]);
}
printf ("\n");
}
+static void
+print_bytes (void *buf,
+ size_t buf_len,
+ int fold)
+{
+ print_bytes_ (buf, buf_len, fold, 0);
+}
+
+
/**
* Main function that will be run.
@@ -74,16 +110,17 @@ run (void *cls,
id_priv.type = htonl (GNUNET_IDENTITY_TYPE_ECDSA);
GNUNET_CRYPTO_ecdsa_key_create (&id_priv.ecdsa_key);
+ parsehex(d_pkey,(char*)&id_priv.ecdsa_key, sizeof (id_priv.ecdsa_key), 1);
GNUNET_IDENTITY_key_get_public (&id_priv,
&id_pub);
GNUNET_STRINGS_data_to_string (&id_pub,
GNUNET_IDENTITY_key_get_length (&id_pub),
ztld,
sizeof (ztld));
- fprintf (stdout, "Zone private key (d, little-endian scalar, with ztype prepended):\n");
- print_bytes (&id_priv, sizeof(id_priv), 8);
+ fprintf (stdout, "Zone private key (d, big-endian scalar):\n");
+ print_bytes_ (&id_priv.ecdsa_key, sizeof(id_priv.ecdsa_key), 8, 1);
fprintf (stdout, "\n");
- fprintf (stdout, "Zone identifier (zid):\n");
+ fprintf (stdout, "Zone identifier (ztype|zkey):\n");
print_bytes (&id_pub, GNUNET_IDENTITY_key_get_length (&id_pub), 8);
fprintf (stdout, "\n");
fprintf (stdout, "Encoded zone identifier (zkl = zTLD):\n");
@@ -104,6 +141,15 @@ run (void *cls,
{
pow_passes++;
}
+ struct GNUNET_REVOCATION_SignaturePurposePS *purp;
+ purp = REV_create_signature_message (pow);
+ fprintf (stdout, "Signed message:\n");
+ print_bytes (purp,
+ ntohl (purp->purpose.size),
+ 8);
+ printf ("\n");
+ GNUNET_free (purp);
+
exp = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_YEARS,
TEST_EPOCHS);
GNUNET_assert (GNUNET_OK == GNUNET_REVOCATION_check_pow (pow,
diff --git a/src/revocation/revocation.h b/src/revocation/revocation.h
index c3a9c9e6b..490abf180 100644
--- a/src/revocation/revocation.h
+++ b/src/revocation/revocation.h
@@ -113,5 +113,13 @@ struct RevocationResponseMessage
GNUNET_NETWORK_STRUCT_END
+/**
+ * Create the revocation metadata to sign for a revocation message
+ *
+ * @param pow the PoW to sign
+ * @return the signature purpose
+ */
+struct GNUNET_REVOCATION_SignaturePurposePS *
+REV_create_signature_message (const struct GNUNET_REVOCATION_PowP *pow);
#endif
diff --git a/src/revocation/revocation_api.c b/src/revocation/revocation_api.c
index d5bd53e56..bc5dae021 100644
--- a/src/revocation/revocation_api.c
+++ b/src/revocation/revocation_api.c
@@ -404,19 +404,15 @@ calculate_score (const struct GNUNET_REVOCATION_PowCalculationHandle *ph)
return avg;
}
-
-enum GNUNET_GenericReturnValue
-check_signature_identity (const struct GNUNET_REVOCATION_PowP *pow,
- const struct GNUNET_IDENTITY_PublicKey *key)
+struct GNUNET_REVOCATION_SignaturePurposePS *
+REV_create_signature_message (const struct GNUNET_REVOCATION_PowP *pow)
{
struct GNUNET_REVOCATION_SignaturePurposePS *spurp;
- struct GNUNET_IDENTITY_Signature *sig;
const struct GNUNET_IDENTITY_PublicKey *pk;
size_t ksize;
pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1];
ksize = GNUNET_IDENTITY_key_get_length (pk);
-
spurp = GNUNET_malloc (sizeof (*spurp) + ksize);
spurp->timestamp = pow->timestamp;
spurp->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION);
@@ -424,15 +420,25 @@ check_signature_identity (const struct GNUNET_REVOCATION_PowP *pow,
GNUNET_IDENTITY_write_key_to_buffer (pk,
(char*) &spurp[1],
ksize);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Expected signature payload len: %u\n",
- ntohl (spurp->purpose.size));
- sig = (struct GNUNET_IDENTITY_Signature *) ((char*) &pow[1] + ksize);
+ return spurp;
+}
+
+enum GNUNET_GenericReturnValue
+check_signature_identity (const struct GNUNET_REVOCATION_PowP *pow,
+ const struct GNUNET_IDENTITY_PublicKey *key)
+{
+ struct GNUNET_REVOCATION_SignaturePurposePS *spurp;
+ unsigned char *sig;
+ size_t ksize;
+
+ ksize = GNUNET_IDENTITY_key_get_length (key);
+ spurp = REV_create_signature_message (pow);
+ sig = ((unsigned char*) &pow[1] + ksize);
if (GNUNET_OK !=
- GNUNET_IDENTITY_signature_verify_ (GNUNET_SIGNATURE_PURPOSE_REVOCATION,
- &spurp->purpose,
- sig,
- key))
+ GNUNET_IDENTITY_signature_verify_raw_ (GNUNET_SIGNATURE_PURPOSE_REVOCATION,
+ &spurp->purpose,
+ sig,
+ key))
{
return GNUNET_SYSERR;
}
@@ -577,20 +583,11 @@ sign_pow_identity (const struct GNUNET_IDENTITY_PrivateKey *key,
pk = (const struct GNUNET_IDENTITY_PublicKey *) &pow[1];
ksize = GNUNET_IDENTITY_key_get_length (pk);
pow->timestamp = GNUNET_TIME_absolute_hton (ts);
- rp = GNUNET_malloc (sizeof (*rp) + ksize);
- rp->timestamp = pow->timestamp;
- rp->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION);
- rp->purpose.size = htonl (sizeof(*rp) + ksize);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Signature payload len: %u\n",
- ntohl (rp->purpose.size));
- GNUNET_IDENTITY_write_key_to_buffer (pk,
- ((char*) &rp[1]),
- ksize);
+ rp = REV_create_signature_message (pow);
sig = ((char*) &pow[1]) + ksize;
- int result = GNUNET_IDENTITY_sign_ (key,
- &rp->purpose,
- (void*) sig);
+ int result = GNUNET_IDENTITY_sign_raw_ (key,
+ &rp->purpose,
+ (void*) sig);
if (result == GNUNET_SYSERR)
return GNUNET_NO;
else
@@ -768,7 +765,7 @@ GNUNET_REVOCATION_proof_get_size (const struct GNUNET_REVOCATION_PowP *pow)
ksize = GNUNET_IDENTITY_key_get_length (pk);
size += ksize;
sig = (struct GNUNET_IDENTITY_Signature *) ((char*) &pow[1] + ksize);
- size += GNUNET_IDENTITY_signature_get_length (sig);
+ size += GNUNET_IDENTITY_signature_get_raw_length_by_type (pk->type);
return size;
}
diff --git a/src/util/.gitignore b/src/util/.gitignore
index 7c7b7045d..51eab71db 100644
--- a/src/util/.gitignore
+++ b/src/util/.gitignore
@@ -43,6 +43,7 @@ test_crypto_kdf
test_crypto_paillier
test_crypto_random
test_crypto_rsa
+test_crypto_cs
test_crypto_symmetric
test_disk
test_getopt
@@ -70,7 +71,9 @@ perf_crypto_asymmetric
perf_crypto_hash
perf_crypto_symmetric
perf_crypto_rsa
+perf_crypto_cs
perf_crypto_ecc_dlog
+perf_crypto_paillier
test_hexcoder
test_regex
test_tun
diff --git a/src/util/gnunet-crypto-tvg.c b/src/util/gnunet-crypto-tvg.c
index 28e44e28b..6b2a7f472 100644
--- a/src/util/gnunet-crypto-tvg.c
+++ b/src/util/gnunet-crypto-tvg.c
@@ -672,6 +672,263 @@ checkvec (const char *operation,
GNUNET_free (sig_enc_data);
GNUNET_free (skey);
}
+ else if (0 == strcmp (operation, "cs_blind_signing"))
+ {
+ struct GNUNET_CRYPTO_CsPrivateKey priv;
+ struct GNUNET_CRYPTO_CsPublicKey pub;
+ struct GNUNET_CRYPTO_CsBlindingSecret bs[2];
+ struct GNUNET_CRYPTO_CsRSecret r_priv[2];
+ struct GNUNET_CRYPTO_CsRPublic r_pub[2];
+ struct GNUNET_CRYPTO_CsRPublic r_pub_blind[2];
+ struct GNUNET_CRYPTO_CsC c[2];
+ struct GNUNET_CRYPTO_CsS signature_scalar;
+ struct GNUNET_CRYPTO_CsBlindS blinded_s;
+ struct GNUNET_CRYPTO_CsSignature sig;
+ struct GNUNET_CRYPTO_CsNonce nonce;
+ struct GNUNET_HashCode message_hash;
+ unsigned int b;
+
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "message_hash",
+ &message_hash,
+ sizeof (message_hash)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_public_key",
+ &pub,
+ sizeof (pub)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_private_key",
+ &priv,
+ sizeof (priv)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_nonce",
+ &nonce,
+ sizeof (nonce)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_r_priv_0",
+ &r_priv[0],
+ sizeof (r_priv[0])))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_r_priv_1",
+ &r_priv[1],
+ sizeof (r_priv[1])))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_r_pub_0",
+ &r_pub[0],
+ sizeof (r_pub[0])))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_r_pub_1",
+ &r_pub[1],
+ sizeof (r_pub[1])))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_bs_alpha_0",
+ &bs[0].alpha,
+ sizeof (bs[0].alpha)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_bs_alpha_1",
+ &bs[1].alpha,
+ sizeof (bs[1].alpha)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_bs_beta_0",
+ &bs[0].beta,
+ sizeof (bs[0].beta)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_bs_beta_1",
+ &bs[1].beta,
+ sizeof (bs[1].beta)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_r_pub_blind_0",
+ &r_pub_blind[0],
+ sizeof (r_pub_blind[0])))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_r_pub_blind_1",
+ &r_pub_blind[1],
+ sizeof (r_pub_blind[1])))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_c_0",
+ &c[0],
+ sizeof (c[0])))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_c_1",
+ &c[1],
+ sizeof (c[1])))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_blind_s",
+ &blinded_s,
+ sizeof (blinded_s)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_b",
+ &b,
+ sizeof (b)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_sig_s",
+ &signature_scalar,
+ sizeof (signature_scalar)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ sig.s_scalar = signature_scalar;
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "cs_sig_R",
+ &sig.r_point,
+ sizeof (sig.r_point)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+
+ if ((b != 1)&& (b != 0))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+
+ struct GNUNET_CRYPTO_CsRSecret r_priv_comp[2];
+ struct GNUNET_CRYPTO_CsRPublic r_pub_comp[2];
+ struct GNUNET_CRYPTO_CsBlindingSecret bs_comp[2];
+ struct GNUNET_CRYPTO_CsC c_comp[2];
+ struct GNUNET_CRYPTO_CsRPublic r_pub_blind_comp[2];
+ struct GNUNET_CRYPTO_CsBlindS blinded_s_comp;
+ struct GNUNET_CRYPTO_CsS signature_scalar_comp;
+ struct GNUNET_CRYPTO_CsSignature sig_comp;
+ unsigned int b_comp;
+
+
+ GNUNET_CRYPTO_cs_r_derive (&nonce, &priv, r_priv_comp);
+ GNUNET_CRYPTO_cs_r_get_public (&r_priv_comp[0], &r_pub_comp[0]);
+ GNUNET_CRYPTO_cs_r_get_public (&r_priv_comp[1], &r_pub_comp[1]);
+ GNUNET_assert (0 == memcmp (&r_priv_comp,
+ &r_priv,
+ sizeof(struct GNUNET_CRYPTO_CsRSecret) * 2));
+ GNUNET_assert (0 == memcmp (&r_pub_comp,
+ &r_pub,
+ sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2));
+
+ GNUNET_CRYPTO_cs_blinding_secrets_derive (&nonce,
+ bs_comp);
+ GNUNET_assert (0 == memcmp (&bs_comp,
+ &bs,
+ sizeof(struct GNUNET_CRYPTO_CsBlindingSecret)
+ * 2));
+ GNUNET_CRYPTO_cs_calc_blinded_c (bs_comp,
+ r_pub_comp,
+ &pub,
+ &message_hash,
+ sizeof(message_hash),
+ c_comp,
+ r_pub_blind_comp);
+ GNUNET_assert (0 == memcmp (&c_comp,
+ &c,
+ sizeof(struct GNUNET_CRYPTO_CsC) * 2));
+ GNUNET_assert (0 == memcmp (&r_pub_blind_comp,
+ &r_pub_blind,
+ sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2));
+ b_comp = GNUNET_CRYPTO_cs_sign_derive (&priv,
+ r_priv_comp,
+ c_comp,
+ &nonce,
+ &blinded_s_comp);
+ GNUNET_assert (0 == memcmp (&blinded_s_comp,
+ &blinded_s,
+ sizeof(blinded_s)));
+ GNUNET_assert (0 == memcmp (&b_comp,
+ &b,
+ sizeof(b)));
+ GNUNET_CRYPTO_cs_unblind (&blinded_s_comp,
+ &bs_comp[b_comp],
+ &signature_scalar_comp);
+ GNUNET_assert (0 == memcmp (&signature_scalar_comp,
+ &signature_scalar,
+ sizeof(signature_scalar_comp)));
+ sig_comp.r_point = r_pub_blind_comp[b_comp];
+ sig_comp.s_scalar = signature_scalar_comp;
+ GNUNET_assert (0 == memcmp (&sig_comp,
+ &sig,
+ sizeof(sig_comp)));
+ if (GNUNET_OK != GNUNET_CRYPTO_cs_verify (&sig_comp,
+ &pub,
+ &message_hash,
+ sizeof(message_hash)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ }
else
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -1025,6 +1282,150 @@ output_vectors ()
GNUNET_free (secret_enc_data);
}
+ {
+ json_t *vec = vec_for (vecs, "cs_blind_signing");
+
+ struct GNUNET_CRYPTO_CsPrivateKey priv;
+ struct GNUNET_CRYPTO_CsPublicKey pub;
+ struct GNUNET_CRYPTO_CsBlindingSecret bs[2];
+ struct GNUNET_CRYPTO_CsRSecret r_priv[2];
+ struct GNUNET_CRYPTO_CsRPublic r_pub[2];
+ struct GNUNET_CRYPTO_CsRPublic r_pub_blind[2];
+ struct GNUNET_CRYPTO_CsC c[2];
+ struct GNUNET_CRYPTO_CsS signature_scalar;
+ struct GNUNET_CRYPTO_CsBlindS blinded_s;
+ struct GNUNET_CRYPTO_CsSignature sig;
+ struct GNUNET_CRYPTO_CsNonce nonce;
+ unsigned int b;
+ struct GNUNET_HashCode message_hash;
+
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &message_hash,
+ sizeof (struct GNUNET_HashCode));
+
+ GNUNET_CRYPTO_cs_private_key_generate (&priv);
+ GNUNET_CRYPTO_cs_private_key_get_public (&priv, &pub);
+
+ GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_hkdf (nonce.nonce,
+ sizeof(nonce.nonce),
+ GCRY_MD_SHA512,
+ GCRY_MD_SHA256,
+ "nonce",
+ strlen ("nonce"),
+ "nonce_secret",
+ strlen ("nonce_secret"),
+ NULL,
+ 0));
+ GNUNET_CRYPTO_cs_r_derive (&nonce, &priv, r_priv);
+ GNUNET_CRYPTO_cs_r_get_public (&r_priv[0], &r_pub[0]);
+ GNUNET_CRYPTO_cs_r_get_public (&r_priv[1], &r_pub[1]);
+ GNUNET_CRYPTO_cs_blinding_secrets_derive (&nonce,
+ bs);
+ GNUNET_CRYPTO_cs_calc_blinded_c (bs,
+ r_pub,
+ &pub,
+ &message_hash,
+ sizeof(message_hash),
+ c,
+ r_pub_blind);
+ b = GNUNET_CRYPTO_cs_sign_derive (&priv,
+ r_priv,
+ c,
+ &nonce,
+ &blinded_s);
+ GNUNET_CRYPTO_cs_unblind (&blinded_s, &bs[b], &signature_scalar);
+ sig.r_point = r_pub_blind[b];
+ sig.s_scalar = signature_scalar;
+ if (GNUNET_OK != GNUNET_CRYPTO_cs_verify (&sig,
+ &pub,
+ &message_hash,
+ sizeof(message_hash)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ d2j (vec,
+ "message_hash",
+ &message_hash,
+ sizeof (struct GNUNET_HashCode));
+ d2j (vec,
+ "cs_public_key",
+ &pub,
+ sizeof(pub));
+ d2j (vec,
+ "cs_private_key",
+ &priv,
+ sizeof(priv));
+ d2j (vec,
+ "cs_nonce",
+ &nonce,
+ sizeof(nonce));
+ d2j (vec,
+ "cs_r_priv_0",
+ &r_priv[0],
+ sizeof(r_priv[0]));
+ d2j (vec,
+ "cs_r_priv_1",
+ &r_priv[1],
+ sizeof(r_priv[1]));
+ d2j (vec,
+ "cs_r_pub_0",
+ &r_pub[0],
+ sizeof(r_pub[0]));
+ d2j (vec,
+ "cs_r_pub_1",
+ &r_pub[1],
+ sizeof(r_pub[1]));
+ d2j (vec,
+ "cs_bs_alpha_0",
+ &bs[0].alpha,
+ sizeof(bs[0].alpha));
+ d2j (vec,
+ "cs_bs_alpha_1",
+ &bs[1].alpha,
+ sizeof(bs[1].alpha));
+ d2j (vec,
+ "cs_bs_beta_0",
+ &bs[0].beta,
+ sizeof(bs[0].beta));
+ d2j (vec,
+ "cs_bs_beta_1",
+ &bs[1].beta,
+ sizeof(bs[1].beta));
+ d2j (vec,
+ "cs_r_pub_blind_0",
+ &r_pub_blind[0],
+ sizeof(r_pub_blind[0]));
+ d2j (vec,
+ "cs_r_pub_blind_1",
+ &r_pub_blind[1],
+ sizeof(r_pub_blind[1]));
+ d2j (vec,
+ "cs_c_0",
+ &c[0],
+ sizeof(c[0]));
+ d2j (vec,
+ "cs_c_1",
+ &c[1],
+ sizeof(c[1]));
+ d2j (vec,
+ "cs_blind_s",
+ &blinded_s,
+ sizeof(blinded_s));
+ d2j (vec,
+ "cs_b",
+ &b,
+ sizeof(b));
+ d2j (vec,
+ "cs_sig_s",
+ &signature_scalar,
+ sizeof(signature_scalar));
+ d2j (vec,
+ "cs_sig_R",
+ &r_pub_blind[b],
+ sizeof(r_pub_blind[b]));
+ }
+
json_dumpf (vecfile, stdout, JSON_INDENT (2));
json_decref (vecfile);
printf ("\n");
diff --git a/src/zonemaster/gnunet-service-zonemaster-monitor.c b/src/zonemaster/gnunet-service-zonemaster-monitor.c
index 7e8c1fb8b..3392a19d7 100644
--- a/src/zonemaster/gnunet-service-zonemaster-monitor.c
+++ b/src/zonemaster/gnunet-service-zonemaster-monitor.c
@@ -255,17 +255,19 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key,
expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count,
rd_public);
if (cache_keys)
- block = GNUNET_GNSRECORD_block_create2 (key,
- expire,
- label,
- rd_public,
- rd_public_count);
+ GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key,
+ expire,
+ label,
+ rd_public,
+ rd_public_count,
+ &block));
else
- block = GNUNET_GNSRECORD_block_create (key,
- expire,
- label,
- rd_public,
- rd_public_count);
+ GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key,
+ expire,
+ label,
+ rd_public,
+ rd_public_count,
+ &block));
if (NULL == block)
{
GNUNET_break (0);
diff --git a/src/zonemaster/gnunet-service-zonemaster.c b/src/zonemaster/gnunet-service-zonemaster.c
index 2957cfee2..bacafb97c 100644
--- a/src/zonemaster/gnunet-service-zonemaster.c
+++ b/src/zonemaster/gnunet-service-zonemaster.c
@@ -594,17 +594,19 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key,
expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count,
rd_public);
if (cache_keys)
- block = GNUNET_GNSRECORD_block_create2 (key,
+ GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key,
expire,
label,
rd_public,
- rd_public_count);
+ rd_public_count,
+ &block));
else
- block = GNUNET_GNSRECORD_block_create (key,
+ GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key,
expire,
label,
rd_public,
- rd_public_count);
+ rd_public_count,
+ &block));
if (NULL == block)
{
GNUNET_break (0);