Added RecognTags.

- items are described in serialiser.
	- util functions in util/rsrecogn.cc are used to manipulate it.
	- these are attached to GxsIds, with new interface fns.
	- Associated Signing Code is in a separate program.

Other Tweaks.
	- Added RsMemCache::erase()
	- Added RsTlvStringSetRef 
	- Fix for rsturtleitem (already added to trunk).
	- Formatting and debugging.

Status: There is a bug in RsGenExchange::updateGroup which prevents full testing, 
The basic generation, parsing and validation functions have been tested and are ok.
The processing as part of p3IdService still needs to be fully debugged.





git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs_finale@6854 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2013-10-20 09:43:30 +00:00
parent 19d7faa572
commit fc58861447
19 changed files with 2645 additions and 101 deletions

View File

@ -7,7 +7,7 @@ CONFIG += test_voip
#GXS Stuff.
# This should be disabled for releases until further notice.
#CONFIG += gxs debug
CONFIG += gxs debug
# Beware: All data of the stripped services are lost
DEFINES *= PQI_DISABLE_TUNNEL
@ -387,6 +387,7 @@ HEADERS += serialiser/rsbaseitems.h \
serialiser/rstlvbanlist.h \
serialiser/rsbanlistitems.h \
serialiser/rsbwctrlitems.h \
serialiser/rsgxsrecognitems.h \
serialiser/rstunnelitems.h
HEADERS += services/p3channels.h \
@ -430,6 +431,7 @@ HEADERS += util/folderiterator.h \
util/pugiconfig.h \
util/rsmemcache.h \
util/rstickevent.h \
util/rsrecogn.h \
SOURCES += dbase/cachestrapper.cc \
dbase/fimonitor.cc \
@ -529,6 +531,7 @@ SOURCES += serialiser/rsbaseitems.cc \
serialiser/rstlvbanlist.cc \
serialiser/rsbanlistitems.cc \
serialiser/rsbwctrlitems.cc \
serialiser/rsgxsrecognitems.cc \
serialiser/rstunnelitems.cc
SOURCES += services/p3channels.cc \
@ -571,6 +574,7 @@ SOURCES += util/folderiterator.cc \
util/rsaes.cc \
util/rsrandom.cc \
util/rstickevent.cc \
util/rsrecogn.cc \
upnp_miniupnpc {

View File

@ -47,7 +47,7 @@ public:
mGroupStatus = 0;
mCircleType = 0;
//mPublishTs = 0;
mPublishTs = 0;
}
void operator =(const RsGxsGrpMetaData& rGxsMeta);

View File

@ -55,6 +55,8 @@ extern RsIdentity *rsIdentity;
#define RSID_RELATION_OTHER 0x0008
#define RSID_RELATION_UNKNOWN 0x0010
#define RSRECOGN_MAX_TAGINFO 5
std::string rsIdTypeToString(uint32_t idtype);
class RsGxsIdGroup
@ -82,6 +84,9 @@ class RsGxsIdGroup
std::string mPgpIdHash;
std::string mPgpIdSign; // Need a signature as proof - otherwise anyone could add others Hashes.
// Recognition Strings. MAX# defined above.
std::list<std::string> mRecognTags;
// Not Serialised - for GUI's benefit.
bool mPgpKnown;
std::string mPgpId;
@ -163,6 +168,36 @@ class RsIdOpinion
typedef std::string RsGxsId; // TMP. =>
class RsRecognTag
{
public:
RsRecognTag(uint16_t tc, uint16_t tt, bool v)
:tag_class(tc), tag_type(tt), valid(v) { return; }
uint16_t tag_class;
uint16_t tag_type;
bool valid;
};
class RsRecognTagDetails
{
public:
RsRecognTagDetails()
:valid_from(0), valid_to(0), tag_class(0), tag_type(0),
is_valid(false), is_pending(false) { return; }
time_t valid_from;
time_t valid_to;
uint16_t tag_class;
uint16_t tag_type;
std::string signer;
bool is_valid;
bool is_pending;
};
class RsIdentityDetails
{
public:
@ -181,6 +216,9 @@ class RsIdentityDetails
bool mPgpKnown;
std::string mPgpId;
// Recogn details.
std::list<RsRecognTag> mRecognTags;
// reputation details.
double mOpinion;
double mReputation;
@ -230,6 +268,13 @@ virtual bool getOwnIds(std::list<RsGxsId> &ownIds) = 0;
virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion) = 0;
virtual bool createIdentity(uint32_t& token, RsIdentityParameters &params) = 0;
virtual bool updateIdentity(uint32_t& token, RsGxsIdGroup &group) = 0;
virtual bool parseRecognTag(const RsGxsId &id, const std::string &nickname,
const std::string &tag, RsRecognTagDetails &details) = 0;
virtual bool getRecognTagRequest(const RsGxsId &id, const std::string &comment,
uint16_t tag_class, uint16_t tag_type, std::string &tag) = 0;
// Specific RsIdentity Functions....
/* Specific Service Data */
/* We expose these initially for testing / GUI purposes.

View File

@ -122,20 +122,30 @@ void RsGxsIdGroupItem::clear()
group.mPgpIdHash.clear();
group.mPgpIdSign.clear();
group.mRecognTags.clear();
group.mPgpKnown = false;
group.mPgpId.clear();
}
std::ostream& RsGxsIdGroupItem::print(std::ostream& out, uint16_t indent)
{
printRsItemBase(out, "RsGxsIdGroupItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "MetaData: " << meta << std::endl;
printIndent(out, int_Indent);
out << "PgpIdHash: " << group.mPgpIdHash << std::endl;
printIndent(out, int_Indent);
out << "PgpIdSign: " << group.mPgpIdSign << std::endl;
printIndent(out, int_Indent);
out << "RecognTags:" << std::endl;
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, group.mRecognTags);
set.print(out, int_Indent + 2);
printRsItemEnd(out ,"RsGxsIdGroupItem", indent);
return out;
@ -151,6 +161,9 @@ uint32_t RsGxsIdSerialiser::sizeGxsIdGroupItem(RsGxsIdGroupItem *item)
s += GetTlvStringSize(group.mPgpIdHash);
s += GetTlvStringSize(group.mPgpIdSign);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, item->group.mRecognTags);
s += set.TlvSize();
return s;
}
@ -181,6 +194,9 @@ bool RsGxsIdSerialiser::serialiseGxsIdGroupItem(RsGxsIdGroupItem *item, void *da
/* GxsIdGroupItem */
ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mPgpIdHash);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mPgpIdSign);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, item->group.mRecognTags);
ok &= set.SetTlv(data, tlvsize, &offset);
if(offset != tlvsize)
{
@ -238,6 +254,10 @@ RsGxsIdGroupItem* RsGxsIdSerialiser::deserialiseGxsIdGroupItem(void *data, uint3
ok &= GetTlvString(data, rssize, &offset, 1, item->group.mPgpIdHash);
ok &= GetTlvString(data, rssize, &offset, 1, item->group.mPgpIdSign);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, item->group.mRecognTags);
ok &= set.GetTlv(data, rssize, &offset);
if (offset != rssize)
{

View File

@ -52,7 +52,8 @@
std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta)
{
out << "[ GroupId: " << meta.mGroupId << " Name: " << meta.mGroupName << " ]";
out << "[ GroupId: " << meta.mGroupId << " Name: " << meta.mGroupName;
out << " PublishTs: " << meta.mPublishTs << " ]";
return out;
}

View File

@ -0,0 +1,600 @@
/*
* libretroshare/src/serialiser: rsgxsrecogitems.cc
*
* RetroShare Serialiser.
*
* Copyright 2013-2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "serialiser/rsbaseserial.h"
#include "serialiser/rsgxsrecognitems.h"
/***
#define RSSERIAL_DEBUG 1
***/
#include <iostream>
/*************************************************************************/
RsGxsRecognReqItem::~RsGxsRecognReqItem()
{
return;
}
void RsGxsRecognReqItem::clear()
{
issued_at = 0;
period = 0;
tag_class = 0;
tag_type = 0;
identity.clear();
nickname.clear();
comment.clear();
sign.TlvClear();
}
std::ostream &RsGxsRecognReqItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsRecognReqItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "issued_at: " << issued_at << std::endl;
printIndent(out, int_Indent);
out << "period: " << period << std::endl;
printIndent(out, int_Indent);
out << "tag_class: " << tag_class << std::endl;
printIndent(out, int_Indent);
out << "tag_type: " << tag_type << std::endl;
printIndent(out, int_Indent);
out << "identity: " << identity << std::endl;
printIndent(out, int_Indent);
out << "nickname: " << nickname << std::endl;
printIndent(out, int_Indent);
out << "comment: " << comment << std::endl;
printIndent(out, int_Indent);
out << "signature: " << std::endl;
sign.print(out, int_Indent + 2);
printRsItemEnd(out, "RsGxsRecognReqItem", indent);
return out;
}
uint32_t RsGxsRecognSerialiser::sizeReq(RsGxsRecognReqItem *item)
{
uint32_t s = 8; /* header */
s += 4; // issued_at;
s += 4; // period;
s += 2; // tag_class;
s += 2; // tag_type;
s += GetTlvStringSize(item->identity);
s += GetTlvStringSize(item->nickname);
s += GetTlvStringSize(item->comment);
s += item->sign.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsGxsRecognSerialiser::serialiseReq(RsGxsRecognReqItem *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeReq(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseReq() Header: " << ok << std::endl;
std::cerr << "RsGxsRecognSerialiser::serialiseReq() Size: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, item->issued_at);
ok &= setRawUInt32(data, tlvsize, &offset, item->period);
ok &= setRawUInt16(data, tlvsize, &offset, item->tag_class);
ok &= setRawUInt16(data, tlvsize, &offset, item->tag_type);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->identity);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->nickname);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->comment);
ok &= item->sign.SetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseReq() Size Error! " << std::endl;
#endif
}
return ok;
}
RsGxsRecognReqItem *RsGxsRecognSerialiser::deserialiseReq(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t tlvsize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_TYPE_GXS_RECOGN != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_RECOGN_REQ != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < tlvsize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = tlvsize;
bool ok = true;
/* ready to load */
RsGxsRecognReqItem *item = new RsGxsRecognReqItem();
item->clear();
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= getRawUInt32(data, tlvsize, &offset, &(item->issued_at));
ok &= getRawUInt32(data, tlvsize, &offset, &(item->period));
ok &= getRawUInt16(data, tlvsize, &offset, &(item->tag_class));
ok &= getRawUInt16(data, tlvsize, &offset, &(item->tag_type));
ok &= GetTlvString(data, tlvsize, &offset, 1, item->identity);
ok &= GetTlvString(data, tlvsize, &offset, 1, item->nickname);
ok &= GetTlvString(data, tlvsize, &offset, 1, item->comment);
ok &= item->sign.GetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
/*************************************************************************/
RsGxsRecognTagItem::~RsGxsRecognTagItem()
{
return;
}
void RsGxsRecognTagItem::clear()
{
valid_from = 0;
valid_to = 0;
tag_class = 0;
tag_type = 0;
identity.clear();
nickname.clear();
sign.TlvClear();
}
std::ostream &RsGxsRecognTagItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsRecognTagItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "valid_from: " << valid_from << std::endl;
printIndent(out, int_Indent);
out << "valid_to: " << valid_to << std::endl;
printIndent(out, int_Indent);
out << "tag_class: " << tag_class << std::endl;
printIndent(out, int_Indent);
out << "tag_type: " << tag_type << std::endl;
printIndent(out, int_Indent);
out << "identity: " << identity << std::endl;
printIndent(out, int_Indent);
out << "nickname: " << nickname << std::endl;
printIndent(out, int_Indent);
out << "signature: " << std::endl;
sign.print(out, int_Indent + 2);
printRsItemEnd(out, "RsGxsRecognTagItem", indent);
return out;
}
uint32_t RsGxsRecognSerialiser::sizeTag(RsGxsRecognTagItem *item)
{
uint32_t s = 8; /* header */
s += 4; // valid_from;
s += 4; // valid_to;
s += 2; // tag_class;
s += 2; // tag_type;
s += GetTlvStringSize(item->identity);
s += GetTlvStringSize(item->nickname);
s += item->sign.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsGxsRecognSerialiser::serialiseTag(RsGxsRecognTagItem *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeTag(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseTag() Header: " << ok << std::endl;
std::cerr << "RsGxsRecognSerialiser::serialiseTag() Size: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, item->valid_from);
ok &= setRawUInt32(data, tlvsize, &offset, item->valid_to);
ok &= setRawUInt16(data, tlvsize, &offset, item->tag_class);
ok &= setRawUInt16(data, tlvsize, &offset, item->tag_type);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->identity);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->nickname);
ok &= item->sign.SetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseTag() Size Error! " << std::endl;
#endif
}
return ok;
}
RsGxsRecognTagItem *RsGxsRecognSerialiser::deserialiseTag(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t tlvsize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_TYPE_GXS_RECOGN != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_RECOGN_TAG != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < tlvsize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = tlvsize;
bool ok = true;
/* ready to load */
RsGxsRecognTagItem *item = new RsGxsRecognTagItem();
item->clear();
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= getRawUInt32(data, tlvsize, &offset, &(item->valid_from));
ok &= getRawUInt32(data, tlvsize, &offset, &(item->valid_to));
ok &= getRawUInt16(data, tlvsize, &offset, &(item->tag_class));
ok &= getRawUInt16(data, tlvsize, &offset, &(item->tag_type));
ok &= GetTlvString(data, tlvsize, &offset, 1, item->identity);
ok &= GetTlvString(data, tlvsize, &offset, 1, item->nickname);
ok &= item->sign.GetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
/*************************************************************************/
RsGxsRecognSignerItem::~RsGxsRecognSignerItem()
{
return;
}
void RsGxsRecognSignerItem::clear()
{
signing_classes.TlvClear();
key.TlvClear();
sign.TlvClear();
}
std::ostream &RsGxsRecognSignerItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsRecognSignerItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "signing_classes: " << std::endl;
signing_classes.print(out, int_Indent + 2);
printIndent(out, int_Indent);
out << "key: " << std::endl;
key.print(out, int_Indent + 2);
printIndent(out, int_Indent);
out << "signature: " << std::endl;
sign.print(out, int_Indent + 2);
printRsItemEnd(out, "RsGxsRecognSignerItem", indent);
return out;
}
uint32_t RsGxsRecognSerialiser::sizeSigner(RsGxsRecognSignerItem *item)
{
uint32_t s = 8; /* header */
s += item->signing_classes.TlvSize();
s += item->key.TlvSize();
s += item->sign.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsGxsRecognSerialiser::serialiseSigner(RsGxsRecognSignerItem *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeSigner(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseSigner() Header: " << ok << std::endl;
std::cerr << "RsGxsRecognSerialiser::serialiseSigner() Size: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= item->signing_classes.SetTlv(data, tlvsize, &offset);
ok &= item->key.SetTlv(data, tlvsize, &offset);
ok &= item->sign.SetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseSigner() Size Error! " << std::endl;
#endif
}
return ok;
}
RsGxsRecognSignerItem *RsGxsRecognSerialiser::deserialiseSigner(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t tlvsize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_TYPE_GXS_RECOGN != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_RECOGN_SIGNER != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < tlvsize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = tlvsize;
bool ok = true;
/* ready to load */
RsGxsRecognSignerItem *item = new RsGxsRecognSignerItem();
item->clear();
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= item->signing_classes.GetTlv(data, tlvsize, &offset);
ok &= item->key.GetTlv(data, tlvsize, &offset);
ok &= item->sign.GetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
/*************************************************************************/
uint32_t RsGxsRecognSerialiser::size(RsItem *i)
{
RsGxsRecognReqItem *rqi;
RsGxsRecognTagItem *rti;
RsGxsRecognSignerItem *rsi;
if (NULL != (rqi = dynamic_cast<RsGxsRecognReqItem *>(i)))
{
return sizeReq(rqi);
}
if (NULL != (rti = dynamic_cast<RsGxsRecognTagItem *>(i)))
{
return sizeTag(rti);
}
if (NULL != (rsi = dynamic_cast<RsGxsRecognSignerItem *>(i)))
{
return sizeSigner(rsi);
}
return 0;
}
bool RsGxsRecognSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
{
RsGxsRecognReqItem *rri;
RsGxsRecognTagItem *rti;
RsGxsRecognSignerItem *rsi;
if (NULL != (rri = dynamic_cast<RsGxsRecognReqItem *>(i)))
{
return serialiseReq(rri, data, pktsize);
}
if (NULL != (rti = dynamic_cast<RsGxsRecognTagItem *>(i)))
{
return serialiseTag(rti, data, pktsize);
}
if (NULL != (rsi = dynamic_cast<RsGxsRecognSignerItem *>(i)))
{
return serialiseSigner(rsi, data, pktsize);
}
return false;
}
RsItem *RsGxsRecognSerialiser::deserialise(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_TYPE_GXS_RECOGN != getRsItemService(rstype)))
{
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_RECOGN_REQ:
return deserialiseReq(data, pktsize);
break;
case RS_PKT_SUBTYPE_RECOGN_TAG:
return deserialiseTag(data, pktsize);
break;
case RS_PKT_SUBTYPE_RECOGN_SIGNER:
return deserialiseSigner(data, pktsize);
break;
default:
return NULL;
break;
}
}
/*************************************************************************/

View File

@ -0,0 +1,152 @@
#ifndef RS_GXS_RECOG_ITEMS_H
#define RS_GXS_RECOG_ITEMS_H
/*
* libretroshare/src/serialiser: rsgxsrecogitems.h
*
* RetroShare Serialiser.
*
* Copyright 2013-2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include <map>
#include "serialiser/rsserviceids.h"
#include "serialiser/rsserial.h"
#include "serialiser/rstlvbase.h"
#include "serialiser/rstlvtypes.h"
#include "serialiser/rstlvkeys.h"
/**************************************************************************/
#define RS_PKT_SUBTYPE_RECOGN_REQ 0x01
#define RS_PKT_SUBTYPE_RECOGN_TAG 0x02
#define RS_PKT_SUBTYPE_RECOGN_SIGNER 0x03
class RsGxsRecognReqItem: public RsItem
{
public:
RsGxsRecognReqItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN,
RS_PKT_SUBTYPE_RECOGN_REQ)
{
setPriorityLevel(QOS_PRIORITY_DEFAULT);
return;
}
virtual ~RsGxsRecognReqItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint32_t issued_at;
uint32_t period;
uint16_t tag_class;
uint16_t tag_type;
std::string identity;
std::string nickname;
std::string comment;
RsTlvKeySignature sign;
};
class RsGxsRecognTagItem: public RsItem
{
public:
RsGxsRecognTagItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN,
RS_PKT_SUBTYPE_RECOGN_TAG)
{
setPriorityLevel(QOS_PRIORITY_DEFAULT);
return;
}
virtual ~RsGxsRecognTagItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint32_t valid_from;
uint32_t valid_to;
uint16_t tag_class;
uint16_t tag_type;
std::string identity;
std::string nickname;
RsTlvKeySignature sign;
};
class RsGxsRecognSignerItem: public RsItem
{
public:
RsGxsRecognSignerItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN,
RS_PKT_SUBTYPE_RECOGN_SIGNER)
{
setPriorityLevel(QOS_PRIORITY_DEFAULT);
return;
}
virtual ~RsGxsRecognSignerItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
RsTlvServiceIdSet signing_classes;
RsTlvSecurityKey key; // has from->to, and flags.
RsTlvKeySignature sign;
};
class RsGxsRecognSerialiser: public RsSerialType
{
public:
RsGxsRecognSerialiser()
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN)
{ return; }
virtual ~RsGxsRecognSerialiser()
{ return; }
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
private:
virtual uint32_t sizeReq(RsGxsRecognReqItem *);
virtual bool serialiseReq(RsGxsRecognReqItem *item, void *data, uint32_t *size);
virtual RsGxsRecognReqItem *deserialiseReq(void *data, uint32_t *size);
virtual uint32_t sizeTag(RsGxsRecognTagItem *);
virtual bool serialiseTag(RsGxsRecognTagItem *item, void *data, uint32_t *size);
virtual RsGxsRecognTagItem *deserialiseTag(void *data, uint32_t *size);
virtual uint32_t sizeSigner(RsGxsRecognSignerItem *);
virtual bool serialiseSigner(RsGxsRecognSignerItem *item, void *data, uint32_t *size);
virtual RsGxsRecognSignerItem *deserialiseSigner(void *data, uint32_t *size);
};
/**************************************************************************/
#endif /* RS_GXS_RECOGN_ITEMS_H */

View File

@ -149,6 +149,8 @@ const uint16_t RS_SERVICE_GXSV3_TYPE_POSTED = 0xf326;
const uint16_t RS_SERVICE_GXSV3_TYPE_CHANNELS = 0xf327;
const uint16_t RS_SERVICE_GXSV3_TYPE_GXSCIRCLE = 0xf328;
const uint16_t RS_SERVICE_TYPE_GXS_RECOGN = 0xf331;
/***************** IDS ALLOCATED FOR PLUGINS ******************/
const uint16_t RS_SERVICE_TYPE_PLUGIN_ARADO_TEST_ID1 = 0xf401;

View File

@ -201,6 +201,7 @@ const uint16_t TLV_TYPE_WKEYVALUESET = 0x1013;
const uint16_t TLV_TYPE_STRINGSET = 0x1020; /* dummy non-existant */
const uint16_t TLV_TYPE_PEERSET = 0x1021;
const uint16_t TLV_TYPE_HASHSET = 0x1022;
const uint16_t TLV_TYPE_RECOGNSET = 0x1023;
const uint16_t TLV_TYPE_SERVICESET = 0x1030;
const uint16_t TLV_TYPE_SECURITYKEY = 0x1040;

View File

@ -428,6 +428,165 @@ std::ostream &RsTlvStringSet::printHex(std::ostream &out, uint16_t indent)
}
/************************************* String Set Ref ************************************/
/* This is exactly the same as StringSet, but it uses an alternative list.
*/
RsTlvStringSetRef::RsTlvStringSetRef(uint16_t type, std::list<std::string> &refids)
:mType(type), ids(refids)
{
}
void RsTlvStringSetRef::TlvClear()
{
ids.clear();
}
uint32_t RsTlvStringSetRef::TlvSize()
{
uint32_t s = TLV_HEADER_SIZE; /* header */
/* determine the total size of ids strings in list */
std::list<std::string>::iterator it;
for(it = ids.begin(); it != ids.end() ; ++it)
{
if (it->length() > 0)
s += GetTlvStringSize(*it);
}
return s;
}
bool RsTlvStringSetRef::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
/* must check sizes */
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
return false; /* not enough space */
bool ok = true;
/* start at data[offset] */
ok &= SetTlvBase(data, tlvend, offset, mType , tlvsize);
/* determine the total size of ids strings in list */
std::list<std::string>::iterator it;
for(it = ids.begin(); it != ids.end() ; ++it)
{
if (it->length() > 0)
ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, *it);
}
return ok;
}
bool RsTlvStringSetRef::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend) /* check size */
return false; /* not enough space */
if (tlvtype != mType) /* check type */
return false;
bool ok = true;
/* ready to load */
TlvClear();
/* skip the header */
(*offset) += TLV_HEADER_SIZE;
/* while there is TLV */
while((*offset) + 2 < tlvend)
{
/* get the next type */
uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
if (tlvsubtype == TLV_TYPE_STR_GENID)
{
std::string newIds;
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, newIds);
if(ok)
{
ids.push_back(newIds);
}
}
else
{
/* Step past unknown TLV TYPE */
ok &= SkipUnknownTlv(data, tlvend, offset);
}
if (!ok)
{
break;
}
}
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvPeerIdSetRef::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}
/// print to screen RsTlvStringSet contents
std::ostream &RsTlvStringSetRef::print(std::ostream &out, uint16_t indent)
{
printBase(out, "RsTlvStringSetRef", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "type:" << mType;
out << std::endl;
std::list<std::string>::iterator it;
for(it = ids.begin(); it != ids.end() ; ++it)
{
printIndent(out, int_Indent);
out << "id:" << *it;
out << std::endl;
}
printEnd(out, "RsTlvStringSetRef", indent);
return out;
}
/************************************* Service Id Set ************************************/
void RsTlvServiceIdSet::TlvClear()

View File

@ -137,6 +137,22 @@ virtual std::ostream &print(std::ostream &out, uint16_t indent);
};
class RsTlvStringSetRef: public RsTlvItem
{
public:
RsTlvStringSetRef(uint16_t type, std::list<std::string> &refids);
virtual ~RsTlvStringSetRef() { return; }
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
virtual std::ostream &print(std::ostream &out, uint16_t indent);
uint16_t mType;
std::list<std::string> &ids; /* Mandatory */
};
/**** MORE TLV *****
*
* File Items/Data.

View File

@ -217,7 +217,7 @@ bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group)
bool p3GxsForums::updateGroup(uint32_t &token, RsGxsGroupUpdateMeta& meta, RsGxsForumGroup &group)
{
std::cerr << "p3GxsForums::createGroup()" << std::endl;
std::cerr << "p3GxsForums::updateGroup()" << std::endl;
if(meta.getGroupId().empty())
return false;

File diff suppressed because it is too large Load Diff

View File

@ -38,9 +38,12 @@
#include "util/rsmemcache.h"
#include "util/rstickevent.h"
#include "util/rsrecogn.h"
#include "pqi/authgpg.h"
#include "serialiser/rsgxsrecognitems.h"
/*
* Identity Service
*
@ -73,6 +76,27 @@ virtual std::string save() const;
std::string pgpId;
};
class SSGxsIdRecognTags: public SSBit
{
public:
SSGxsIdRecognTags()
:tagFlags(0), publishTs(0), lastCheckTs(0) { return; }
virtual bool load(const std::string &input);
virtual std::string save() const;
void setTags(bool processed, bool pending, uint32_t flags);
bool tagsProcessed() const; // have we processed?
bool tagsPending() const; // should we reprocess?
bool tagValid(int i) const;
time_t publishTs;
time_t lastCheckTs;
uint32_t tagFlags;
};
class SSGxsIdScore: public SSBit
{
public:
@ -113,11 +137,14 @@ virtual std::string save() const;
// pgphash status
SSGxsIdPgp pgp;
// recogTags.
SSGxsIdRecognTags recogntags;
// reputation score.
SSGxsIdScore score;
SSGxsIdCumulator opinion;
SSGxsIdCumulator reputation;
};
#define ID_LOCAL_STATUS_FULL_CALC_FLAG 0x00010000
@ -133,10 +160,14 @@ class RsGxsIdCache
{
public:
RsGxsIdCache();
RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey);
RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey,
const std::list<RsRecognTag> &tagList);
void updateServiceString(std::string serviceString);
time_t mPublishTs;
std::list<RsRecognTag> mRecognTags; // Only partially validated.
RsIdentityDetails details;
RsTlvSecurityKey pubkey;
};
@ -175,6 +206,7 @@ virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsIdOpinion> &opin
// These are local - and not exposed via RsIdentity.
virtual bool createGroup(uint32_t& token, RsGxsIdGroup &group);
virtual bool updateGroup(uint32_t& token, RsGxsIdGroup &group);
virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion);
/**************** RsIdentity External Interface.
@ -197,6 +229,13 @@ virtual bool getOwnIds(std::list<RsGxsId> &ownIds);
virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion);
virtual bool createIdentity(uint32_t& token, RsIdentityParameters &params);
virtual bool updateIdentity(uint32_t& token, RsGxsIdGroup &group);
virtual bool parseRecognTag(const RsGxsId &id, const std::string &nickname,
const std::string &tag, RsRecognTagDetails &details);
virtual bool getRecognTagRequest(const RsGxsId &id, const std::string &comment,
uint16_t tag_class, uint16_t tag_type, std::string &tag);
/**************** RsGixs Implementation
* Notes:
@ -303,6 +342,32 @@ virtual void handle_event(uint32_t event_type, const std::string &elabel);
std::map<PGPIdType, PGPFingerprintType> mPgpFingerprintMap;
std::list<RsGxsIdGroup> mGroupsToProcess;
/************************************************************************
* recogn processing.
*
*/
bool recogn_start();
bool recogn_handlerequest(uint32_t token);
bool recogn_process();
// helper functions.
bool recogn_extract_taginfo(const RsGxsIdGroupItem *item, std::list<RsGxsRecognTagItem *> &tagItems);
bool cache_process_recogntaginfo(const RsGxsIdGroupItem *item, std::list<RsRecognTag> &tagList);
bool recogn_checktag(const RsGxsId &id, const std::string &nickname, RsGxsRecognTagItem *item, bool doSignCheck, bool &isPending);
void loadRecognKeys();
/* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */
bool checkRecognSignature_locked(std::string encoded, RSA &key, std::string signature);
bool getRecognKey_locked(std::string signer, RSA &key);
std::list<RsGxsGroupId> mRecognGroupIds;
std::list<RsGxsIdGroupItem *> mRecognGroupsToProcess;
std::map<std::string, RsGxsRecognSignerItem *> mRecognSignKeys;
std::map<std::string, uint32_t> mRecognOldSignKeys;
/************************************************************************
* Below is the background task for processing opinions => reputations
*

View File

@ -40,7 +40,6 @@
/****
* #define POSTED_DEBUG 1
****/
#define POSTED_DEBUG 1
RsPosted *rsPosted = NULL;

View File

@ -544,7 +544,7 @@ RsTurtleGenericDataItem::RsTurtleGenericDataItem(void *data,uint32_t pktsize)
if(data_bytes != NULL)
{
memcpy(data_bytes,data+offset,data_size) ;
memcpy(data_bytes,(void *)((uint8_t *)data+offset),data_size) ;
offset += data_size ;
}
else
@ -585,7 +585,7 @@ bool RsTurtleGenericDataItem::serialize(void *data,uint32_t& pktsize)
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
ok &= setRawUInt32(data, tlvsize, &offset, data_size);
memcpy(data+offset,data_bytes,data_size) ;
memcpy((void *)((uint8_t *)data+offset),data_bytes,data_size) ;
offset += data_size ;
if (offset != tlvsize)

View File

@ -65,6 +65,7 @@ template<class Key, class Value> class RsMemCache
bool fetch(const Key &key, Value &data);
Value &ref(const Key &key); // like map[] installs empty one if non-existent.
bool store(const Key &key, const Value &data);
bool erase(const Key &key); // clean up cache.
bool resize(); // should be called periodically to cleanup old entries.
@ -169,6 +170,47 @@ template<class Key, class Value> bool RsMemCache<Key, Value>::fetch(const Key &k
}
template<class Key, class Value> bool RsMemCache<Key, Value>::erase(const Key &key)
{
#ifdef DEBUG_RSMEMCACHE
std::cerr << "RsMemCache::erase()";
std::cerr << std::endl;
printStats(std::cerr);
#endif // DEBUG_RSMEMCACHE
typename std::map<Key, cache_data>::iterator it;
it = mDataMap.find(key);
if (it == mDataMap.end())
{
#ifdef DEBUG_RSMEMCACHE
std::cerr << "RsMemCache::erase(" << key << ") false";
std::cerr << std::endl;
#endif // DEBUG_RSMEMCACHE
mStats_accessmiss++;
return false;
}
#ifdef DEBUG_RSMEMCACHE
std::cerr << "RsMemCache::erase(" << key << ") OK";
std::cerr << std::endl;
#endif // DEBUG_RSMEMCACHE
/* get timestamps */
time_t old_ts = it->second.ts;
time_t new_ts = 0;
// remove from lru.
mDataMap.erase(it);
update_lrumap(key, old_ts, new_ts);
mStats_access++;
return true;
}
template<class Key, class Value> Value &RsMemCache<Key, Value>::ref(const Key &key)
{
#ifdef DEBUG_RSMEMCACHE

View File

@ -0,0 +1,640 @@
/*
* libretroshare/src/util: rsrecogn.cc
*
* RetroShare Utilities
*
* Copyright 2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include "pqi/pqi_base.h"
#include "util/rsrecogn.h"
#include "util/radix64.h"
#include "util/rsstring.h"
#include "gxs/gxssecurity.h"
/***
* #define DEBUG_RECOGN 1
***/
#define DEBUG_RECOGN 1
static std::string RecognKey = "MIICCgKCAgEA4/i2fy+zR27/H8fzphM8mR/Nz+yXjMJTtqKlCvEMQlyk7lKzDbKifNjGSiAXjSv3b9TRgMtje7hfEhs3//Oeu4KsCf6sz17aj2StBF579IdJTSUPDwq6jCsZ6NDEYpG8xz3FVV+Ac8q5Vpr/+jdg23ta09zq4aV8VIdIsroVOmZQqjwPcmQK57iWHd538i/XBtc2rnzbYq5bprnmtAKdx55gXVXDfALa0s6yR0HYvCaWguMEJhMIKWfi/9PEgLgwF9OmRwywc2TU/EdvYJo8fYHLfGk0PnYBuL1oSnn3cwAAef02W2JyCzQ84g30tLSUk+hC1LLi+iYj3x7IRR4q7Rlf/FYv/Q5fvjRtPT9eqM6fKyJ9ZO4NjlrSPFGydNbgABzP6WMhBzFjUkEKS27bGmr8Qxdj3Zp0TvR2IkyM6oM+6YknuM4RndUEgC1ZxtoIhugMjm6HdMQmoaHNK3kXewgQB90HHqzKA/J1gok3NcqL8Yls5g0LHepVHsU4cuaIqQr5yr665ZTLU2oqn1HIdkgydBYYUt6G3eWJKXYRbDhWPthGo/HK+W+iw6cTGWxzlCZS40EU9efxz4mDuhow67jOe704lBP3kiYXu05Y5uspaYnuvrvIwaRWBYapyR9UmKktnY8xJYrZvrcZgCovAbiodTzWeYg37xjFfGgYNI8CAwEAAQ==";
#define NUM_RECOGN_SIGN_KEYS 3
static std::string RecognSigningKeys[NUM_RECOGN_SIGN_KEYS] =
{
"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",
};
EVP_PKEY *RsRecogn::loadMasterKey()
{
/* load master signing key */
size_t keylen;
char *keyptr;
Radix64::decode(RecognKey, keyptr, keylen);
const unsigned char *keyptr2 = (const unsigned char *) keyptr;
long keylen2 = keylen;
RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr2), keylen2);
delete []keyptr;
if (!rsakey)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadMasterKeys() failed rsakey load";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return NULL;
}
EVP_PKEY *signKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(signKey, rsakey);
return signKey;
}
bool RsRecogn::loadSigningKeys(std::map<std::string, RsGxsRecognSignerItem *> &signMap)
{
EVP_PKEY *signKey = loadMasterKey();
RsGxsRecognSerialiser recognSerialiser;
if (!signKey)
{
std::cerr << "RsRecogn::loadSigningKeys() missing Master Key";
return false;
}
time_t now = time(NULL);
for(int i = 0; i < NUM_RECOGN_SIGN_KEYS; i++)
{
char *signerbuf;
size_t len;
Radix64::decode(RecognSigningKeys[i], signerbuf, len);
uint32_t pktsize = len;
RsItem *pktitem = recognSerialiser.deserialise(signerbuf, &pktsize);
RsGxsRecognSignerItem *item = dynamic_cast<RsGxsRecognSignerItem *>(pktitem);
delete []signerbuf;
if (!item)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() failed to deserialise SignerItem";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
continue;
}
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() SignerItem: ";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
/* check dates */
if ((item->key.startTS > (unsigned) now) || (item->key.endTS < (unsigned) now))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() failed timestamp";
std::cerr << std::endl;
std::cerr << "RsRecogn::loadSigningKeys() key.startTS: " << item->key.startTS;
std::cerr << std::endl;
std::cerr << "RsRecogn::loadSigningKeys() now: " << now;
std::cerr << std::endl;
std::cerr << "RsRecogn::loadSigningKeys() key.endTS: " << item->key.endTS;
std::cerr << std::endl;
#endif // DEBUG_RECOGN
delete item;
continue;
}
/* check signature */
RsTlvKeySignature signature = item->sign;
item->sign.TlvShallowClear();
unsigned int siglen = signature.signData.bin_len;
unsigned char *sigbuf = (unsigned char *) signature.signData.bin_data;
/* store in */
uint32_t datalen = recognSerialiser.size(item);
uint8_t *data = (uint8_t *) malloc(datalen);
uint32_t pktlen = datalen;
int signOk = 0;
if (recognSerialiser.serialise(item, data, &pktlen))
{
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_VerifyInit(mdctx, EVP_sha1());
EVP_VerifyUpdate(mdctx, data, pktlen);
signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey);
EVP_MD_CTX_destroy(mdctx);
item->sign = signature;
signature.TlvShallowClear();
if (signOk)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() signature ok";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
std::string signerId = item->key.keyId;
signMap[signerId] = item;
}
}
if (!signOk)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() signature failed";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
delete item;
}
free(data);
}
/* clean up */
EVP_PKEY_free(signKey);
return true;
}
bool RsRecogn::validateTagSignature(RsGxsRecognSignerItem *signer, RsGxsRecognTagItem *item)
{
if (item->sign.keyId != signer->key.keyId)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::validateTagSignature() keyId mismatch";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return false;
}
const unsigned char *keyptr = (const unsigned char *) signer->key.keyData.bin_data;
long keylen = signer->key.keyData.bin_len;
/* extract admin key */
RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen);
if (!rsakey)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::validateTagSignature() failed extract signkey";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return false;
}
/* check signature */
RsTlvKeySignature signature = item->sign;
item->sign.TlvShallowClear();
unsigned int siglen = signature.signData.bin_len;
unsigned char *sigbuf = (unsigned char *) signature.signData.bin_data;
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_PKEY *signKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(signKey, rsakey);
/* store in */
RsGxsRecognSerialiser serialiser;
uint32_t datalen = serialiser.size(item);
uint8_t *data = (uint8_t *) malloc(datalen);
int signOk = 0;
uint32_t pktlen = datalen;
if (serialiser.serialise(item, data, &pktlen))
{
EVP_VerifyInit(mdctx, EVP_sha1());
EVP_VerifyUpdate(mdctx, data, pktlen);
signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey);
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::validateTagSignature() sign_result: " << signOk;
std::cerr << std::endl;
#endif // DEBUG_RECOGN
}
else
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::validateTagSignature() failed to serialise";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
}
// Clean up.
item->sign = signature;
signature.TlvShallowClear();
EVP_MD_CTX_destroy(mdctx);
EVP_PKEY_free(signKey);
free(data);
return (signOk == 1);
}
bool rsa_sanity_check(RSA *rsa)
{
std::cerr << "rsa_sanity_check()";
std::cerr << std::endl;
if (!rsa)
{
std::cerr << "rsa_sanity_check() RSA == NULL";
std::cerr << std::endl;
return false;
}
RSA *pubkey = RSAPublicKey_dup(rsa);
std::string signId = RsRecogn::getRsaKeyId(rsa);
std::string signId2 = RsRecogn::getRsaKeyId(pubkey);
bool ok = true;
if (signId != signId2)
{
std::cerr << "rsa_sanity_check() ERROR SignId Failure";
std::cerr << std::endl;
ok = false;
}
if (1 != RSA_check_key(rsa))
{
std::cerr << "rsa_sanity_check() ERROR RSA key is not private";
std::cerr << std::endl;
ok = false;
}
#if 0
if (1 == RSA_check_key(pubkey))
{
std::cerr << "rsa_sanity_check() ERROR RSA dup key is private";
std::cerr << std::endl;
ok = false;
}
#endif
RSA_free(pubkey);
if (!ok)
{
exit(1);
}
return true;
}
bool RsRecogn::signTag(EVP_PKEY *signKey, RsGxsRecognTagItem *item)
{
RsGxsRecognSerialiser serialiser;
RSA *rsa = EVP_PKEY_get1_RSA(signKey);
std::string signId = getRsaKeyId(rsa);
rsa_sanity_check(rsa);
RSA_free(rsa);
item->sign.TlvClear();
/* write out the item for signing */
uint32_t len = serialiser.size(item);
char *buf = new char[len];
if (!serialiser.serialise(item, buf, &len))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::signTag() Failed serialise TagItem:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete []buf;
return false;
}
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_SignInit(mdctx, EVP_sha1());
EVP_SignUpdate(mdctx, buf, len);
unsigned int siglen = EVP_PKEY_size(signKey);
unsigned char sigbuf[siglen];
EVP_SignFinal(mdctx, sigbuf, &siglen, signKey);
/* save signature */
item->sign.signData.setBinData(sigbuf, siglen);
item->sign.keyId = signId;
/* clean up */
EVP_MD_CTX_destroy(mdctx);
delete []buf;
return true;
}
bool RsRecogn::signSigner(EVP_PKEY *signKey, RsGxsRecognSignerItem *item)
{
std::cerr << "RsRecogn::signSigner()";
std::cerr << std::endl;
RsGxsRecognSerialiser serialiser;
std::cerr << "RsRecogn::signSigner() Checking Key";
std::cerr << std::endl;
RSA *rsa = EVP_PKEY_get1_RSA(signKey);
std::string signId = getRsaKeyId(rsa);
rsa_sanity_check(rsa);
RSA_free(rsa);
std::cerr << "RsRecogn::signSigner() Key Okay";
std::cerr << std::endl;
item->sign.TlvClear();
/* write out the item for signing */
uint32_t len = serialiser.size(item);
char *buf = new char[len];
if (!serialiser.serialise(item, buf, &len))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::signSigner() Failed serialise SignerItem:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete []buf;
return false;
}
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_SignInit(mdctx, EVP_sha1());
EVP_SignUpdate(mdctx, buf, len);
unsigned int siglen = EVP_PKEY_size(signKey);
unsigned char sigbuf[siglen];
EVP_SignFinal(mdctx, sigbuf, &siglen, signKey);
/* save signature */
item->sign.signData.setBinData(sigbuf, siglen);
item->sign.keyId = signId;
/* clean up */
EVP_MD_CTX_destroy(mdctx);
delete []buf;
return true;
}
bool RsRecogn::signTagRequest(EVP_PKEY *signKey, RsGxsRecognReqItem *item)
{
std::cerr << "RsRecogn::signTagRequest()";
std::cerr << std::endl;
RsGxsRecognSerialiser serialiser;
RSA *rsa = EVP_PKEY_get1_RSA(signKey);
std::string signId = getRsaKeyId(rsa);
rsa_sanity_check(rsa);
RSA_free(rsa);
item->sign.TlvClear();
/* write out the item for signing */
uint32_t len = serialiser.size(item);
char *buf = new char[len];
if (!serialiser.serialise(item, buf, &len))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::signTagRequest() Failed serialise Tag Request:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete []buf;
return false;
}
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_SignInit(mdctx, EVP_sha1());
EVP_SignUpdate(mdctx, buf, len);
unsigned int siglen = EVP_PKEY_size(signKey);
unsigned char sigbuf[siglen];
EVP_SignFinal(mdctx, sigbuf, &siglen, signKey);
/* save signature */
item->sign.signData.setBinData(sigbuf, siglen);
item->sign.keyId = signId;
/* clean up */
EVP_MD_CTX_destroy(mdctx);
delete []buf;
return true;
}
bool RsRecogn::itemToRadix64(RsItem *item, std::string &radstr)
{
RsGxsRecognSerialiser serialiser;
/* write out the item for signing */
uint32_t len = serialiser.size(item);
char *buf = new char[len];
if (!serialiser.serialise(item, buf, &len))
{
return false;
}
radstr.clear();
Radix64::encode(buf, len, radstr);
return true;
}
std::string RsRecogn::getRsaKeyId(RSA *pubkey)
{
int len = BN_num_bytes(pubkey -> n);
unsigned char tmp[len];
BN_bn2bin(pubkey -> n, tmp);
// copy first CERTSIGNLEN bytes...
if (len > CERTSIGNLEN)
{
len = CERTSIGNLEN;
}
std::string id;
for(uint32_t i = 0; i < CERTSIGNLEN; i++)
{
rs_sprintf_append(id, "%02x", (uint16_t) (((uint8_t *) (tmp))[i]));
}
return id;
}
RsGxsRecognTagItem *RsRecogn::extractTag(const std::string &encoded)
{
// Decode from Radix64 encoded Packet.
size_t buflen;
char *buffer;
uint32_t pktsize;
Radix64::decode(encoded, buffer, buflen);
pktsize = buflen;
RsGxsRecognSerialiser serialiser;
RsItem *item = serialiser.deserialise(buffer, &pktsize);
delete []buffer;
if (!item)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::extractTag() ERROR Deserialise failed";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return NULL;
}
RsGxsRecognTagItem *tagitem = dynamic_cast<RsGxsRecognTagItem *>(item);
if (!tagitem)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::extractTag() ERROR Not TagItem, is: ";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete item;
}
return tagitem;
}
bool RsRecogn::createTagRequest(const RsTlvSecurityKey &key, const std::string &id, const std::string &nickname, uint16_t tag_class, uint16_t tag_type, const std::string &comment, std::string &tag)
{
RsGxsRecognReqItem *item = new RsGxsRecognReqItem();
EVP_PKEY *signKey = EVP_PKEY_new();
RSA *rsakey = GxsSecurity::extractPrivateKey(key);
if (!rsakey)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::createTagRequest() Failed to extract key";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return false;
}
if (!EVP_PKEY_assign_RSA(signKey, rsakey))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::createTagRequest() Failed to assign key";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return false;
}
item->issued_at = time(NULL);
item->period = 365 * 24 * 3600;
item->tag_class = tag_class;
item->tag_type = tag_type;
item->nickname = nickname;
item->identity = id;
item->comment = comment;
bool signOk = RsRecogn::signTagRequest(signKey,item);
EVP_PKEY_free(signKey);
if (!signOk)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::createTagRequest() Failed to sign Tag Request:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete item;
return false;
}
/* write out the item for signing */
RsGxsRecognSerialiser serialiser;
uint32_t len = serialiser.size(item);
char *buf = new char[len];
bool serOk = serialiser.serialise(item, buf, &len);
delete item;
if (serOk)
{
Radix64::encode(buf, len, tag);
}
delete []buf;
if (!serOk)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::createTagRequest() Failed serialise Tag Request:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
return false;
}
return serOk;
}

View File

@ -0,0 +1,61 @@
/*
* libretroshare/src/util: rsrecogn.h
*
* RetroShare Utilities
*
* Copyright 2013 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef RSUTIL_RECOGN_H
#define RSUTIL_RECOGN_H
#include <inttypes.h>
#include <string>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include "serialiser/rsgxsrecognitems.h"
namespace RsRecogn {
EVP_PKEY * loadMasterKey();
bool loadSigningKeys(std::map<std::string, RsGxsRecognSignerItem *> &signMap);
bool validateTagSignature(RsGxsRecognSignerItem *signer, RsGxsRecognTagItem *item);
bool signTag(EVP_PKEY *signKey, RsGxsRecognTagItem *item);
bool signSigner(EVP_PKEY *signKey, RsGxsRecognSignerItem *item);
bool signTagRequest(EVP_PKEY *signKey, RsGxsRecognReqItem *item);
bool itemToRadix64(RsItem *item, std::string &radstr);
std::string getRsaKeyId(RSA *pubkey);
RsGxsRecognTagItem *extractTag(const std::string &encoded);
bool createTagRequest(const RsTlvSecurityKey &key,
const std::string &id, const std::string &nickname,
uint16_t tag_class, uint16_t tag_type,
const std::string &comment, std::string &tag);
}
#endif