/*
This file is part of GNUnet.
- (C) 2009-2013 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2009-2013 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
/**
* @param rd_count number of records
* @return NULL on error (block too large)
*/
-struct GNUNET_NAMESTORE_Block *
-GNUNET_NAMESTORE_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
+struct GNUNET_GNSRECORD_Block *
+GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
struct GNUNET_TIME_Absolute expire,
const char *label,
- const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_GNSRECORD_Data *rd,
unsigned int rd_count)
{
- size_t payload_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
+ size_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
char payload[sizeof (uint32_t) + payload_len];
- struct GNUNET_NAMESTORE_Block *block;
+ struct GNUNET_GNSRECORD_Block *block;
struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey;
struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
struct GNUNET_CRYPTO_SymmetricSessionKey skey;
+ struct GNUNET_GNSRECORD_Data rdc[rd_count];
uint32_t rd_count_nbo;
+ unsigned int i;
+ struct GNUNET_TIME_Absolute now;
- if (payload_len > GNUNET_NAMESTORE_MAX_VALUE_SIZE)
+ if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
return NULL;
+ /* convert relative to absolute times */
+ now = GNUNET_TIME_absolute_get ();
+ for (i=0;i<rd_count;i++)
+ {
+ rdc[i] = rd[i];
+ if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
+ {
+ struct GNUNET_TIME_Relative t;
+
+ /* encrypted blocks must never have relative expiration times, convert! */
+ rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
+ t.rel_value_us = rdc[i].expiration_time;
+ rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us;
+ }
+ }
+ /* serialize */
rd_count_nbo = htonl (rd_count);
memcpy (payload, &rd_count_nbo, sizeof (uint32_t));
GNUNET_assert (payload_len ==
- GNUNET_NAMESTORE_records_serialize (rd_count, rd,
+ GNUNET_GNSRECORD_records_serialize (rd_count, rdc,
payload_len, &payload[sizeof (uint32_t)]));
- block = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Block) +
+ block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) +
sizeof (uint32_t) + payload_len);
block->purpose.size = htonl (sizeof (uint32_t) + payload_len +
sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
sizeof (struct GNUNET_TIME_AbsoluteNBO));
block->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
block->expiration_time = GNUNET_TIME_absolute_hton (expire);
+ /* encrypt and sign */
dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key,
- label,
- "gns");
+ label,
+ "gns");
GNUNET_CRYPTO_ecdsa_key_get_public (dkey,
&block->derived_key);
GNUNET_CRYPTO_ecdsa_key_get_public (key,
derive_block_aes_key (&iv, &skey, label, &pkey);
GNUNET_break (payload_len + sizeof (uint32_t) ==
GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len + sizeof (uint32_t),
- &skey, &iv,
- &block[1]));
+ &skey, &iv,
+ &block[1]));
if (GNUNET_OK !=
GNUNET_CRYPTO_ecdsa_sign (dkey,
&block->purpose,
* @return #GNUNET_OK if the signature is valid
*/
int
-GNUNET_NAMESTORE_block_verify (const struct GNUNET_NAMESTORE_Block *block)
+GNUNET_GNSRECORD_block_verify (const struct GNUNET_GNSRECORD_Block *block)
{
return GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN,
&block->purpose,
* not well-formed
*/
int
-GNUNET_NAMESTORE_block_decrypt (const struct GNUNET_NAMESTORE_Block *block,
+GNUNET_GNSRECORD_block_decrypt (const struct GNUNET_GNSRECORD_Block *block,
const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key,
const char *label,
- GNUNET_NAMESTORE_RecordCallback proc,
+ GNUNET_GNSRECORD_RecordCallback proc,
void *proc_cls)
{
size_t payload_len = ntohl (block->purpose.size) -
return GNUNET_SYSERR;
}
{
- struct GNUNET_NAMESTORE_RecordData rd[rd_count];
+ struct GNUNET_GNSRECORD_Data rd[rd_count];
+ unsigned int i;
+ unsigned int j;
+ unsigned int k;
+ struct GNUNET_TIME_Absolute now;
if (GNUNET_OK !=
- GNUNET_NAMESTORE_records_deserialize (payload_len - sizeof (uint32_t),
+ GNUNET_GNSRECORD_records_deserialize (payload_len - sizeof (uint32_t),
&payload[sizeof (uint32_t)],
rd_count,
rd))
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
+ /* hide expired records */
+ now = GNUNET_TIME_absolute_get ();
+ j = 0;
+ for (i=0;i<rd_count;i++)
+ {
+ if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
+ {
+ /* encrypted blocks must never have relative expiration times, skip! */
+ GNUNET_break_op (0);
+ continue;
+ }
+
+ if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD))
+ {
+ int include_record = GNUNET_YES;
+ /* Shadow record, figure out if we have a not expired active record */
+ for (k=0;k<rd_count;k++)
+ {
+ if (k == i)
+ continue;
+ if (rd[i].expiration_time < now.abs_value_us)
+ include_record = GNUNET_NO; /* Shadow record is expired */
+ if ((rd[k].record_type == rd[i].record_type)
+ && (rd[k].expiration_time >= now.abs_value_us)
+ && (0 == (rd[k].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)))
+ include_record = GNUNET_NO; /* We have a non-expired, non-shadow record of the same type */
+ }
+ if (GNUNET_YES == include_record)
+ {
+ rd[i].flags ^= GNUNET_GNSRECORD_RF_SHADOW_RECORD; /* Remove Flag */
+ if (j != i)
+ rd[j] = rd[i];
+ j++;
+ }
+ }
+ else if (rd[i].expiration_time >= now.abs_value_us)
+ {
+ /* Include this record */
+ if (j != i)
+ rd[j] = rd[i];
+ j++;
+ }
+ }
+ rd_count = j;
if (NULL != proc)
proc (proc_cls, rd_count, (0 != rd_count) ? rd : NULL);
}
* @param query hash to use for the query
*/
void
-GNUNET_NAMESTORE_query_from_private_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+GNUNET_GNSRECORD_query_from_private_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
const char *label,
struct GNUNET_HashCode *query)
{
struct GNUNET_CRYPTO_EcdsaPublicKey pub;
GNUNET_CRYPTO_ecdsa_key_get_public (zone, &pub);
- GNUNET_NAMESTORE_query_from_public_key (&pub, label, query);
+ GNUNET_GNSRECORD_query_from_public_key (&pub, label, query);
}
* @param query hash to use for the query
*/
void
-GNUNET_NAMESTORE_query_from_public_key (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
+GNUNET_GNSRECORD_query_from_public_key (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
const char *label,
struct GNUNET_HashCode *query)
{