X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fnamestore%2Fnamestore_api_common.c;h=388722cd3931f6aac4e3638c16d18a320f44d35a;hb=b6bfed8309e6b9b3286b8f608ad899bfb0a97205;hp=b38a594db8cfea29bc48825d3fed762c951e4892;hpb=8414aa3d3a3eb463f3cadda5fb31dfc24c01f53b;p=oweals%2Fgnunet.git diff --git a/src/namestore/namestore_api_common.c b/src/namestore/namestore_api_common.c index b38a594db..388722cd3 100644 --- a/src/namestore/namestore_api_common.c +++ b/src/namestore/namestore_api_common.c @@ -30,13 +30,14 @@ #include "gnunet_constants.h" #include "gnunet_signatures.h" #include "gnunet_arm_service.h" +#include "gnunet_conversation_service.h" #include "gnunet_namestore_service.h" #include "gnunet_dnsparser_lib.h" #include "gnunet_tun_lib.h" #include "namestore.h" -#define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__) +#define LOG(kind,...) GNUNET_log_from (kind, "namestore-api",__VA_ARGS__) GNUNET_NETWORK_STRUCT_BEGIN @@ -67,7 +68,7 @@ struct NetworkRecord * Flags for the record, network byte order. */ uint32_t flags GNUNET_PACKED; - + }; GNUNET_NETWORK_STRUCT_END @@ -97,13 +98,13 @@ GNUNET_NAMESTORE_normalize_string (const char *src) * @return string form; will be overwritten by next call to #GNUNET_NAMESTORE_z2s */ const char * -GNUNET_NAMESTORE_z2s (const struct GNUNET_CRYPTO_EccPublicKey *z) +GNUNET_NAMESTORE_z2s (const struct GNUNET_CRYPTO_EcdsaPublicKey *z) { - static char buf[sizeof (struct GNUNET_CRYPTO_EccPublicKey) * 8]; + static char buf[sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) * 8]; char *end; - end = GNUNET_STRINGS_data_to_string ((const unsigned char *) z, - sizeof (struct GNUNET_CRYPTO_EccPublicKey), + end = GNUNET_STRINGS_data_to_string ((const unsigned char *) z, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), buf, sizeof (buf)); if (NULL == end) { @@ -136,7 +137,7 @@ GNUNET_NAMESTORE_records_get_size (unsigned int rd_count, GNUNET_assert ((ret + rd[i].data_size) >= ret); ret += rd[i].data_size; } - return ret; + return ret; } @@ -158,10 +159,15 @@ GNUNET_NAMESTORE_records_serialize (unsigned int rd_count, struct NetworkRecord rec; unsigned int i; size_t off; - + off = 0; for (i=0;irecord_type != b->record_type) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Record type %lu != %lu\n", a->record_type, b->record_type); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Record type %lu != %lu\n", a->record_type, b->record_type); return GNUNET_NO; } if ((a->expiration_time != b->expiration_time) && ((a->expiration_time != 0) && (b->expiration_time != 0))) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Expiration time %llu != %llu\n", a->expiration_time, b->expiration_time); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Expiration time %llu != %llu\n", + a->expiration_time, + b->expiration_time); return GNUNET_NO; } - if ((a->flags & GNUNET_NAMESTORE_RF_RCMP_FLAGS) + if ((a->flags & GNUNET_NAMESTORE_RF_RCMP_FLAGS) != (b->flags & GNUNET_NAMESTORE_RF_RCMP_FLAGS)) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Flags %lu (%lu) != %lu (%lu)\n", a->flags, - a->flags & GNUNET_NAMESTORE_RF_RCMP_FLAGS, b->flags, - b->flags & GNUNET_NAMESTORE_RF_RCMP_FLAGS); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Flags %lu (%lu) != %lu (%lu)\n", a->flags, + a->flags & GNUNET_NAMESTORE_RF_RCMP_FLAGS, b->flags, + b->flags & GNUNET_NAMESTORE_RF_RCMP_FLAGS); return GNUNET_NO; } if (a->data_size != b->data_size) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Data size %lu != %lu\n", a->data_size, b->data_size); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Data size %lu != %lu\n", + a->data_size, + b->data_size); return GNUNET_NO; } if (0 != memcmp (a->data, b->data, a->data_size)) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Data contents do not match\n"); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Data contents do not match\n"); return GNUNET_NO; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Records are equal\n"); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Records are equal\n"); return GNUNET_YES; } @@ -252,7 +262,7 @@ GNUNET_NAMESTORE_records_deserialize (size_t len, struct NetworkRecord rec; unsigned int i; size_t off; - + off = 0; for (i=0;i len) return GNUNET_SYSERR; dest[i].data = &src[off]; off += dest[i].data_size; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Deserialized record %u with flags %d and expiration time %llu\n", + i, + dest[i].flags, + (unsigned long long) dest[i].expiration_time); } - return GNUNET_OK; + return GNUNET_OK; } /** * Returns the expiration time of the given block of records. The block - * expiration time is the expiration time of the block with smallest + * expiration time is the expiration time of the record with smallest * expiration time. * * @param rd_count number of records given in @a rd @@ -284,7 +298,7 @@ GNUNET_NAMESTORE_records_deserialize (size_t len, * @return absolute expiration time */ struct GNUNET_TIME_Absolute -GNUNET_NAMESTORE_record_get_expiration_time (unsigned int rd_count, +GNUNET_NAMESTORE_record_get_expiration_time (unsigned int rd_count, const struct GNUNET_NAMESTORE_RecordData *rd) { unsigned int c; @@ -295,7 +309,7 @@ GNUNET_NAMESTORE_record_get_expiration_time (unsigned int rd_count, if (NULL == rd) return GNUNET_TIME_UNIT_ZERO_ABS; expire = GNUNET_TIME_UNIT_FOREVER_ABS; - for (c = 0; c < rd_count; c++) + for (c = 0; c < rd_count; c++) { if (0 != (rd[c].flags & GNUNET_NAMESTORE_RF_RELATIVE_EXPIRATION)) { @@ -306,8 +320,12 @@ GNUNET_NAMESTORE_record_get_expiration_time (unsigned int rd_count, { at.abs_value_us = rd[c].expiration_time; } - expire = GNUNET_TIME_absolute_min (at, expire); + expire = GNUNET_TIME_absolute_min (at, expire); } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Determined expiration time for block with %u records to be %s\n", + rd_count, + GNUNET_STRINGS_absolute_time_to_string (expire)); return expire; } @@ -321,21 +339,21 @@ GNUNET_NAMESTORE_record_get_expiration_time (unsigned int rd_count, * @param pub public key to use for KDF */ static void -derive_block_aes_key (struct GNUNET_CRYPTO_AesInitializationVector *iv, - struct GNUNET_CRYPTO_AesSessionKey *skey, +derive_block_aes_key (struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, + struct GNUNET_CRYPTO_SymmetricSessionKey *skey, const char *label, - const struct GNUNET_CRYPTO_EccPublicKey *pub) + const struct GNUNET_CRYPTO_EcdsaPublicKey *pub) { static const char ctx_key[] = "gns-aes-ctx-key"; static const char ctx_iv[] = "gns-aes-ctx-iv"; - GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_AesSessionKey), - pub, sizeof (struct GNUNET_CRYPTO_EccPublicKey), + GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), + pub, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), label, strlen (label), ctx_key, strlen (ctx_key), NULL, 0); - GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_AesInitializationVector), - pub, sizeof (struct GNUNET_CRYPTO_EccPublicKey), + GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector), + pub, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), label, strlen (label), ctx_iv, strlen (ctx_iv), NULL, 0); @@ -353,7 +371,7 @@ derive_block_aes_key (struct GNUNET_CRYPTO_AesInitializationVector *iv, * @return NULL on error (block too large) */ struct GNUNET_NAMESTORE_Block * -GNUNET_NAMESTORE_block_create (const struct GNUNET_CRYPTO_EccPrivateKey *key, +GNUNET_NAMESTORE_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_NAMESTORE_RecordData *rd, @@ -362,10 +380,10 @@ GNUNET_NAMESTORE_block_create (const struct GNUNET_CRYPTO_EccPrivateKey *key, size_t payload_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd); char payload[sizeof (uint32_t) + payload_len]; struct GNUNET_NAMESTORE_Block *block; - struct GNUNET_CRYPTO_EccPublicKey pkey; - struct GNUNET_CRYPTO_EccPrivateKey *dkey; - struct GNUNET_CRYPTO_AesInitializationVector iv; - struct GNUNET_CRYPTO_AesSessionKey skey; + struct GNUNET_CRYPTO_EcdsaPublicKey pkey; + struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; + struct GNUNET_CRYPTO_SymmetricInitializationVector iv; + struct GNUNET_CRYPTO_SymmetricSessionKey skey; uint32_t rd_count_nbo; if (payload_len > GNUNET_NAMESTORE_MAX_VALUE_SIZE) @@ -374,28 +392,28 @@ GNUNET_NAMESTORE_block_create (const struct GNUNET_CRYPTO_EccPrivateKey *key, memcpy (payload, &rd_count_nbo, sizeof (uint32_t)); GNUNET_assert (payload_len == GNUNET_NAMESTORE_records_serialize (rd_count, rd, - payload_len, &payload[sizeof (uint32_t)])); + payload_len, &payload[sizeof (uint32_t)])); block = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Block) + sizeof (uint32_t) + payload_len); - block->purpose.size = htonl (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); - dkey = GNUNET_CRYPTO_ecc_key_derive (key, + dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key, label, "gns"); - GNUNET_CRYPTO_ecc_key_get_public (dkey, + GNUNET_CRYPTO_ecdsa_key_get_public (dkey, &block->derived_key); - GNUNET_CRYPTO_ecc_key_get_public (key, + GNUNET_CRYPTO_ecdsa_key_get_public (key, &pkey); derive_block_aes_key (&iv, &skey, label, &pkey); GNUNET_break (payload_len + sizeof (uint32_t) == - GNUNET_CRYPTO_aes_encrypt (payload, payload_len + sizeof (uint32_t), + GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len + sizeof (uint32_t), &skey, &iv, &block[1])); if (GNUNET_OK != - GNUNET_CRYPTO_ecc_sign (dkey, + GNUNET_CRYPTO_ecdsa_sign (dkey, &block->purpose, &block->signature)) { @@ -418,8 +436,8 @@ GNUNET_NAMESTORE_block_create (const struct GNUNET_CRYPTO_EccPrivateKey *key, */ int GNUNET_NAMESTORE_block_verify (const struct GNUNET_NAMESTORE_Block *block) -{ - return GNUNET_CRYPTO_ecc_verify (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, +{ + return GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, &block->purpose, &block->signature, &block->derived_key); @@ -434,12 +452,12 @@ GNUNET_NAMESTORE_block_verify (const struct GNUNET_NAMESTORE_Block *block) * @param label the name for the records * @param proc function to call with the result * @param proc_cls closure for proc - * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block was + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the block was * not well-formed */ int GNUNET_NAMESTORE_block_decrypt (const struct GNUNET_NAMESTORE_Block *block, - const struct GNUNET_CRYPTO_EccPublicKey *zone_key, + const struct GNUNET_CRYPTO_EcdsaPublicKey *zone_key, const char *label, GNUNET_NAMESTORE_RecordCallback proc, void *proc_cls) @@ -447,11 +465,11 @@ GNUNET_NAMESTORE_block_decrypt (const struct GNUNET_NAMESTORE_Block *block, size_t payload_len = ntohl (block->purpose.size) - sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) - sizeof (struct GNUNET_TIME_AbsoluteNBO); - struct GNUNET_CRYPTO_AesInitializationVector iv; - struct GNUNET_CRYPTO_AesSessionKey skey; + struct GNUNET_CRYPTO_SymmetricInitializationVector iv; + struct GNUNET_CRYPTO_SymmetricSessionKey skey; if (ntohl (block->purpose.size) < - sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) - + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO)) { GNUNET_break_op (0); @@ -459,11 +477,11 @@ GNUNET_NAMESTORE_block_decrypt (const struct GNUNET_NAMESTORE_Block *block, } derive_block_aes_key (&iv, &skey, label, zone_key); { - char payload[payload_len]; + char payload[payload_len]; uint32_t rd_count; GNUNET_break (payload_len == - GNUNET_CRYPTO_aes_decrypt (&block[1], payload_len, + GNUNET_CRYPTO_symmetric_decrypt (&block[1], payload_len, &skey, &iv, payload)); memcpy (&rd_count, @@ -478,7 +496,7 @@ GNUNET_NAMESTORE_block_decrypt (const struct GNUNET_NAMESTORE_Block *block, } { struct GNUNET_NAMESTORE_RecordData rd[rd_count]; - + if (GNUNET_OK != GNUNET_NAMESTORE_records_deserialize (payload_len - sizeof (uint32_t), &payload[sizeof (uint32_t)], @@ -489,418 +507,16 @@ GNUNET_NAMESTORE_block_decrypt (const struct GNUNET_NAMESTORE_Block *block, return GNUNET_SYSERR; } if (NULL != proc) - proc (proc_cls, rd_count, rd); + proc (proc_cls, rd_count, (0 != rd_count) ? rd : NULL); } } return GNUNET_OK; } -/** - * Convert the 'value' of a record to a string. - * - * @param type type of the record - * @param data value in binary encoding - * @param data_size number of bytes in data - * @return NULL on error, otherwise human-readable representation of the value - */ -char * -GNUNET_NAMESTORE_value_to_string (uint32_t type, - const void *data, - size_t data_size) -{ - uint16_t mx_pref; - const struct GNUNET_TUN_DnsSoaRecord *soa; - const struct GNUNET_TUN_GnsVpnRecord *vpn; - const struct GNUNET_TUN_DnsSrvRecord *srv; - const struct GNUNET_TUN_DnsTlsaRecord *tlsa; - struct GNUNET_CRYPTO_HashAsciiEncoded s_peer; - const char *cdata; - char* vpn_str; - char* srv_str; - char* tlsa_str; - char* result; - const char* soa_rname; - const char* soa_mname; - char tmp[INET6_ADDRSTRLEN]; - - switch (type) - { - case 0: - return NULL; - case GNUNET_DNSPARSER_TYPE_A: - if (data_size != sizeof (struct in_addr)) - return NULL; - if (NULL == inet_ntop (AF_INET, data, tmp, sizeof (tmp))) - return NULL; - return GNUNET_strdup (tmp); - case GNUNET_DNSPARSER_TYPE_NS: - return GNUNET_strndup (data, data_size); - case GNUNET_DNSPARSER_TYPE_CNAME: - return GNUNET_strndup (data, data_size); - case GNUNET_DNSPARSER_TYPE_SOA: - if (data_size <= sizeof (struct GNUNET_TUN_DnsSoaRecord)) - return NULL; - soa = data; - soa_rname = (const char*) &soa[1]; - soa_mname = memchr (soa_rname, 0, data_size - sizeof (struct GNUNET_TUN_DnsSoaRecord) - 1); - if (NULL == soa_mname) - return NULL; - soa_mname++; - if (NULL == memchr (soa_mname, 0, - data_size - (sizeof (struct GNUNET_TUN_DnsSoaRecord) + strlen (soa_rname) + 1))) - return NULL; - GNUNET_asprintf (&result, - "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu", - soa_rname, soa_mname, - ntohl (soa->serial), - ntohl (soa->refresh), - ntohl (soa->retry), - ntohl (soa->expire), - ntohl (soa->minimum)); - return result; - case GNUNET_DNSPARSER_TYPE_PTR: - return GNUNET_strndup (data, data_size); - case GNUNET_DNSPARSER_TYPE_MX: - mx_pref = ntohs(*((uint16_t*)data)); - if (GNUNET_asprintf(&result, "%hu,%s", mx_pref, data+sizeof(uint16_t)) - != 0) - return result; - else - { - GNUNET_free (result); - return NULL; - } - case GNUNET_DNSPARSER_TYPE_TXT: - return GNUNET_strndup (data, data_size); - case GNUNET_DNSPARSER_TYPE_AAAA: - if (data_size != sizeof (struct in6_addr)) - return NULL; - if (NULL == inet_ntop (AF_INET6, data, tmp, sizeof (tmp))) - return NULL; - return GNUNET_strdup (tmp); - case GNUNET_NAMESTORE_TYPE_PKEY: - if (data_size != sizeof (struct GNUNET_CRYPTO_EccPublicKey)) - return NULL; - return GNUNET_CRYPTO_ecc_public_key_to_string (data); - case GNUNET_NAMESTORE_TYPE_PSEU: - return GNUNET_strndup (data, data_size); - case GNUNET_NAMESTORE_TYPE_LEHO: - return GNUNET_strndup (data, data_size); - case GNUNET_NAMESTORE_TYPE_VPN: - cdata = data; - if ( (data_size <= sizeof (struct GNUNET_TUN_GnsVpnRecord)) || - ('\0' != cdata[data_size - 1]) ) - return NULL; /* malformed */ - vpn = data; - GNUNET_CRYPTO_hash_to_enc (&vpn->peer.hashPubKey, &s_peer); - if (0 == GNUNET_asprintf (&vpn_str, "%u %s %s", - (unsigned int) ntohs (vpn->proto), - (const char*) &s_peer, - (const char*) &vpn[1])) - { - GNUNET_free (vpn_str); - return NULL; - } - return vpn_str; - case GNUNET_DNSPARSER_TYPE_SRV: - cdata = data; - if ( (data_size <= sizeof (struct GNUNET_TUN_DnsSrvRecord)) || - ('\0' != cdata[data_size - 1]) ) - return NULL; /* malformed */ - srv = data; - - if (0 == GNUNET_asprintf (&srv_str, - "%d %d %d %s", - ntohs (srv->prio), - ntohs (srv->weight), - ntohs (srv->port), - (const char *)&srv[1])) - { - GNUNET_free (srv_str); - return NULL; - } - return srv_str; - case GNUNET_DNSPARSER_TYPE_TLSA: - cdata = data; - if ( (data_size <= sizeof (struct GNUNET_TUN_DnsTlsaRecord)) || - ('\0' != cdata[data_size - 1]) ) - return NULL; /* malformed */ - tlsa = data; - if (0 == GNUNET_asprintf (&tlsa_str, - "%c %c %c %s", - tlsa->usage, - tlsa->selector, - tlsa->matching_type, - (const char *) &tlsa[1])) - { - GNUNET_free (tlsa_str); - return NULL; - } - return tlsa_str; - default: - GNUNET_break (0); - } - GNUNET_break (0); // not implemented - return NULL; -} - - -/** - * Convert human-readable version of a 'value' of a record to the binary - * representation. - * - * @param type type of the record - * @param s human-readable string - * @param data set to value in binary encoding (will be allocated) - * @param data_size set to number of bytes in data - * @return GNUNET_OK on success - */ -int -GNUNET_NAMESTORE_string_to_value (uint32_t type, - const char *s, - void **data, - size_t *data_size) -{ - struct in_addr value_a; - struct in6_addr value_aaaa; - struct GNUNET_CRYPTO_EccPublicKey pkey; - struct GNUNET_TUN_DnsSoaRecord *soa; - struct GNUNET_TUN_GnsVpnRecord *vpn; - struct GNUNET_TUN_DnsTlsaRecord *tlsa; - char result[253 + 1]; - char soa_rname[253 + 1]; - char soa_mname[253 + 1]; - char s_peer[103 + 1]; - char s_serv[253 + 1]; - unsigned int soa_serial; - unsigned int soa_refresh; - unsigned int soa_retry; - unsigned int soa_expire; - unsigned int soa_min; - uint16_t mx_pref; - uint16_t mx_pref_n; - unsigned int proto; - - if (NULL == s) - return GNUNET_SYSERR; - switch (type) - { - case 0: - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Unsupported record type %d\n"), - (int) type); - return GNUNET_SYSERR; - case GNUNET_DNSPARSER_TYPE_A: - if (1 != inet_pton (AF_INET, s, &value_a)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Unable to parse IPv4 address `%s'\n"), - s); - return GNUNET_SYSERR; - } - *data = GNUNET_malloc (sizeof (struct in_addr)); - memcpy (*data, &value_a, sizeof (value_a)); - *data_size = sizeof (value_a); - return GNUNET_OK; - case GNUNET_DNSPARSER_TYPE_NS: - *data = GNUNET_strdup (s); - *data_size = strlen (s) + 1; - return GNUNET_OK; - case GNUNET_DNSPARSER_TYPE_CNAME: - *data = GNUNET_strdup (s); - *data_size = strlen (s) + 1; - return GNUNET_OK; - case GNUNET_DNSPARSER_TYPE_SOA: - if (7 != SSCANF (s, - "rname=%253s mname=%253s %u,%u,%u,%u,%u", - soa_rname, soa_mname, - &soa_serial, &soa_refresh, &soa_retry, &soa_expire, &soa_min)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Unable to parse SOA record `%s'\n"), - s); - return GNUNET_SYSERR; - } - *data_size = sizeof (struct GNUNET_TUN_DnsSoaRecord)+strlen(soa_rname)+strlen(soa_mname)+2; - *data = GNUNET_malloc (*data_size); - soa = (struct GNUNET_TUN_DnsSoaRecord*)*data; - soa->serial = htonl(soa_serial); - soa->refresh = htonl(soa_refresh); - soa->retry = htonl(soa_retry); - soa->expire = htonl(soa_expire); - soa->minimum = htonl(soa_min); - strcpy((char*)&soa[1], soa_rname); - strcpy((char*)&soa[1]+strlen(*data)+1, soa_mname); - return GNUNET_OK; - case GNUNET_DNSPARSER_TYPE_PTR: - *data = GNUNET_strdup (s); - *data_size = strlen (s); - return GNUNET_OK; - case GNUNET_DNSPARSER_TYPE_MX: - if (2 != SSCANF(s, "%hu,%253s", &mx_pref, result)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Unable to parse MX record `%s'\n"), - s); - return GNUNET_SYSERR; - } - *data_size = sizeof (uint16_t)+strlen(result)+1; - *data = GNUNET_malloc (*data_size); - mx_pref_n = htons(mx_pref); - memcpy(*data, &mx_pref_n, sizeof (uint16_t)); - strcpy((*data)+sizeof (uint16_t), result); - return GNUNET_OK; - case GNUNET_DNSPARSER_TYPE_TXT: - *data = GNUNET_strdup (s); - *data_size = strlen (s); - return GNUNET_OK; - case GNUNET_DNSPARSER_TYPE_AAAA: - if (1 != inet_pton (AF_INET6, s, &value_aaaa)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Unable to parse IPv6 address `%s'\n"), - s); - return GNUNET_SYSERR; - } - *data = GNUNET_malloc (sizeof (struct in6_addr)); - *data_size = sizeof (struct in6_addr); - memcpy (*data, &value_aaaa, sizeof (value_aaaa)); - return GNUNET_OK; - case GNUNET_NAMESTORE_TYPE_PKEY: - if (GNUNET_OK != - GNUNET_CRYPTO_ecc_public_key_from_string (s, strlen (s), &pkey)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Unable to parse PKEY record `%s'\n"), - s); - return GNUNET_SYSERR; - } - *data = GNUNET_new (struct GNUNET_CRYPTO_EccPublicKey); - memcpy (*data, &pkey, sizeof (pkey)); - *data_size = sizeof (struct GNUNET_CRYPTO_EccPublicKey); - return GNUNET_OK; - case GNUNET_NAMESTORE_TYPE_PSEU: - *data = GNUNET_strdup (s); - *data_size = strlen (s); - return GNUNET_OK; - case GNUNET_NAMESTORE_TYPE_LEHO: - *data = GNUNET_strdup (s); - *data_size = strlen (s); - return GNUNET_OK; - case GNUNET_NAMESTORE_TYPE_VPN: - if (3 != SSCANF (s,"%u %103s %253s", - &proto, s_peer, s_serv)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Unable to parse VPN record string `%s'\n"), - s); - return GNUNET_SYSERR; - } - *data_size = sizeof (struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1; - *data = vpn = GNUNET_malloc (*data_size); - if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_peer, - &vpn->peer.hashPubKey)) - { - GNUNET_free (vpn); - *data_size = 0; - return GNUNET_SYSERR; - } - vpn->proto = htons ((uint16_t) proto); - strcpy ((char*)&vpn[1], s_serv); - return GNUNET_OK; - case GNUNET_DNSPARSER_TYPE_TLSA: - *data_size = sizeof (struct GNUNET_TUN_DnsTlsaRecord) + strlen (s) - 6; - *data = tlsa = GNUNET_malloc (*data_size); - if (4 != SSCANF (s, "%c %c %c %s", - &tlsa->usage, - &tlsa->selector, - &tlsa->matching_type, - (char*)&tlsa[1])) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Unable to parse TLSA record string `%s'\n"), - s); - *data_size = 0; - GNUNET_free (tlsa); - return GNUNET_SYSERR; - } - return GNUNET_OK; - default: - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Unsupported record type %d\n"), - (int) type); - return GNUNET_SYSERR; - } -} - - -/** - * Mapping of record type numbers to human-readable - * record type names. - */ -static struct { - const char *name; - uint32_t number; -} name_map[] = { - { "A", GNUNET_DNSPARSER_TYPE_A }, - { "NS", GNUNET_DNSPARSER_TYPE_NS }, - { "CNAME", GNUNET_DNSPARSER_TYPE_CNAME }, - { "SOA", GNUNET_DNSPARSER_TYPE_SOA }, - { "PTR", GNUNET_DNSPARSER_TYPE_PTR }, - { "MX", GNUNET_DNSPARSER_TYPE_MX }, - { "TXT", GNUNET_DNSPARSER_TYPE_TXT }, - { "AAAA", GNUNET_DNSPARSER_TYPE_AAAA }, - { "PKEY", GNUNET_NAMESTORE_TYPE_PKEY }, - { "PSEU", GNUNET_NAMESTORE_TYPE_PSEU }, - { "LEHO", GNUNET_NAMESTORE_TYPE_LEHO }, - { "VPN", GNUNET_NAMESTORE_TYPE_VPN }, - { "TLSA", GNUNET_DNSPARSER_TYPE_TLSA }, - { NULL, UINT32_MAX } -}; - - -/** - * Convert a type name (i.e. "AAAA") to the corresponding number. - * - * @param typename name to convert - * @return corresponding number, UINT32_MAX on error - */ -uint32_t -GNUNET_NAMESTORE_typename_to_number (const char *typename) -{ - unsigned int i; - - i=0; - while ( (name_map[i].name != NULL) && - (0 != strcasecmp (typename, name_map[i].name)) ) - i++; - return name_map[i].number; -} - - -/** - * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A") - * - * @param type number of a type to convert - * @return corresponding typestring, NULL on error - */ -const char * -GNUNET_NAMESTORE_number_to_typename (uint32_t type) -{ - unsigned int i; - - i=0; - while ( (name_map[i].name != NULL) && - (type != name_map[i].number) ) - i++; - return name_map[i].name; -} - - /** * Test if a given record is expired. - * + * * @return #GNUNET_YES if the record is expired, * #GNUNET_NO if not */ @@ -918,40 +534,105 @@ GNUNET_NAMESTORE_is_expired (const struct GNUNET_NAMESTORE_RecordData *rd) /** * Calculate the DHT query for a given @a label in a given @a zone. - * + * * @param zone private key of the zone * @param label label of the record * @param query hash to use for the query */ void -GNUNET_NAMESTORE_query_from_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *zone, +GNUNET_NAMESTORE_query_from_private_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, struct GNUNET_HashCode *query) { - struct GNUNET_CRYPTO_EccPublicKey pub; + struct GNUNET_CRYPTO_EcdsaPublicKey pub; - GNUNET_CRYPTO_ecc_key_get_public (zone, &pub); + GNUNET_CRYPTO_ecdsa_key_get_public (zone, &pub); GNUNET_NAMESTORE_query_from_public_key (&pub, label, query); } /** * Calculate the DHT query for a given @a label in a given @a zone. - * + * * @param pub public key of the zone * @param label label of the record * @param query hash to use for the query */ void -GNUNET_NAMESTORE_query_from_public_key (const struct GNUNET_CRYPTO_EccPublicKey *pub, +GNUNET_NAMESTORE_query_from_public_key (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, const char *label, struct GNUNET_HashCode *query) { - struct GNUNET_CRYPTO_EccPublicKey pd; + struct GNUNET_CRYPTO_EcdsaPublicKey pd; - GNUNET_CRYPTO_ecc_public_key_derive (pub, label, "gns", &pd); + GNUNET_CRYPTO_ecdsa_public_key_derive (pub, label, "gns", &pd); GNUNET_CRYPTO_hash (&pd, sizeof (pd), query); } +/** + * Convert public key to the respective absolute domain name in the + * ".zkey" pTLD. + * This is one of the very few calls in the entire API that is + * NOT reentrant! + * + * @param pkey a public key with a point on the eliptic curve + * @return string "X.zkey" where X is the public + * key in an encoding suitable for DNS labels. + */ +const char * +GNUNET_NAMESTORE_pkey_to_zkey (const struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) +{ + static char ret[128]; + char *pkeys; + + pkeys = GNUNET_CRYPTO_ecdsa_public_key_to_string (pkey); + GNUNET_snprintf (ret, + sizeof (ret), + "%s.zkey", + pkeys); + GNUNET_free (pkeys); + return ret; +} + + +/** + * Convert an absolute domain name in the ".zkey" pTLD to the + * respective public key. + * + * @param zkey string "X.zkey" where X is the coordinates of the public + * key in an encoding suitable for DNS labels. + * @param pkey set to a public key on the eliptic curve + * @return #GNUNET_SYSERR if @a zkey has the wrong syntax + */ +int +GNUNET_NAMESTORE_zkey_to_pkey (const char *zkey, + struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) +{ + char *cpy; + char *dot; + const char *x; + + cpy = GNUNET_strdup (zkey); + x = cpy; + if (NULL == (dot = strchr (x, (int) '.'))) + goto error; + *dot = '\0'; + if (0 != strcasecmp (dot + 1, + "zkey")) + goto error; + + if (GNUNET_OK != + GNUNET_CRYPTO_ecdsa_public_key_from_string (x, + strlen (x), + pkey)) + goto error; + GNUNET_free (cpy); + return GNUNET_OK; + error: + GNUNET_free (cpy); + return GNUNET_SYSERR; +} + + /* end of namestore_common.c */