mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-10-13 14:01:03 -04:00
moved static/parsing of radix parts of short invites into RsCertificate (more code should be moved static there) and fixed adding incoming keys to friend server
This commit is contained in:
parent
5da31592f2
commit
b7c7c4c3f5
4 changed files with 171 additions and 155 deletions
|
@ -28,6 +28,7 @@
|
||||||
#include <retroshare/rspeers.h>
|
#include <retroshare/rspeers.h>
|
||||||
#include <util/radix64.h>
|
#include <util/radix64.h>
|
||||||
#include <pgp/pgpkeyutil.h>
|
#include <pgp/pgpkeyutil.h>
|
||||||
|
#include <pgp/pgphandler.h>
|
||||||
#include "rscertificate.h"
|
#include "rscertificate.h"
|
||||||
#include "util/rsstring.h"
|
#include "util/rsstring.h"
|
||||||
#include "util/stacktrace.h"
|
#include "util/stacktrace.h"
|
||||||
|
@ -621,6 +622,140 @@ bool RsCertificate::cleanRadix64(const std::string& instr,std::string& str,uint3
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RsCertificate::decodeRadix64ShortInvite(const std::string& rsInvite, RsPeerDetails& details, uint32_t& err_code)
|
||||||
|
{
|
||||||
|
err_code = 0;
|
||||||
|
std::vector<uint8_t> bf = Radix64::decode(rsInvite);
|
||||||
|
size_t size = bf.size();
|
||||||
|
|
||||||
|
unsigned char* buf = bf.data();
|
||||||
|
size_t total_s = 0;
|
||||||
|
bool CRC_ok = false ; // not checked yet
|
||||||
|
|
||||||
|
while(total_s < size)
|
||||||
|
{
|
||||||
|
RsShortInviteFieldType ptag = RsShortInviteFieldType(buf[0]);
|
||||||
|
buf = &buf[1];
|
||||||
|
|
||||||
|
unsigned char *buf2 = buf;
|
||||||
|
uint32_t s = 0;
|
||||||
|
|
||||||
|
try { s = PGPKeyParser::read_125Size(buf); }
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_s += 1 + ( reinterpret_cast<size_t>(buf) - reinterpret_cast<size_t>(buf2) );
|
||||||
|
|
||||||
|
if(total_s > size)
|
||||||
|
{
|
||||||
|
err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dbg3() << __PRETTY_FUNCTION__ << " Read ptag: "
|
||||||
|
<< static_cast<uint32_t>(ptag)
|
||||||
|
<< ", size " << s << ", total_s = " << total_s
|
||||||
|
<< ", expected total = " << size << std::endl;
|
||||||
|
|
||||||
|
switch(ptag)
|
||||||
|
{
|
||||||
|
case RsShortInviteFieldType::SSL_ID:
|
||||||
|
details.id = RsPeerId::fromBufferUnsafe(buf) ;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RsShortInviteFieldType::PEER_NAME:
|
||||||
|
details.name = std::string((char*)buf,s);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RsShortInviteFieldType::PGP_FINGERPRINT:
|
||||||
|
details.fpr = RsPgpFingerprint::fromBufferUnsafe(buf);
|
||||||
|
details.gpg_id = PGPHandler::pgpIdFromFingerprint(details.fpr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RsShortInviteFieldType::LOCATOR:
|
||||||
|
{
|
||||||
|
std::string locatorStr((char*)buf,s);
|
||||||
|
details.ipAddressList.push_back(locatorStr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RsShortInviteFieldType::DNS_LOCATOR:
|
||||||
|
details.extPort = (((int)buf[0]) << 8) + buf[1];
|
||||||
|
details.dyndns = std::string((char*)&buf[2],s-2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RsShortInviteFieldType::LOC4_LOCATOR:
|
||||||
|
{
|
||||||
|
uint32_t t4Addr = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3];
|
||||||
|
sockaddr_in tLocalAddr;
|
||||||
|
tLocalAddr.sin_addr.s_addr = t4Addr;
|
||||||
|
|
||||||
|
details.localAddr = rs_inet_ntoa(tLocalAddr.sin_addr);
|
||||||
|
details.localPort = (((uint32_t)buf[4])<<8) + (uint32_t)buf[5];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RsShortInviteFieldType::EXT4_LOCATOR:
|
||||||
|
{
|
||||||
|
uint32_t t4Addr = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3];
|
||||||
|
sockaddr_in tExtAddr;
|
||||||
|
tExtAddr.sin_addr.s_addr = t4Addr;
|
||||||
|
|
||||||
|
details.extAddr = rs_inet_ntoa(tExtAddr.sin_addr);
|
||||||
|
details.extPort = (((uint32_t)buf[4])<<8) + (uint32_t)buf[5];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RsShortInviteFieldType::HIDDEN_LOCATOR:
|
||||||
|
details.hiddenType = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3];
|
||||||
|
details.hiddenNodePort = (((uint32_t)buf[4]) << 8)+ (uint32_t)buf[5];
|
||||||
|
details.isHiddenNode = true;
|
||||||
|
details.hiddenNodeAddress = std::string((char*)&buf[6],s-6);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RsShortInviteFieldType::CHECKSUM:
|
||||||
|
{
|
||||||
|
if(s != 3 || total_s+3 != size) // make sure the checksum is the last section
|
||||||
|
{
|
||||||
|
err_code = CERTIFICATE_PARSING_ERROR_INVALID_CHECKSUM_SECTION;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint32_t computed_crc = PGPKeyManagement::compute24bitsCRC(bf.data(),size-5);
|
||||||
|
uint32_t certificate_crc = static_cast<uint32_t>( buf[0] + (buf[1] << 8) + (buf[2] << 16) );
|
||||||
|
|
||||||
|
if(computed_crc != certificate_crc)
|
||||||
|
{
|
||||||
|
err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
CRC_ok = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = &buf[s];
|
||||||
|
total_s += s;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(details.id.isNull())
|
||||||
|
{
|
||||||
|
err_code = CERTIFICATE_PARSING_ERROR_MISSING_LOCATION_ID;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!CRC_ok)
|
||||||
|
{
|
||||||
|
err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,21 @@ struct RsPeerDetails;
|
||||||
class RsCertificate
|
class RsCertificate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum class RsShortInviteFieldType : uint8_t
|
||||||
|
{
|
||||||
|
SSL_ID = 0x00,
|
||||||
|
PEER_NAME = 0x01,
|
||||||
|
LOCATOR = 0x02,
|
||||||
|
PGP_FINGERPRINT = 0x03,
|
||||||
|
CHECKSUM = 0x04,
|
||||||
|
|
||||||
|
/* The following will be deprecated, and ported to LOCATOR when generic transport layer will be implemented */
|
||||||
|
HIDDEN_LOCATOR = 0x90,
|
||||||
|
DNS_LOCATOR = 0x91,
|
||||||
|
EXT4_LOCATOR = 0x92, // external IPv4 address
|
||||||
|
LOC4_LOCATOR = 0x93 // local IPv4 address
|
||||||
|
};
|
||||||
|
|
||||||
typedef enum { RS_CERTIFICATE_OLD_FORMAT, RS_CERTIFICATE_RADIX, RS_CERTIFICATE_SHORT_RADIX } Format;
|
typedef enum { RS_CERTIFICATE_OLD_FORMAT, RS_CERTIFICATE_RADIX, RS_CERTIFICATE_SHORT_RADIX } Format;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,6 +79,8 @@ public:
|
||||||
|
|
||||||
~RsCertificate();
|
~RsCertificate();
|
||||||
|
|
||||||
|
static bool decodeRadix64ShortInvite(const std::string& short_invite_b64,RsPeerDetails& det,uint32_t& error_code);
|
||||||
|
|
||||||
/// Convert to certificate radix string
|
/// Convert to certificate radix string
|
||||||
std::string toStdString() const;
|
std::string toStdString() const;
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
|
|
||||||
#include "pqi/authssl.h"
|
#include "pqi/authssl.h"
|
||||||
|
|
||||||
|
typedef RsCertificate::RsShortInviteFieldType RsShortInviteFieldType; // locally in this file to avoid renaming everything.
|
||||||
|
|
||||||
RsPeers *rsPeers = NULL;
|
RsPeers *rsPeers = NULL;
|
||||||
|
|
||||||
|
@ -1159,22 +1160,6 @@ bool p3Peers::GetPGPBase64StringAndCheckSum(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class RsShortInviteFieldType : uint8_t
|
|
||||||
{
|
|
||||||
SSL_ID = 0x00,
|
|
||||||
PEER_NAME = 0x01,
|
|
||||||
LOCATOR = 0x02,
|
|
||||||
PGP_FINGERPRINT = 0x03,
|
|
||||||
CHECKSUM = 0x04,
|
|
||||||
|
|
||||||
/* The following will be deprecated, and ported to LOCATOR when generic
|
|
||||||
* trasport layer will be implemented */
|
|
||||||
HIDDEN_LOCATOR = 0x90,
|
|
||||||
DNS_LOCATOR = 0x91,
|
|
||||||
EXT4_LOCATOR = 0x92, // external IPv4 address
|
|
||||||
LOC4_LOCATOR = 0x93 // local IPv4 address
|
|
||||||
};
|
|
||||||
|
|
||||||
static void addPacketHeader(RsShortInviteFieldType ptag, size_t size, unsigned char *& buf, uint32_t& offset, uint32_t& buf_size)
|
static void addPacketHeader(RsShortInviteFieldType ptag, size_t size, unsigned char *& buf, uint32_t& offset, uint32_t& buf_size)
|
||||||
{
|
{
|
||||||
// Check that the buffer has sufficient size. If not, increase it.
|
// Check that the buffer has sufficient size. If not, increase it.
|
||||||
|
@ -1351,136 +1336,23 @@ bool p3Peers::getShortInvite(std::string& invite, const RsPeerId& _sslId, Retros
|
||||||
|
|
||||||
bool p3Peers::parseShortInvite(const std::string& inviteStrUrl, RsPeerDetails& details, uint32_t &err_code )
|
bool p3Peers::parseShortInvite(const std::string& inviteStrUrl, RsPeerDetails& details, uint32_t &err_code )
|
||||||
{
|
{
|
||||||
if(inviteStrUrl.empty())
|
if(inviteStrUrl.empty())
|
||||||
{
|
{
|
||||||
RsErr() << __PRETTY_FUNCTION__ << " can't parse empty invite"
|
RsErr() << __PRETTY_FUNCTION__ << " can't parse empty invite"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string rsInvite = inviteStrUrl;
|
std::string rsInvite = inviteStrUrl;
|
||||||
|
|
||||||
RsUrl inviteUrl(inviteStrUrl);
|
RsUrl inviteUrl(inviteStrUrl);
|
||||||
|
|
||||||
if(inviteUrl.hasQueryK("rsInvite"))
|
if(inviteUrl.hasQueryK("rsInvite"))
|
||||||
rsInvite = *inviteUrl.getQueryV("rsInvite");
|
rsInvite = *inviteUrl.getQueryV("rsInvite");
|
||||||
|
|
||||||
std::vector<uint8_t> bf = Radix64::decode(rsInvite);
|
if(!RsCertificate::decodeRadix64ShortInvite(rsInvite, details, err_code))
|
||||||
size_t size = bf.size();
|
return false;
|
||||||
|
|
||||||
unsigned char* buf = bf.data();
|
// Also check if the PGP key is available. If so, add it in the PeerDetails:
|
||||||
size_t total_s = 0;
|
|
||||||
bool CRC_ok = false ; // not checked yet
|
|
||||||
|
|
||||||
while(total_s < size)
|
|
||||||
{
|
|
||||||
RsShortInviteFieldType ptag = RsShortInviteFieldType(buf[0]);
|
|
||||||
buf = &buf[1];
|
|
||||||
|
|
||||||
unsigned char *buf2 = buf;
|
|
||||||
uint32_t s = 0;
|
|
||||||
|
|
||||||
try { s = PGPKeyParser::read_125Size(buf); }
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_s += 1 + ( reinterpret_cast<size_t>(buf) - reinterpret_cast<size_t>(buf2) );
|
|
||||||
|
|
||||||
if(total_s > size)
|
|
||||||
{
|
|
||||||
err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dbg3() << __PRETTY_FUNCTION__ << " Read ptag: "
|
|
||||||
<< static_cast<uint32_t>(ptag)
|
|
||||||
<< ", size " << s << ", total_s = " << total_s
|
|
||||||
<< ", expected total = " << size << std::endl;
|
|
||||||
|
|
||||||
switch(ptag)
|
|
||||||
{
|
|
||||||
case RsShortInviteFieldType::SSL_ID:
|
|
||||||
details.id = RsPeerId::fromBufferUnsafe(buf) ;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RsShortInviteFieldType::PEER_NAME:
|
|
||||||
details.name = std::string((char*)buf,s);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RsShortInviteFieldType::PGP_FINGERPRINT:
|
|
||||||
details.fpr = RsPgpFingerprint::fromBufferUnsafe(buf);
|
|
||||||
details.gpg_id = PGPHandler::pgpIdFromFingerprint(details.fpr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RsShortInviteFieldType::LOCATOR:
|
|
||||||
{
|
|
||||||
std::string locatorStr((char*)buf,s);
|
|
||||||
details.ipAddressList.push_back(locatorStr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RsShortInviteFieldType::DNS_LOCATOR:
|
|
||||||
details.extPort = (((int)buf[0]) << 8) + buf[1];
|
|
||||||
details.dyndns = std::string((char*)&buf[2],s-2);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RsShortInviteFieldType::LOC4_LOCATOR:
|
|
||||||
{
|
|
||||||
uint32_t t4Addr = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3];
|
|
||||||
sockaddr_in tLocalAddr;
|
|
||||||
tLocalAddr.sin_addr.s_addr = t4Addr;
|
|
||||||
|
|
||||||
details.localAddr = rs_inet_ntoa(tLocalAddr.sin_addr);
|
|
||||||
details.localPort = (((uint32_t)buf[4])<<8) + (uint32_t)buf[5];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RsShortInviteFieldType::EXT4_LOCATOR:
|
|
||||||
{
|
|
||||||
uint32_t t4Addr = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3];
|
|
||||||
sockaddr_in tExtAddr;
|
|
||||||
tExtAddr.sin_addr.s_addr = t4Addr;
|
|
||||||
|
|
||||||
details.extAddr = rs_inet_ntoa(tExtAddr.sin_addr);
|
|
||||||
details.extPort = (((uint32_t)buf[4])<<8) + (uint32_t)buf[5];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RsShortInviteFieldType::HIDDEN_LOCATOR:
|
|
||||||
details.hiddenType = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3];
|
|
||||||
details.hiddenNodePort = (((uint32_t)buf[4]) << 8)+ (uint32_t)buf[5];
|
|
||||||
details.isHiddenNode = true;
|
|
||||||
details.hiddenNodeAddress = std::string((char*)&buf[6],s-6);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RsShortInviteFieldType::CHECKSUM:
|
|
||||||
{
|
|
||||||
if(s != 3 || total_s+3 != size) // make sure the checksum is the last section
|
|
||||||
{
|
|
||||||
err_code = CERTIFICATE_PARSING_ERROR_INVALID_CHECKSUM_SECTION;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
uint32_t computed_crc = PGPKeyManagement::compute24bitsCRC(bf.data(),size-5);
|
|
||||||
uint32_t certificate_crc = static_cast<uint32_t>( buf[0] + (buf[1] << 8) + (buf[2] << 16) );
|
|
||||||
|
|
||||||
if(computed_crc != certificate_crc)
|
|
||||||
{
|
|
||||||
err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
CRC_ok = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = &buf[s];
|
|
||||||
total_s += s;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now check if the PGP key is available. If so, add it in the PeerDetails:
|
|
||||||
|
|
||||||
RsPeerDetails pgp_det ;
|
RsPeerDetails pgp_det ;
|
||||||
if(getGPGDetails(PGPHandler::pgpIdFromFingerprint(details.fpr),pgp_det) && pgp_det.fpr == details.fpr)
|
if(getGPGDetails(PGPHandler::pgpIdFromFingerprint(details.fpr),pgp_det) && pgp_det.fpr == details.fpr)
|
||||||
|
@ -1497,23 +1369,13 @@ bool p3Peers::parseShortInvite(const std::string& inviteStrUrl, RsPeerDetails& d
|
||||||
else
|
else
|
||||||
details.skip_pgp_signature_validation = true;
|
details.skip_pgp_signature_validation = true;
|
||||||
|
|
||||||
if(!CRC_ok)
|
|
||||||
{
|
|
||||||
err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(details.gpg_id.isNull())
|
if(details.gpg_id.isNull())
|
||||||
{
|
{
|
||||||
err_code = CERTIFICATE_PARSING_ERROR_MISSING_PGP_FINGERPRINT;
|
err_code = CERTIFICATE_PARSING_ERROR_MISSING_PGP_FINGERPRINT;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(details.id.isNull())
|
err_code = CERTIFICATE_PARSING_ERROR_NO_ERROR;
|
||||||
{
|
return true;
|
||||||
err_code = CERTIFICATE_PARSING_ERROR_MISSING_LOCATION_ID;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
err_code = CERTIFICATE_PARSING_ERROR_NO_ERROR;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3Peers::acceptInvite( const std::string& invite,
|
bool p3Peers::acceptInvite( const std::string& invite,
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "util/rsbase64.h"
|
#include "util/rsbase64.h"
|
||||||
#include "util/radix64.h"
|
#include "util/radix64.h"
|
||||||
|
|
||||||
|
#include "pgp/rscertificate.h"
|
||||||
|
|
||||||
#include "friendserver.h"
|
#include "friendserver.h"
|
||||||
#include "friend_server/fsitem.h"
|
#include "friend_server/fsitem.h"
|
||||||
|
|
||||||
|
@ -92,7 +94,7 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it
|
||||||
RsPeerDetails shortInviteDetails;
|
RsPeerDetails shortInviteDetails;
|
||||||
uint32_t errorCode = 0;
|
uint32_t errorCode = 0;
|
||||||
|
|
||||||
if(item->short_invite.empty() || !rsPeers->parseShortInvite(item->short_invite, shortInviteDetails,errorCode ))
|
if(item->short_invite.empty() || !RsCertificate::decodeRadix64ShortInvite(item->short_invite, shortInviteDetails,errorCode ))
|
||||||
throw std::runtime_error("Could not parse short certificate. Error = " + RsUtil::NumberToString(errorCode));
|
throw std::runtime_error("Could not parse short certificate. Error = " + RsUtil::NumberToString(errorCode));
|
||||||
|
|
||||||
RsDbg() << " Short invite is fine. PGP fingerprint: " << shortInviteDetails.fpr ;
|
RsDbg() << " Short invite is fine. PGP fingerprint: " << shortInviteDetails.fpr ;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue