mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-03 14:45:12 -04:00
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:
parent
19d7faa572
commit
fc58861447
19 changed files with 2645 additions and 101 deletions
|
@ -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
|
||||
|
|
640
libretroshare/src/util/rsrecogn.cc
Normal file
640
libretroshare/src/util/rsrecogn.cc
Normal 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;
|
||||
}
|
||||
|
||||
|
61
libretroshare/src/util/rsrecogn.h
Normal file
61
libretroshare/src/util/rsrecogn.h
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue