This file is part of GNUnet.
Copyright (C) 2009-2013, 2016 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.
+ 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/>.
- 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.
+ SPDX-License-Identifier: AGPL3.0-or-later
*/
#include "gnunet_util_lib.h"
#include "gnunet_constants.h"
#include "gnunet_credential_service.h"
-
-GNUNET_NETWORK_STRUCT_BEGIN
-
-struct DelegationRecordData
-{
- /**
- * Subject key
- */
- struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
-
- /**
- * Subject attributes
- */
- uint32_t subject_attribute_len GNUNET_PACKED;
-};
-
-
-struct ChainEntry
-{
- /**
- * Issuer key
- */
- struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key;
-
- /**
- * Subject key
- */
- struct GNUNET_CRYPTO_EcdsaPublicKey subject_key;
-
- /**
- * Issuer attributes
- */
- uint32_t issuer_attribute_len GNUNET_PACKED;
-
- /**
- * Subject attributes
- */
- uint32_t subject_attribute_len GNUNET_PACKED;
-};
-
-GNUNET_NETWORK_STRUCT_END
-
+#include "gnunet_signatures.h"
+#include "credential.h"
/**
* Calculate how many bytes we will need to serialize
- * the given delegation chain and credential
+ * the given delegation chain
*
- * @param d_count number of delegation chain entries
- * @param dd array of #GNUNET_CREDENTIAL_Delegation
- * @param cd a #GNUNET_CREDENTIAL_Credential
+ * @param ds_count number of delegation chain entries
+ * @param dsr array of #GNUNET_CREDENTIAL_DelegationSet
* @return the required size to serialize
*/
size_t
GNUNET_CREDENTIAL_delegation_set_get_size (unsigned int ds_count,
- const struct GNUNET_CREDENTIAL_DelegationSetRecord *dsr)
+ const struct GNUNET_CREDENTIAL_DelegationSet *dsr)
{
unsigned int i;
size_t ret;
* Serizalize the given delegation chain entries and credential
*
* @param d_count number of delegation chain entries
- * @param dd array of #GNUNET_CREDENTIAL_Delegation
- * @param cd a #GNUNET_CREDENTIAL_Credential
+ * @param dsr array of #GNUNET_CREDENTIAL_DelegationSet
* @param dest_size size of the destination
* @param dest where to store the result
* @return the size of the data, -1 on failure
*/
ssize_t
GNUNET_CREDENTIAL_delegation_set_serialize (unsigned int d_count,
- const struct GNUNET_CREDENTIAL_DelegationSetRecord *dsr,
+ const struct GNUNET_CREDENTIAL_DelegationSet *dsr,
size_t dest_size,
char *dest)
{
* @param len size of the serialized delegation chain and cred
* @param src the serialized data
* @param d_count the number of delegation chain entries
- * @param dd where to put the delegation chain entries
- * @param cd where to put the credential data
+ * @param dsr where to put the delegation chain entries
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
GNUNET_CREDENTIAL_delegation_set_deserialize (size_t len,
const char *src,
unsigned int d_count,
- struct GNUNET_CREDENTIAL_DelegationSetRecord *dsr)
+ struct GNUNET_CREDENTIAL_DelegationSet *dsr)
{
struct DelegationRecordData rec;
unsigned int i;
dsr[i].subject_attribute_len = ntohl ((uint32_t) rec.subject_attribute_len);
if (off + dsr[i].subject_attribute_len > len)
return GNUNET_SYSERR;
- dsr[i].subject_attribute = &src[off];
+ dsr[i].subject_attribute = (char*)&src[off];
off += dsr[i].subject_attribute_len;
}
return GNUNET_OK;
}
+
+
+/**
+ * Calculate how many bytes we will need to serialize
+ * the credentials
+ *
+ * @param c_count number of credential entries
+ * @param cd a #GNUNET_CREDENTIAL_Credential
+ * @return the required size to serialize
+ */
+size_t
+GNUNET_CREDENTIAL_credentials_get_size (unsigned int c_count,
+ const struct GNUNET_CREDENTIAL_Credential *cd)
+{
+ unsigned int i;
+ size_t ret;
+
+ ret = sizeof (struct CredentialEntry) * (c_count);
+
+ for (i=0; i<c_count;i++)
+ {
+ GNUNET_assert ((ret + cd[i].issuer_attribute_len) >= ret);
+ ret += cd[i].issuer_attribute_len;
+ }
+ return ret;
+}
+/**
+ * Serizalize the given credentials
+ *
+ * @param c_count number of credential entries
+ * @param cd a #GNUNET_CREDENTIAL_Credential
+ * @param dest_size size of the destination
+ * @param dest where to store the result
+ * @return the size of the data, -1 on failure
+ */
+ssize_t
+GNUNET_CREDENTIAL_credentials_serialize (unsigned int c_count,
+ const struct GNUNET_CREDENTIAL_Credential *cd,
+ size_t dest_size,
+ char *dest)
+{
+ struct CredentialEntry c_rec;
+ unsigned int i;
+ size_t off;
+
+ off = 0;
+ for (i=0;i<c_count;i++)
+ {
+ c_rec.issuer_attribute_len = htonl ((uint32_t) cd[i].issuer_attribute_len);
+ c_rec.issuer_key = cd[i].issuer_key;
+ c_rec.subject_key = cd[i].subject_key;
+ c_rec.signature = cd[i].signature;
+ c_rec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
+ c_rec.purpose.size = htonl ((sizeof (struct CredentialEntry) + cd[i].issuer_attribute_len) - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
+ c_rec.expiration = GNUNET_htonll (cd[i].expiration.abs_value_us);
+ if (off + sizeof (c_rec) > dest_size)
+ return -1;
+ GNUNET_memcpy (&dest[off],
+ &c_rec,
+ sizeof (c_rec));
+ off += sizeof (c_rec);
+ if (off + cd[i].issuer_attribute_len > dest_size)
+ return -1;
+ GNUNET_memcpy (&dest[off],
+ cd[i].issuer_attribute,
+ cd[i].issuer_attribute_len);
+ off += cd[i].issuer_attribute_len;
+ }
+
+ return off;
+}
+
+
+
+/**
+ * Deserialize the given destination
+ *
+ * @param len size of the serialized creds
+ * @param src the serialized data
+ * @param c_count the number of credential entries
+ * @param cd where to put the credential data
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+int
+GNUNET_CREDENTIAL_credentials_deserialize (size_t len,
+ const char *src,
+ unsigned int c_count,
+ struct GNUNET_CREDENTIAL_Credential *cd)
+{
+ struct CredentialEntry c_rec;
+ unsigned int i;
+ size_t off;
+
+ off = 0;
+ for (i=0;i<c_count;i++)
+ {
+ if (off + sizeof (c_rec) > len)
+ return GNUNET_SYSERR;
+ GNUNET_memcpy (&c_rec, &src[off], sizeof (c_rec));
+ cd[i].issuer_attribute_len = ntohl ((uint32_t) c_rec.issuer_attribute_len);
+ cd[i].issuer_key = c_rec.issuer_key;
+ cd[i].subject_key = c_rec.subject_key;
+ cd[i].signature = c_rec.signature;
+ cd[i].expiration.abs_value_us = GNUNET_ntohll(c_rec.expiration);
+ off += sizeof (c_rec);
+ if (off + cd[i].issuer_attribute_len > len)
+ return GNUNET_SYSERR;
+ cd[i].issuer_attribute = &src[off];
+ off += cd[i].issuer_attribute_len;
+ }
+ return GNUNET_OK;
+}
+
+
+
/**
* Calculate how many bytes we will need to serialize
* the given delegation chain and credential
*
* @param d_count number of delegation chain entries
* @param dd array of #GNUNET_CREDENTIAL_Delegation
+ * @param c_count number of credential entries
* @param cd a #GNUNET_CREDENTIAL_Credential
* @return the required size to serialize
*/
size_t
GNUNET_CREDENTIAL_delegation_chain_get_size (unsigned int d_count,
const struct GNUNET_CREDENTIAL_Delegation *dd,
+ unsigned int c_count,
const struct GNUNET_CREDENTIAL_Credential *cd)
{
unsigned int i;
size_t ret;
- ret = sizeof (struct ChainEntry) * (d_count + 1);
+ ret = sizeof (struct ChainEntry) * (d_count);
for (i=0; i<d_count;i++)
{
dd[i].subject_attribute_len) >= ret);
ret += dd[i].issuer_attribute_len + dd[i].subject_attribute_len;
}
- GNUNET_assert ((ret + cd->issuer_attribute_len) >= ret);
- ret += cd->issuer_attribute_len;
- return ret;
+ return ret+GNUNET_CREDENTIAL_credentials_get_size(c_count, cd);
}
/**
*
* @param d_count number of delegation chain entries
* @param dd array of #GNUNET_CREDENTIAL_Delegation
+ * @param c_count number of credential entries
* @param cd a #GNUNET_CREDENTIAL_Credential
* @param dest_size size of the destination
* @param dest where to store the result
ssize_t
GNUNET_CREDENTIAL_delegation_chain_serialize (unsigned int d_count,
const struct GNUNET_CREDENTIAL_Delegation *dd,
+ unsigned int c_count,
const struct GNUNET_CREDENTIAL_Credential *cd,
size_t dest_size,
char *dest)
dd[i].subject_attribute_len);
off += dd[i].subject_attribute_len;
}
- rec.issuer_attribute_len = htonl ((uint32_t) cd->issuer_attribute_len);
- rec.subject_attribute_len = htonl (0);
- rec.issuer_key = cd->issuer_key;
- if (off + sizeof (rec) > dest_size)
- return -1;
- GNUNET_memcpy (&dest[off],
- &rec,
- sizeof (rec));
- off += sizeof (rec);
- if (off + cd->issuer_attribute_len > dest_size)
- return -1;
- GNUNET_memcpy (&dest[off],
- cd->issuer_attribute,
- cd->issuer_attribute_len);
- off += cd->issuer_attribute_len;
-
- return off;
+ return off+GNUNET_CREDENTIAL_credentials_serialize (c_count,
+ cd,
+ dest_size-off,
+ &dest[off]);
}
* @param src the serialized data
* @param d_count the number of delegation chain entries
* @param dd where to put the delegation chain entries
+ * @param c_count the number of credential entries
* @param cd where to put the credential data
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
const char *src,
unsigned int d_count,
struct GNUNET_CREDENTIAL_Delegation *dd,
+ unsigned int c_count,
struct GNUNET_CREDENTIAL_Credential *cd)
{
struct ChainEntry rec;
dd[i].subject_attribute = &src[off];
off += dd[i].subject_attribute_len;
}
- if (off + sizeof (rec) > len)
- return GNUNET_SYSERR;
- GNUNET_memcpy (&rec, &src[off], sizeof (rec));
- cd->issuer_attribute_len = ntohl ((uint32_t) rec.issuer_attribute_len);
- cd->issuer_key = rec.issuer_key;
- cd->subject_key = rec.subject_key;
- off += sizeof (rec);
- if (off + cd->issuer_attribute_len > len)
- return GNUNET_SYSERR;
- cd->issuer_attribute = &src[off];
- off += cd->issuer_attribute_len;
- return GNUNET_OK;
+ return GNUNET_CREDENTIAL_credentials_deserialize (len-off,
+ &src[off],
+ c_count,
+ cd);
+}
+int
+GNUNET_CREDENTIAL_credential_serialize (struct GNUNET_CREDENTIAL_Credential *cred,
+ char **data)
+{
+ size_t size;
+ struct CredentialEntry *cdata;
+
+ size = sizeof (struct CredentialEntry) + strlen (cred->issuer_attribute) + 1;
+ *data = GNUNET_malloc (size);
+ cdata = (struct CredentialEntry*)*data;
+ cdata->subject_key = cred->subject_key;
+ cdata->issuer_key = cred->issuer_key;
+ cdata->expiration = GNUNET_htonll (cred->expiration.abs_value_us);
+ cdata->signature = cred->signature;
+ cdata->issuer_attribute_len = htonl (strlen (cred->issuer_attribute) + 1);
+ cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
+ cdata->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
+ GNUNET_memcpy (&cdata[1],
+ cred->issuer_attribute,
+ strlen (cred->issuer_attribute));
+
+ if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL,
+ &cdata->purpose,
+ &cdata->signature,
+ &cdata->issuer_key))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Invalid credential\n");
+ //return NULL;
+ }
+ return size;
+}
+
+struct GNUNET_CREDENTIAL_Credential*
+GNUNET_CREDENTIAL_credential_deserialize (const char* data,
+ size_t data_size)
+{
+ struct GNUNET_CREDENTIAL_Credential *cred;
+ struct CredentialEntry *cdata;
+ char *issuer_attribute;
+
+ if (data_size < sizeof (struct CredentialEntry))
+ return NULL;
+ cdata = (struct CredentialEntry*)data;
+ if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL,
+ &cdata->purpose,
+ &cdata->signature,
+ &cdata->issuer_key))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Invalid credential\n");
+ //return NULL;
+ }
+ issuer_attribute = (char*)&cdata[1];
+
+ cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) + ntohl(cdata->issuer_attribute_len));
+
+ cred->issuer_key = cdata->issuer_key;
+ cred->subject_key = cdata->subject_key;
+ GNUNET_memcpy (&cred[1],
+ issuer_attribute,
+ ntohl (cdata->issuer_attribute_len));
+ cred->signature = cdata->signature;
+ cred->issuer_attribute = (char*)&cred[1];
+ cred->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration);
+ return cred;
}
+
/* end of credential_serialization.c */