This file is part of GNUnet
Copyright (C) 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
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- 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., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file credential/plugin_gnsrecord_credential.c
* @brief gnsrecord plugin to provide the API for CREDENTIAL records
- * @author Adnan Husain
+ * @author Martin Schanzenbach
*/
#include "platform.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_credential_service.h"
#include "gnunet_gnsrecord_plugin.h"
-
+#include "gnunet_signatures.h"
+#include "credential_serialization.h"
+#include "credential_misc.h"
/**
* Convert the 'value' of a record to a string.
switch (type)
{
- case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
+ case GNUNET_GNSRECORD_TYPE_ATTRIBUTE:
{
- struct GNUNET_CREDENTIAL_RecordData cred;
- char *cred_str;
+ struct GNUNET_CREDENTIAL_DelegationRecord sets;
+ char *attr_str;
char *subject_pkey;
- char *issuer_pkey;
- uint32_t cf; // Credential flags
- uint32_t mdd; // Max delegation depth
- if (data_size < sizeof (struct GNUNET_CREDENTIAL_RecordData))
- return NULL; /* malformed */
- memcpy (&cred,
- data,
- sizeof (cred));
- cdata = data;
- subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.subject_key);
- issuer_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.issuer_key);
- cf = ntohl (cred.credential_flags);
- mdd = ntohl (cred.max_delegation_depth);
-
- GNUNET_asprintf (&cred_str,
- "%s %s %u %u %s",
- subject_pkey,
- issuer_pkey,
- (unsigned int) cf,
- (unsigned int) mdd,
- &cdata[sizeof (cred)]);
+ char *tmp_str;
+ int i;
+ if (data_size < sizeof (struct GNUNET_CREDENTIAL_DelegationRecord))
+ return NULL; /* malformed */
+ GNUNET_memcpy (&sets,
+ data,
+ sizeof (sets));
+ cdata = data;
+ struct GNUNET_CREDENTIAL_DelegationSet set[ntohl(sets.set_count)];
+ if (GNUNET_OK != GNUNET_CREDENTIAL_delegation_set_deserialize (GNUNET_ntohll (sets.data_size),
+ &cdata[sizeof (sets)],
+ ntohl (sets.set_count),
+ set))
+ return NULL;
+
+ for (i=0;i<ntohl(sets.set_count);i++)
+ {
+ subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&set[i].subject_key);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%d len attr\n", set[i].subject_attribute_len);
+ if (0 == set[i].subject_attribute_len)
+ {
+ if (0 == i)
+ {
+ GNUNET_asprintf (&attr_str,
+ "%s",
+ subject_pkey);
+ } else {
+ GNUNET_asprintf (&tmp_str,
+ "%s,%s",
+ attr_str,
+ subject_pkey);
+ GNUNET_free (attr_str);
+ attr_str = tmp_str;
+ }
+ } else {
+ if (0 == i)
+ {
+ GNUNET_asprintf (&attr_str,
+ "%s %s",
+ subject_pkey,
+ set[i].subject_attribute);
+ } else {
+ GNUNET_asprintf (&tmp_str,
+ "%s,%s %s",
+ attr_str,
+ subject_pkey,
+ set[i].subject_attribute);
+ GNUNET_free (attr_str);
+ attr_str = tmp_str;
+ }
+ }
GNUNET_free (subject_pkey);
- GNUNET_free (issuer_pkey);
-
-
-
- return cred_str;
}
- default:
- return NULL;
+ return attr_str;
+ }
+ case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
+ {
+ struct GNUNET_CREDENTIAL_Credential *cred;
+ char *cred_str;
+
+ cred = GNUNET_CREDENTIAL_credential_deserialize (data,
+ data_size);
+ cred_str = GNUNET_CREDENTIAL_credential_to_string (cred);
+ GNUNET_free (cred);
+ return cred_str;
+ }
+ case GNUNET_GNSRECORD_TYPE_POLICY:
+ {
+ return GNUNET_strndup (data,data_size);
+ }
+ default:
+ return NULL;
}
}
*/
static int
credential_string_to_value (void *cls,
- uint32_t type,
- const char *s,
- void **data,
- size_t *data_size)
+ uint32_t type,
+ const char *s,
+ void **data,
+ size_t *data_size)
{
if (NULL == s)
return GNUNET_SYSERR;
switch (type)
{
- case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
- {
- struct GNUNET_CREDENTIAL_RecordData *cred;
- unsigned int cf; // credential flags
- unsigned int mdd; // max delegation depth
-
- size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
- if (enclen % 5 > 0)
- enclen += 5 - enclen % 5;
- enclen /= 5; /* 260/5 = 52 */
- char subject_pkey[enclen + 1];
- char issuer_pkey[enclen + 1];
- char name[253 + 1];
-
- if (5 != SSCANF (s,
- "%52s %52s %u %u %253s",
- subject_pkey,
- issuer_pkey,
- &cf,
- &mdd,
- name))
+ case GNUNET_GNSRECORD_TYPE_ATTRIBUTE:
+ {
+ struct GNUNET_CREDENTIAL_DelegationRecord *sets;
+ char attr_str[253 + 1];
+ char subject_pkey[52 + 1];
+ char *token;
+ char *tmp_str;
+ int matches = 0;
+ int entries;
+ size_t tmp_data_size;
+ int i;
+
+ tmp_str = GNUNET_strdup (s);
+ token = strtok (tmp_str, ",");
+ entries = 0;
+ tmp_data_size = 0;
+ *data_size = sizeof (struct GNUNET_CREDENTIAL_DelegationRecord);
+ while (NULL != token)
+ {
+ matches = SSCANF (token,
+ "%s %s",
+ subject_pkey,
+ attr_str);
+ if (0 == matches)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Unable to parse ATTR record string `%s'\n"),
+ s);
+ GNUNET_free (tmp_str);
+ return GNUNET_SYSERR;
+ }
+ if (1 == matches) {
+ tmp_data_size += sizeof (struct GNUNET_CREDENTIAL_DelegationRecordSet);
+ } else if (2 == matches) {
+ tmp_data_size += sizeof (struct GNUNET_CREDENTIAL_DelegationRecordSet) + strlen (attr_str) + 1;
+ }
+ entries++;
+ token = strtok (NULL, ",");
+ }
+ GNUNET_free (tmp_str);
+ tmp_str = GNUNET_strdup (s);
+ token = strtok (tmp_str, ",");
+ if (NULL == token)
{
+ GNUNET_free (tmp_str);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _("Unable to parse CRED record string `%s'\n"),
- s);
+ "Malformed string %s\n", s);
return GNUNET_SYSERR;
}
- *data_size = sizeof (struct GNUNET_CREDENTIAL_RecordData) + strlen (name) + 1;
- *data = cred = GNUNET_malloc (*data_size);
- GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey,
- strlen (subject_pkey),
- &cred->subject_key);
- GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey,
- strlen (issuer_pkey),
- &cred->issuer_key);
- cred->credential_flags = htonl (cf);
- cred->max_delegation_depth = htonl (mdd);
- GNUNET_memcpy (&cred[1],
- name,
- strlen (name));
-
+ struct GNUNET_CREDENTIAL_DelegationSet set[entries];
+ for (i=0;i<entries;i++)
+ {
+ matches = SSCANF (token,
+ "%s %s",
+ subject_pkey,
+ attr_str);
+ GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey,
+ strlen (subject_pkey),
+ &set[i].subject_key);
+ if (2 == matches) {
+ set[i].subject_attribute_len = strlen (attr_str) + 1;
+ set[i].subject_attribute = GNUNET_strdup (attr_str);
+ }
+ token = strtok (NULL , ",");
+ }
+ tmp_data_size = GNUNET_CREDENTIAL_delegation_set_get_size (entries,
+ set);
- *data = GNUNET_strdup (s);
- *data_size = strlen (s);
- return GNUNET_OK;
- }
- default:
- return GNUNET_SYSERR;
+ if (-1 == tmp_data_size)
+ {
+ GNUNET_free (tmp_str);
+ return GNUNET_SYSERR;
+ }
+ *data_size += tmp_data_size;
+ *data = sets = GNUNET_malloc (*data_size);
+ GNUNET_CREDENTIAL_delegation_set_serialize (entries,
+ set,
+ tmp_data_size,
+ (char*)&sets[1]);
+ for (i=0;i<entries;i++)
+ {
+ if (0 != set[i].subject_attribute_len)
+ GNUNET_free ((char*)set[i].subject_attribute);
+ }
+ sets->set_count = htonl (entries);
+ sets->data_size = GNUNET_htonll (tmp_data_size);
+
+ GNUNET_free (tmp_str);
+ return GNUNET_OK;
+ }
+ case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
+ {
+ struct GNUNET_CREDENTIAL_Credential *cred;
+ cred = GNUNET_CREDENTIAL_credential_from_string (s);
+
+ *data_size = GNUNET_CREDENTIAL_credential_serialize (cred,
+ (char**)data);
+ return GNUNET_OK;
+ }
+ case GNUNET_GNSRECORD_TYPE_POLICY:
+ {
+ *data_size = strlen (s);
+ *data = GNUNET_strdup (s);
+ return GNUNET_OK;
+ }
+ default:
+ return GNUNET_SYSERR;
}
}
uint32_t number;
} name_map[] = {
{ "CRED", GNUNET_GNSRECORD_TYPE_CREDENTIAL },
+ { "ATTR", GNUNET_GNSRECORD_TYPE_ATTRIBUTE },
+ { "POLICY", GNUNET_GNSRECORD_TYPE_POLICY },
{ NULL, UINT32_MAX }
};
*/
static uint32_t
credential_typename_to_number (void *cls,
- const char *gns_typename)
+ const char *gns_typename)
{
unsigned int i;
i=0;
while ( (name_map[i].name != NULL) &&
- (0 != strcasecmp (gns_typename, name_map[i].name)) )
+ (0 != strcasecmp (gns_typename, name_map[i].name)) )
i++;
return name_map[i].number;
}
*/
static const char *
credential_number_to_typename (void *cls,
- uint32_t type)
+ uint32_t type)
{
unsigned int i;
i=0;
while ( (name_map[i].name != NULL) &&
- (type != name_map[i].number) )
+ (type != name_map[i].number) )
i++;
return name_map[i].name;
}