From: Matthias Wachs Date: Thu, 1 Mar 2012 16:17:42 +0000 (+0000) Subject: - more changes: sign & verify working and tested X-Git-Tag: initial-import-from-subversion-38251~14516 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=9121b5fdbb38b5ee48695edf5c45bfca1eeb0a29;p=oweals%2Fgnunet.git - more changes: sign & verify working and tested --- diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am index 5f2e23e8b..4d9410f7b 100644 --- a/src/namestore/Makefile.am +++ b/src/namestore/Makefile.am @@ -24,11 +24,13 @@ endif check_PROGRAMS = \ $(SQLITE_TESTS) \ + test_namestore_api_sign_verify \ test_namestore_api \ test_namestore_api_put \ test_namestore_api_lookup \ test_namestore_api_create \ test_namestore_api_remove \ + test_namestore_api_remove_not_existing_record \ test_namestore_api_zone_iteration \ test_namestore_record_serialization @@ -78,6 +80,12 @@ libgnunet_plugin_namestore_sqlite_la_LIBADD = \ libgnunet_plugin_namestore_sqlite_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) +test_namestore_api_sign_verify_SOURCES = \ + test_namestore_api_sign_verify.c +test_namestore_api_sign_verify_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + test_namestore_api_SOURCES = \ test_namestore_api.c test_namestore_api_LDADD = \ @@ -108,6 +116,11 @@ test_namestore_api_remove_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/namestore/libgnunetnamestore.la +test_namestore_api_remove_not_existing_record_SOURCES = \ + test_namestore_api_remove_not_existing_record.c +test_namestore_api_remove_not_existing_record_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la test_namestore_api_zone_iteration_SOURCES = \ test_namestore_api_zone_iteration.c diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c index 828488d58..f25907b81 100644 --- a/src/namestore/gnunet-service-namestore.c +++ b/src/namestore/gnunet-service-namestore.c @@ -504,50 +504,6 @@ struct CreateRecordContext struct GNUNET_NAMESTORE_Client *nc; }; -struct GNUNET_CRYPTO_RsaSignature * -GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_RsaPrivateKey *key, const char *name, struct GNUNET_NAMESTORE_RecordData *rd, unsigned int rd_count) -{ - struct GNUNET_CRYPTO_RsaSignature *sig = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignature)); - struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose; - size_t rd_ser_len; - size_t name_len; - char * name_tmp; - char * rd_tmp; - int res; - - if (name == NULL) - { - GNUNET_break (0); - GNUNET_free (sig); - return NULL; - } - name_len = strlen (name) + 1; - - rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd); - char rd_ser[rd_ser_len]; - GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser); - - sig_purpose = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + rd_ser_len + name_len); - - sig_purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose)+ rd_ser_len + name_len); - sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); - name_tmp = (char *) &sig_purpose[1]; - rd_tmp = &name_tmp[name_len]; - memcpy (name_tmp, name, name_len); - memcpy (rd_tmp, rd_ser, rd_ser_len); - - res = GNUNET_CRYPTO_rsa_sign (key, sig_purpose, sig); - - GNUNET_free (sig_purpose); - - if (GNUNET_OK != res) - { - GNUNET_break (0); - GNUNET_free (sig); - return NULL; - } - return sig; -} static void handle_create_record_it (void *cls, diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h index be061e05e..98a9c5cd1 100644 --- a/src/namestore/namestore.h +++ b/src/namestore/namestore.h @@ -44,6 +44,9 @@ #define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP 442 +struct GNUNET_CRYPTO_RsaSignature * +GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_RsaPrivateKey *key, const char *name, struct GNUNET_NAMESTORE_RecordData *rd, unsigned int rd_count); + GNUNET_NETWORK_STRUCT_BEGIN /** * A GNS record serialized for network transmission. diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c index ff2cbae9f..7a40b2091 100644 --- a/src/namestore/namestore_api.c +++ b/src/namestore/namestore_api.c @@ -30,15 +30,10 @@ #include "gnunet_crypto_lib.h" #include "gnunet_constants.h" #include "gnunet_arm_service.h" +#include "gnunet_signatures.h" #include "gnunet_namestore_service.h" #include "namestore.h" -#include "platform.h" -#include -#include "gnunet_common.h" -#include "gnunet_crypto_lib.h" -#include "gnunet_disk_lib.h" - #define DEBUG_GNS_API GNUNET_EXTRA_LOGGING #define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__) @@ -920,7 +915,36 @@ GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_RsaPublicKeyBinary const struct GNUNET_NAMESTORE_RecordData *rd, const struct GNUNET_CRYPTO_RsaSignature *signature) { - return GNUNET_SYSERR; + int res = GNUNET_SYSERR; + size_t rd_ser_len = 0; + size_t name_len = 0; + char * name_tmp; + char * rd_tmp; + struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose; + + GNUNET_assert (public_key != NULL); + GNUNET_assert (name != NULL); + GNUNET_assert (signature != NULL); + + rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser); + + name_len = strlen (name) + 1; + + sig_purpose = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + rd_ser_len + name_len); + sig_purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose)+ rd_ser_len + name_len); + sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); + name_tmp = (char *) &sig_purpose[1]; + rd_tmp = &name_tmp[name_len]; + memcpy (name_tmp, name, name_len); + memcpy (rd_tmp, rd_ser, rd_ser_len); + + res = GNUNET_CRYPTO_rsa_verify(GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, sig_purpose, signature, public_key); + + GNUNET_free (sig_purpose); + + return res; } /** diff --git a/src/namestore/namestore_common.c b/src/namestore/namestore_common.c index 355bdb52a..c65fc76fe 100644 --- a/src/namestore/namestore_common.c +++ b/src/namestore/namestore_common.c @@ -28,6 +28,7 @@ #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_constants.h" +#include "gnunet_signatures.h" #include "gnunet_arm_service.h" #include "gnunet_namestore_service.h" #include "namestore.h" @@ -171,161 +172,49 @@ GNUNET_NAMESTORE_records_deserialize (size_t len, return GNUNET_OK; } - - -#if 0 - -/** - * Serialize an array of GNUNET_NAMESTORE_RecordData *rd to transmit over the - * network - * - * @param dest where to write the serialized data - * @param rd_count number of elements in array - * @param rd array - * - * @return number of bytes written to destination dest - */ -size_t -GNUNET_NAMESTORE_records_serialize (char ** dest, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd) -{ - //size_t len = 0; - struct GNUNET_NAMESTORE_NetworkRecord nr; - char * d = (*dest); - int c = 0; - int offset; - - GNUNET_assert (rd != NULL); - - size_t total_len = rd_count * sizeof (struct GNUNET_NAMESTORE_NetworkRecord); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Struct size: %u\n", total_len); - - /* figure out total len required */ - for (c = 0; c < rd_count; c ++) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data size record[%i] : %u\n", c, rd[c].data_size); - total_len += rd[c].data_size; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serializing %i records with total length of %llu\n", rd_count, total_len); - - (*dest) = GNUNET_malloc (total_len); - d = (*dest); - - /* copy records */ - offset = 0; - - for (c = 0; c < rd_count; c ++) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serialized record [%i]: data_size %i\n", c,rd[c].data_size); - - // nr = (struct GNUNET_NAMESTORE_NetworkRecord *) &d[offset]; - nr.data_size = htonl (rd[c].data_size); - nr.flags = htonl (rd[c].flags); - nr.record_type = htonl (rd[c].record_type); - nr.expiration = GNUNET_TIME_absolute_hton(rd[c].expiration); - memcpy (&d[offset], &nr, sizeof (nr)); - offset += sizeof (struct GNUNET_NAMESTORE_NetworkRecord); - - /*put data here */ - memcpy (&d[offset], rd[c].data, rd[c].data_size); - offset += rd[c].data_size; - } - - GNUNET_assert (offset == total_len); - return total_len; -} - -void -GNUNET_NAMESTORE_records_free (unsigned int rd_count, struct GNUNET_NAMESTORE_RecordData *rd) -{ - int c; - if ((rd == NULL) || (rd_count == 0)) - return; - - for (c = 0; c < rd_count; c++) - GNUNET_free_non_null ((void *) rd[c].data); - GNUNET_free (rd); -} - - -/** - * Deserialize an array of GNUNET_NAMESTORE_RecordData *rd after transmission - * over the network - * - * @param source where to read the data to deserialize - * @param rd_count number of elements in array - * @param rd array - * - * @return number of elements deserialized - */ -int -GNUNET_NAMESTORE_records_deserialize ( struct GNUNET_NAMESTORE_RecordData **dest, char *src, size_t len) +struct GNUNET_CRYPTO_RsaSignature * +GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_RsaPrivateKey *key, const char *name, struct GNUNET_NAMESTORE_RecordData *rd, unsigned int rd_count) { - struct GNUNET_NAMESTORE_NetworkRecord * nr; - struct GNUNET_NAMESTORE_RecordData *d = (*dest); - int elements; - size_t offset; - uint32_t data_size; - int c; - - if (len == 0) + struct GNUNET_CRYPTO_RsaSignature *sig = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignature)); + struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose; + size_t rd_ser_len; + size_t name_len; + char * name_tmp; + char * rd_tmp; + int res; + + if (name == NULL) { - (*dest) = NULL; - return 0; + GNUNET_break (0); + GNUNET_free (sig); + return NULL; } + name_len = strlen (name) + 1; - offset = 0; - elements = 0; - while (offset < len) - { - nr = (struct GNUNET_NAMESTORE_NetworkRecord *) &src[offset]; - offset += sizeof (struct GNUNET_NAMESTORE_NetworkRecord); + rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser); - data_size = ntohl (nr->data_size); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Datasize record[%i]: %u\n", elements, data_size); - offset += data_size; - elements ++; - } + sig_purpose = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + rd_ser_len + name_len); - if (elements == 0) - { - (*dest) = NULL; - return 0; - } + sig_purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose)+ rd_ser_len + name_len); + sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); + name_tmp = (char *) &sig_purpose[1]; + rd_tmp = &name_tmp[name_len]; + memcpy (name_tmp, name, name_len); + memcpy (rd_tmp, rd_ser, rd_ser_len); + res = GNUNET_CRYPTO_rsa_sign (key, sig_purpose, sig); - GNUNET_assert (len == offset); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deserializing %i records with total length of %u\n", elements, len); + GNUNET_free (sig_purpose); - (*dest) = GNUNET_malloc (elements * sizeof (struct GNUNET_NAMESTORE_RecordData)); - d = (*dest); - - offset = 0; - for (c = 0; c < elements; c++) + if (GNUNET_OK != res) { - nr = (struct GNUNET_NAMESTORE_NetworkRecord *) &src[offset]; - d[c].expiration = GNUNET_TIME_absolute_ntoh(nr->expiration); - d[c].record_type = ntohl (nr->record_type); - d[c].flags = ntohl (nr->flags); - d[c].data_size = ntohl (nr->data_size); - if (d[c].data_size > 0) - d[c].data = GNUNET_malloc (d[c].data_size); - else - d[c].data = NULL; - - offset += sizeof (struct GNUNET_NAMESTORE_NetworkRecord); - memcpy((char *) d[c].data, &src[offset], d[c].data_size); - - offset += d[c].data_size; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deserialized record[%i] /w data_size %i\n", c, d[c].data_size); + GNUNET_break (0); + GNUNET_free (sig); + return NULL; } - GNUNET_assert(offset == len); - - return elements; + return sig; } -#endif - /* end of namestore_api.c */ diff --git a/src/namestore/test_namestore_api.conf b/src/namestore/test_namestore_api.conf index 1b83e8f13..1683d13cf 100644 --- a/src/namestore/test_namestore_api.conf +++ b/src/namestore/test_namestore_api.conf @@ -4,7 +4,7 @@ DEFAULTSERVICES = namestore UNIXPATH = /tmp/gnunet-p1-service-arm.sock [namestore] -#PREFIX = valgrind --leak-check=full +PREFIX = valgrind --leak-check=full AUTOSTART = YES UNIXPATH = /tmp/gnunet-service-namestore.sock UNIX_MATCH_UID = YES diff --git a/src/namestore/test_namestore_api_remove.c b/src/namestore/test_namestore_api_remove.c new file mode 100644 index 000000000..69e9d34f3 --- /dev/null +++ b/src/namestore/test_namestore_api_remove.c @@ -0,0 +1,343 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, 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 + General Public License for more details. + + 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. +*/ +/** + * @file namestore/test_namestore_api.c + * @brief testcase for namestore_api.c + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" +#include "gnunet_signatures.h" + +#define VERBOSE GNUNET_NO + +#define RECORDS 5 +#define TEST_RECORD_TYPE 1234 +#define TEST_RECORD_DATALEN 123 +#define TEST_RECORD_DATA 'a' + +#define TEST_REMOVE_RECORD_TYPE 4321 +#define TEST_REMOVE_RECORD_DATALEN 255 +#define TEST_REMOVE_RECORD_DATA 'b' + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static struct GNUNET_NAMESTORE_Handle * nsh; + +static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; +static struct GNUNET_OS_Process *arm; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; +struct GNUNET_CRYPTO_RsaSignature s_signature; +static GNUNET_HashCode s_zone; +struct GNUNET_NAMESTORE_RecordData *s_rd; +static char *s_name; + + + +static int res; + +static void +start_arm (const char *cfgname) +{ + arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", "-c", cfgname, +#if VERBOSE_PEERS + "-L", "DEBUG", +#else + "-L", "ERROR", +#endif + NULL); +} + +static void +stop_arm () +{ + if (NULL != arm) + { + if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm); + GNUNET_OS_process_close (arm); + arm = NULL; + } +} + +/** + * Re-establish the connection to the service. + * + * @param cls handle to use to re-connect. + * @param tc scheduler context + */ +static void +endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (NULL != arm) + stop_arm(); + + res = 1; +} + + +static void +end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (endbadly_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_NO_TASK; + } + + int c; + for (c = 0; c < RECORDS; c++) + GNUNET_free_non_null((void *) s_rd[c].data); + GNUNET_free (s_rd); + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (NULL != arm) + stop_arm(); +} + +void name_lookup_proc (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *n, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + static int found = GNUNET_NO; + int failed = GNUNET_NO; + int c; + + if (n != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup for name `%s' returned %u records\n", n, rd_count); + if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (0 != strcmp(n, s_name)) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (RECORDS-1 != rd_count) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + for (c = 0; c < rd_count; c++) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record [%u]: type: %u, size %u\n", c, rd[c].record_type, rd[c].data_size); + GNUNET_break (rd[c].expiration.abs_value == s_rd[c+1].expiration.abs_value); + GNUNET_break (rd[c].record_type == TEST_RECORD_TYPE); + GNUNET_break (rd[c].data_size == TEST_RECORD_DATALEN); + GNUNET_break (0 == memcmp (rd[c].data, s_rd[c+1].data, TEST_RECORD_DATALEN)); + } + + found = GNUNET_YES; + if (failed == GNUNET_NO) + res = 0; + else + res = 1; + } + else + { + if (found != GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name); + res = 1; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name); + } + GNUNET_SCHEDULER_add_now(&end, NULL); +} + +void +remove_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Remove record for `%s': %s\n", name, (success == GNUNET_YES) ? "SUCCESS" : "FAIL", emsg); + if (success == GNUNET_OK) + { + res = 0; + GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, 0, &name_lookup_proc, name); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } + +} + +void +put_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); + if (success == GNUNET_OK) + { + res = 0; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for `%s'\n", name); + + GNUNET_NAMESTORE_record_remove (nsh, privkey, name, &s_rd[0], &remove_cont, name); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } +} + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + rd[0].expiration = GNUNET_TIME_absolute_get(); + rd[0].record_type = 0; + rd[0].data_size = TEST_REMOVE_RECORD_DATALEN; + rd[0].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[0].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + + + for (c = 1; c < RECORDS; c++) + { + rd[c].expiration = GNUNET_TIME_absolute_get(); + rd[c].record_type = TEST_RECORD_TYPE; + rd[c].data_size = TEST_RECORD_DATALEN; + rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + } + + return rd; +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL); + size_t rd_ser_len; + + /* load privat key */ + privkey = GNUNET_CRYPTO_rsa_key_create_from_file("hostkey"); + GNUNET_assert (privkey != NULL); + /* get public key */ + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + + /* create record */ + s_name = "dummy.dummy.gnunet"; + s_rd = create_record (RECORDS); + + rd_ser_len = GNUNET_NAMESTORE_records_get_size(RECORDS, s_rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(RECORDS, s_rd, rd_ser_len, rd_ser); + + /* sign */ + struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + rd_ser_len); + sig_purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose)+ rd_ser_len); + sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); + memcpy (&sig_purpose[1], rd_ser, rd_ser_len); + GNUNET_CRYPTO_rsa_sign (privkey, sig_purpose, &s_signature); + GNUNET_free (sig_purpose); + + /* create random zone hash */ + GNUNET_CRYPTO_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_h2s_full(&s_zone)); + + + start_arm (cfgfile); + GNUNET_assert (arm != NULL); + + nsh = GNUNET_NAMESTORE_connect (cfg); + GNUNET_break (NULL != nsh); + + + + GNUNET_break (s_rd != NULL); + GNUNET_break (s_name != NULL); + + GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name, + GNUNET_TIME_absolute_get_forever(), + RECORDS, s_rd, &s_signature, put_cont, s_name); + +} + +static int +check () +{ + static char *const argv[] = { "test-namestore-api", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + + return ret; +} + +/* end of test_namestore_api.c */ diff --git a/src/namestore/test_namestore_api_remove_not_existing_record.c b/src/namestore/test_namestore_api_remove_not_existing_record.c new file mode 100644 index 000000000..69e9d34f3 --- /dev/null +++ b/src/namestore/test_namestore_api_remove_not_existing_record.c @@ -0,0 +1,343 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, 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 + General Public License for more details. + + 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. +*/ +/** + * @file namestore/test_namestore_api.c + * @brief testcase for namestore_api.c + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" +#include "gnunet_signatures.h" + +#define VERBOSE GNUNET_NO + +#define RECORDS 5 +#define TEST_RECORD_TYPE 1234 +#define TEST_RECORD_DATALEN 123 +#define TEST_RECORD_DATA 'a' + +#define TEST_REMOVE_RECORD_TYPE 4321 +#define TEST_REMOVE_RECORD_DATALEN 255 +#define TEST_REMOVE_RECORD_DATA 'b' + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static struct GNUNET_NAMESTORE_Handle * nsh; + +static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; +static struct GNUNET_OS_Process *arm; + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; +struct GNUNET_CRYPTO_RsaSignature s_signature; +static GNUNET_HashCode s_zone; +struct GNUNET_NAMESTORE_RecordData *s_rd; +static char *s_name; + + + +static int res; + +static void +start_arm (const char *cfgname) +{ + arm = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", "-c", cfgname, +#if VERBOSE_PEERS + "-L", "DEBUG", +#else + "-L", "ERROR", +#endif + NULL); +} + +static void +stop_arm () +{ + if (NULL != arm) + { + if (0 != GNUNET_OS_process_kill (arm, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm); + GNUNET_OS_process_close (arm); + arm = NULL; + } +} + +/** + * Re-establish the connection to the service. + * + * @param cls handle to use to re-connect. + * @param tc scheduler context + */ +static void +endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (NULL != arm) + stop_arm(); + + res = 1; +} + + +static void +end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (endbadly_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (endbadly_task); + endbadly_task = GNUNET_SCHEDULER_NO_TASK; + } + + int c; + for (c = 0; c < RECORDS; c++) + GNUNET_free_non_null((void *) s_rd[c].data); + GNUNET_free (s_rd); + + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + + if (nsh != NULL) + GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); + nsh = NULL; + + if (NULL != arm) + stop_arm(); +} + +void name_lookup_proc (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *n, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + static int found = GNUNET_NO; + int failed = GNUNET_NO; + int c; + + if (n != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup for name `%s' returned %u records\n", n, rd_count); + if (0 != memcmp (zone_key, &pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (0 != strcmp(n, s_name)) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + if (RECORDS-1 != rd_count) + { + GNUNET_break (0); + failed = GNUNET_YES; + } + + for (c = 0; c < rd_count; c++) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record [%u]: type: %u, size %u\n", c, rd[c].record_type, rd[c].data_size); + GNUNET_break (rd[c].expiration.abs_value == s_rd[c+1].expiration.abs_value); + GNUNET_break (rd[c].record_type == TEST_RECORD_TYPE); + GNUNET_break (rd[c].data_size == TEST_RECORD_DATALEN); + GNUNET_break (0 == memcmp (rd[c].data, s_rd[c+1].data, TEST_RECORD_DATALEN)); + } + + found = GNUNET_YES; + if (failed == GNUNET_NO) + res = 0; + else + res = 1; + } + else + { + if (found != GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to lookup records for name `%s'\n", s_name); + res = 1; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Lookup done for name %s'\n", s_name); + } + GNUNET_SCHEDULER_add_now(&end, NULL); +} + +void +remove_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Remove record for `%s': %s\n", name, (success == GNUNET_YES) ? "SUCCESS" : "FAIL", emsg); + if (success == GNUNET_OK) + { + res = 0; + GNUNET_NAMESTORE_lookup_record (nsh, &s_zone, name, 0, &name_lookup_proc, name); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } + +} + +void +put_cont (void *cls, int32_t success, const char *emsg) +{ + char *name = cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); + if (success == GNUNET_OK) + { + res = 0; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing record for `%s'\n", name); + + GNUNET_NAMESTORE_record_remove (nsh, privkey, name, &s_rd[0], &remove_cont, name); + } + else + { + res = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to put records for name `%s'\n", name); + GNUNET_SCHEDULER_add_now(&end, NULL); + } +} + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + rd[0].expiration = GNUNET_TIME_absolute_get(); + rd[0].record_type = 0; + rd[0].data_size = TEST_REMOVE_RECORD_DATALEN; + rd[0].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[0].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + + + for (c = 1; c < RECORDS; c++) + { + rd[c].expiration = GNUNET_TIME_absolute_get(); + rd[c].record_type = TEST_RECORD_TYPE; + rd[c].data_size = TEST_RECORD_DATALEN; + rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + } + + return rd; +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL); + size_t rd_ser_len; + + /* load privat key */ + privkey = GNUNET_CRYPTO_rsa_key_create_from_file("hostkey"); + GNUNET_assert (privkey != NULL); + /* get public key */ + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + + /* create record */ + s_name = "dummy.dummy.gnunet"; + s_rd = create_record (RECORDS); + + rd_ser_len = GNUNET_NAMESTORE_records_get_size(RECORDS, s_rd); + char rd_ser[rd_ser_len]; + GNUNET_NAMESTORE_records_serialize(RECORDS, s_rd, rd_ser_len, rd_ser); + + /* sign */ + struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + rd_ser_len); + sig_purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose)+ rd_ser_len); + sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); + memcpy (&sig_purpose[1], rd_ser, rd_ser_len); + GNUNET_CRYPTO_rsa_sign (privkey, sig_purpose, &s_signature); + GNUNET_free (sig_purpose); + + /* create random zone hash */ + GNUNET_CRYPTO_hash (&pubkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &s_zone); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name: `%s' Zone: `%s' \n", s_name, GNUNET_h2s_full(&s_zone)); + + + start_arm (cfgfile); + GNUNET_assert (arm != NULL); + + nsh = GNUNET_NAMESTORE_connect (cfg); + GNUNET_break (NULL != nsh); + + + + GNUNET_break (s_rd != NULL); + GNUNET_break (s_name != NULL); + + GNUNET_NAMESTORE_record_put (nsh, &pubkey, s_name, + GNUNET_TIME_absolute_get_forever(), + RECORDS, s_rd, &s_signature, put_cont, s_name); + +} + +static int +check () +{ + static char *const argv[] = { "test-namestore-api", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + + return ret; +} + +/* end of test_namestore_api.c */ diff --git a/src/namestore/test_namestore_api_sign_verify.c b/src/namestore/test_namestore_api_sign_verify.c new file mode 100644 index 000000000..8a350ac85 --- /dev/null +++ b/src/namestore/test_namestore_api_sign_verify.c @@ -0,0 +1,143 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, 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 + General Public License for more details. + + 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. +*/ +/** + * @file namestore/test_namestore_api_sign_verify.c + * @brief testcase for signing and verifying + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" +#include "gnunet_signatures.h" + +#define VERBOSE GNUNET_NO + +#define RECORDS 5 +#define TEST_RECORD_TYPE 1234 +#define TEST_RECORD_DATALEN 123 +#define TEST_RECORD_DATA 'a' + +#define TEST_REMOVE_RECORD_TYPE 4321 +#define TEST_REMOVE_RECORD_DATALEN 255 +#define TEST_REMOVE_RECORD_DATA 'b' + +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; +struct GNUNET_CRYPTO_RsaSignature s_signature; +struct GNUNET_NAMESTORE_RecordData *s_rd; +static char *s_name; + +static int res; + +static struct GNUNET_NAMESTORE_RecordData * +create_record (int count) +{ + int c; + struct GNUNET_NAMESTORE_RecordData * rd; + rd = GNUNET_malloc (count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + for (c = 0; c < RECORDS; c++) + { + rd[c].expiration = GNUNET_TIME_absolute_get(); + rd[c].record_type = TEST_RECORD_TYPE; + rd[c].data_size = TEST_RECORD_DATALEN; + rd[c].data = GNUNET_malloc(TEST_RECORD_DATALEN); + memset ((char *) rd[c].data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); + } + + return rd; +} + + + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_CRYPTO_RsaSignature * signature; + + /* load privat key */ + privkey = GNUNET_CRYPTO_rsa_key_create_from_file("hostkey"); + GNUNET_assert (privkey != NULL); + /* get public key */ + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + + int res_c; + int res_w; + + /* create record */ + s_name = "dummy.dummy.gnunet"; + s_rd = create_record (RECORDS); + + signature = GNUNET_NAMESTORE_create_signature (privkey, s_name, s_rd, RECORDS); + GNUNET_assert (signature != NULL); + + res_c = GNUNET_NAMESTORE_verify_signature(&pubkey, s_name, RECORDS, s_rd, signature); + GNUNET_break (res == GNUNET_OK); + + GNUNET_free (signature); + + signature = GNUNET_NAMESTORE_create_signature (privkey, s_name, s_rd, RECORDS); + GNUNET_break (signature != NULL); + + res_w = GNUNET_NAMESTORE_verify_signature(&pubkey, s_name, RECORDS - 1, s_rd, signature); + GNUNET_break (res_w == GNUNET_SYSERR); + + GNUNET_free (signature); + + if ((res_c == GNUNET_OK) && (res_w == GNUNET_SYSERR)) + res = 0; + else + res = 1; + +} + +static int +check () +{ + static char *const argv[] = { "test-namestore-api", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-namestore-api", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + + return ret; +} + +/* end of test_namestore_api_sign_verify.c */