[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnunet] branch master updated: GNS: Rework GNS block wire format
From: |
gnunet |
Subject: |
[gnunet] branch master updated: GNS: Rework GNS block wire format |
Date: |
Thu, 03 Feb 2022 09:25:19 +0100 |
This is an automated email from the git hooks/post-receive script.
martin-schanzenbach pushed a commit to branch master
in repository gnunet.
The following commit(s) were added to refs/heads/master by this push:
new 112ef3796 GNS: Rework GNS block wire format
112ef3796 is described below
commit 112ef3796314122465f23215233d8b7dd7a15a0b
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Thu Feb 3 09:25:12 2022 +0100
GNS: Rework GNS block wire format
---
src/gnsrecord/gnsrecord_crypto.c | 311 ++++++++++++++++++--------------
src/gnsrecord/gnsrecord_crypto.h | 20 ++
src/gnsrecord/gnsrecord_misc.c | 19 +-
src/gnsrecord/gnsrecord_serialization.c | 56 +++++-
src/gnsrecord/gnunet-gnsrecord-tvg.c | 82 ++++-----
src/gnsrecord/test_gnsrecord_crypto.c | 12 +-
src/include/gnunet_gnsrecord_lib.h | 76 +++++---
7 files changed, 337 insertions(+), 239 deletions(-)
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c
index 24f4c48ca..890ddb011 100644
--- a/src/gnsrecord/gnsrecord_crypto.c
+++ b/src/gnsrecord/gnsrecord_crypto.c
@@ -95,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))
{
@@ -116,8 +116,8 @@ 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;
}
@@ -180,6 +180,20 @@ GNR_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
*
@@ -189,20 +203,22 @@ GNR_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];
@@ -213,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 ();
@@ -236,31 +252,25 @@ 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,
@@ -272,26 +282,40 @@ block_create_ecdsa (const struct
GNUNET_CRYPTO_EcdsaPrivateKey *key,
label,
ecblock->expiration_time.abs_value_us__,
pkey);
- GNUNET_break (payload_len + sizeof(uint32_t) ==
+ 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;
}
@@ -304,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];
@@ -328,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 ();
@@ -351,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,
@@ -392,38 +417,56 @@ block_create_eddsa (const struct
GNUNET_CRYPTO_EddsaPrivateKey *key,
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,
@@ -438,7 +481,8 @@ GNUNET_GNSRECORD_block_create (const struct
GNUNET_IDENTITY_PrivateKey *key,
expire,
norm_label,
rd,
- rd_count);
+ rd_count,
+ result);
break;
case GNUNET_GNSRECORD_TYPE_EDKEY:
res = block_create_eddsa (&key->eddsa_key,
@@ -446,7 +490,8 @@ GNUNET_GNSRECORD_block_create (const struct
GNUNET_IDENTITY_PrivateKey *key,
expire,
norm_label,
rd,
- rd_count);
+ rd_count,
+ result);
break;
default:
GNUNET_assert (0);
@@ -473,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);
@@ -522,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))
{
@@ -533,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;
@@ -550,41 +586,55 @@ 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_ (
+ purp->expiration_time = block->ecdsa_block.expiration_time;
+ res = GNUNET_CRYPTO_ecdsa_verify_ (
GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
- &block->ecdsa_block.purpose,
+ &purp->purpose,
&block->ecdsa_block.signature,
&block->ecdsa_block.derived_key);
+ break;
case GNUNET_GNSRECORD_TYPE_EDKEY:
- return GNUNET_CRYPTO_eddsa_verify_ (
+ purp->expiration_time = block->eddsa_block.expiration_time;
+ res = GNUNET_CRYPTO_eddsa_verify_ (
GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
- &block->eddsa_block.purpose,
+ &purp->purpose,
&block->eddsa_block.signature,
&block->eddsa_block.derived_key);
+ break;
default:
- return GNUNET_NO;
+ 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))
{
@@ -594,20 +644,18 @@ block_decrypt_ecdsa (const struct
GNUNET_GNSRECORD_EcdsaBlock *block,
GNR_derive_block_aes_key (ctr,
key,
label,
- block->expiration_time.abs_value_us__,
+ 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 */
@@ -620,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))
{
@@ -699,20 +747,20 @@ 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))
{
@@ -722,20 +770,19 @@ block_decrypt_eddsa (const struct
GNUNET_GNSRECORD_EddsaBlock *block,
GNR_derive_block_xsalsa_key (nonce,
key,
label,
- block->expiration_time.abs_value_us__,
+
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 */
@@ -748,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))
{
@@ -852,12 +899,12 @@ GNUNET_GNSRECORD_block_decrypt (const struct
GNUNET_GNSRECORD_Block *block,
switch (ntohl (zone_key->type))
{
case GNUNET_IDENTITY_TYPE_ECDSA:
- res = block_decrypt_ecdsa (&block->ecdsa_block,
+ 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->eddsa_block,
+ res = block_decrypt_eddsa (block,
&zone_key->eddsa_key, norm_label, proc,
proc_cls);
break;
diff --git a/src/gnsrecord/gnsrecord_crypto.h b/src/gnsrecord/gnsrecord_crypto.h
index be762f1b5..79a7e6fb9 100644
--- a/src/gnsrecord/gnsrecord_crypto.h
+++ b/src/gnsrecord/gnsrecord_crypto.h
@@ -34,6 +34,26 @@
#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.
*
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 91c6608cd..f9b83e48b 100644
--- a/src/gnsrecord/gnunet-gnsrecord-tvg.c
+++ b/src/gnsrecord/gnunet-gnsrecord-tvg.c
@@ -38,12 +38,12 @@
#define TEST_RRCOUNT 2
static char *d_pkey =
-"50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98";
+ "50d7b652a4efeadff37396909785e5952171a02178c8e7d450fa907925fafd98";
static char *d_edkey =
-"5af7020ee19160328832352bbc6a68a8d71a7cbe1b929969a7c66d415a0d8f65";
+ "5af7020ee19160328832352bbc6a68a8d71a7cbe1b929969a7c66d415a0d8f65";
-int parsehex(char *src, char *dst, size_t dstlen, int invert)
+int parsehex (char *src, char *dst, size_t dstlen, int invert)
{
char *line = src;
char *data = line;
@@ -51,7 +51,8 @@ int parsehex(char *src, char *dst, size_t dstlen, int invert)
int read_byte;
int data_len = 0;
- while (sscanf(data, " %02x%n", &read_byte, &off) == 1) {
+ while (sscanf (data, " %02x%n", &read_byte, &off) == 1)
+ {
if (invert)
dst[dstlen - 1 - data_len++] = read_byte;
else
@@ -155,9 +156,9 @@ run_pkey (void)
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);
+ parsehex (d_pkey,
+ (char*) &id_priv.ecdsa_key,
+ sizeof (id_priv.ecdsa_key), 1);
GNUNET_IDENTITY_key_get_public (&id_priv,
&id_pub);
@@ -204,16 +205,12 @@ run_pkey (void)
rdata_size = GNUNET_GNSRECORD_records_get_size (TEST_RRCOUNT,
rd);
rdata = GNUNET_malloc (rdata_size);
- rd_count_nbo = htonl (2);
- GNUNET_memcpy (rdata,
- &rd_count_nbo,
- sizeof (uint32_t));
GNUNET_GNSRECORD_records_serialize (2,
rd,
rdata_size,
- rdata + sizeof (uint32_t));
+ rdata);
fprintf (stdout, "RDATA:\n");
- print_bytes (rdata, rdata_size + sizeof (uint32_t), 8);
+ print_bytes (rdata, rdata_size, 8);
fprintf (stdout, "\n");
expire = GNUNET_GNSRECORD_record_get_expiration_time (TEST_RRCOUNT, rd);
GNR_derive_block_aes_key (ctr,
@@ -235,26 +232,20 @@ run_pkey (void)
fprintf (stdout, "Storage key (q):\n");
print_bytes (&query, sizeof (query), 8);
fprintf (stdout, "\n");
-
- rrblock = GNUNET_GNSRECORD_block_create (&id_priv,
- expire,
- 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);
+ 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);
}
@@ -309,9 +300,9 @@ run_edkey (void)
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);
+ 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,
@@ -358,17 +349,13 @@ run_edkey (void)
rd);
expire = GNUNET_GNSRECORD_record_get_expiration_time (TEST_RRCOUNT,
rd);
- rdata = GNUNET_malloc (sizeof (uint32_t) + rdata_size);
- rd_count_nbo = htonl (2);
- GNUNET_memcpy (rdata,
- &rd_count_nbo,
- sizeof (uint32_t));
+ rdata = GNUNET_malloc (rdata_size);
GNUNET_GNSRECORD_records_serialize (2,
rd,
rdata_size,
- rdata + sizeof (uint32_t));
+ rdata);
fprintf (stdout, "RDATA:\n");
- print_bytes (rdata, rdata_size + sizeof (uint32_t), 8);
+ print_bytes (rdata, rdata_size, 8);
fprintf (stdout, "\n");
GNR_derive_block_xsalsa_key (nonce,
skey,
@@ -389,25 +376,20 @@ run_edkey (void)
print_bytes (&query, sizeof (query), 8);
fprintf (stdout, "\n");
- rrblock = GNUNET_GNSRECORD_block_create (&id_priv,
- expire,
- 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);
+ 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);
}
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/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,
@@ -183,12 +192,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.
*/
@@ -213,23 +216,26 @@ 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.
@@ -502,6 +511,21 @@ GNUNET_GNSRECORD_query_from_public_key (
struct GNUNET_HashCode *query);
+/**
+ * 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
*
@@ -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);
/**
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnunet] branch master updated: GNS: Rework GNS block wire format,
gnunet <=