mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-04 17:15:31 -05:00
Safer RsCertificate API
Deprecate costructors that may fails, offer alternative methods which suggest correct usage to the programmer Internally still use too much try,catch,throw but at least the API dosn't expose those anymore.
This commit is contained in:
parent
6ca85ca7b6
commit
5fe8ba0665
@ -3,8 +3,8 @@
|
||||
* *
|
||||
* libretroshare: retroshare core library *
|
||||
* *
|
||||
* Copyright 2016 Cyril Soler <csoler@users.sourceforge.net> *
|
||||
* Copyright 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* Copyright (C) 2016 Cyril Soler <csoler@users.sourceforge.net> *
|
||||
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
@ -31,6 +31,7 @@
|
||||
#include "rscertificate.h"
|
||||
#include "util/rsstring.h"
|
||||
#include "util/stacktrace.h"
|
||||
#include "util/rsdebug.h"
|
||||
|
||||
//#define DEBUG_RSCERTIFICATE
|
||||
|
||||
@ -55,6 +56,7 @@ static bool is_acceptable_radix64Char(char c)
|
||||
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '+' || c == '/' || c == '=' ;
|
||||
}
|
||||
|
||||
|
||||
RsCertificate::~RsCertificate()
|
||||
{
|
||||
delete[] binary_pgp_key ;
|
||||
@ -166,28 +168,16 @@ std::string RsCertificate::toStdString() const
|
||||
return out2 ;
|
||||
}
|
||||
|
||||
RsCertificate::RsCertificate(const std::string& str) :
|
||||
location_name(""), pgp_version("Version: OpenPGP:SDK v0.9"),
|
||||
dns_name(""), only_pgp(true)
|
||||
{
|
||||
uint32_t err_code;
|
||||
binary_pgp_key = nullptr;
|
||||
|
||||
if(!initializeFromString(str, err_code))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " is deprecated because it can "
|
||||
<< "miserably fail like this! str: " << str
|
||||
<< " err_code: " << err_code << std::endl;
|
||||
print_stacktrace();
|
||||
throw err_code;
|
||||
}
|
||||
}
|
||||
|
||||
RsCertificate::RsCertificate(const RsPeerDetails& Detail, const unsigned char *binary_pgp_block,size_t binary_pgp_block_size)
|
||||
:pgp_version("Version: OpenPGP:SDK v0.9")
|
||||
{
|
||||
if(binary_pgp_block_size == 0 || binary_pgp_block == NULL)
|
||||
throw std::runtime_error("Cannot init a certificate with a void key block.") ;
|
||||
if(binary_pgp_block_size == 0 || binary_pgp_block == nullptr)
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " is deprecated because it can "
|
||||
<< "miserably fail like this! " << std::endl;
|
||||
print_stacktrace();
|
||||
throw std::runtime_error("Cannot init a certificate with a void key block.");
|
||||
}
|
||||
|
||||
binary_pgp_key = new unsigned char[binary_pgp_block_size] ;
|
||||
memcpy(binary_pgp_key,binary_pgp_block,binary_pgp_block_size) ;
|
||||
@ -256,6 +246,91 @@ RsCertificate::RsCertificate(const RsPeerDetails& Detail, const unsigned char *b
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*static*/ std::unique_ptr<RsCertificate> RsCertificate::fromMemoryBlock(
|
||||
const RsPeerDetails& details, const uint8_t* binary_pgp_block,
|
||||
size_t binary_pgp_block_size )
|
||||
{
|
||||
if(binary_pgp_block_size == 0 || binary_pgp_block == nullptr)
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " invalid parameters! " << std::endl;
|
||||
print_stacktrace();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<RsCertificate> crt(new RsCertificate);
|
||||
|
||||
crt->binary_pgp_key = new uint8_t[binary_pgp_block_size];
|
||||
memcpy(crt->binary_pgp_key, binary_pgp_block, binary_pgp_block_size);
|
||||
crt->binary_pgp_key_size = binary_pgp_block_size;
|
||||
|
||||
if(!details.isOnlyGPGdetail)
|
||||
{
|
||||
crt->only_pgp = false;
|
||||
crt->location_id = RsPeerId(details.id);
|
||||
crt->location_name = details.location;
|
||||
|
||||
if (details.isHiddenNode)
|
||||
{
|
||||
crt->hidden_node = true;
|
||||
crt->hidden_node_address = details.hiddenNodeAddress;
|
||||
rs_sprintf_append(
|
||||
crt->hidden_node_address, ":%u", details.hiddenNodePort);
|
||||
|
||||
memset(crt->ipv4_internal_ip_and_port, 0, 6);
|
||||
memset(crt->ipv4_external_ip_and_port, 0, 6);
|
||||
crt->dns_name = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
crt->hidden_node = false;
|
||||
crt->hidden_node_address = "";
|
||||
|
||||
try
|
||||
{
|
||||
scan_ip( details.localAddr, details.localPort,
|
||||
crt->ipv4_internal_ip_and_port );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " Invalid LocalAddress: "
|
||||
<< details.localAddr << std::endl;
|
||||
memset(crt->ipv4_internal_ip_and_port, 0, 6);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
scan_ip( details.extAddr, details.extPort,
|
||||
crt->ipv4_external_ip_and_port );
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " Invalid ExternalAddress: "
|
||||
<< details.extAddr << std::endl;
|
||||
memset(crt->ipv4_external_ip_and_port, 0, 6);
|
||||
}
|
||||
|
||||
crt->dns_name = details.dyndns;
|
||||
|
||||
for(auto&& ipr : details.ipAddressList)
|
||||
crt->mLocators.insert(RsUrl(ipr.substr(0, ipr.find(' '))));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
crt->only_pgp = true;
|
||||
crt->hidden_node = false;
|
||||
crt->hidden_node_address = "";
|
||||
crt->location_id = RsPeerId();
|
||||
crt->location_name = "";
|
||||
memset(crt->ipv4_internal_ip_and_port, 0, 6);
|
||||
memset(crt->ipv4_external_ip_and_port, 0, 6);
|
||||
crt->dns_name = "";
|
||||
}
|
||||
|
||||
return crt; // Implicit move semantic
|
||||
}
|
||||
|
||||
void RsCertificate::scan_ip(const std::string& ip_string, unsigned short port,unsigned char *ip_and_port)
|
||||
{
|
||||
int d0,d1,d2,d3 ;
|
||||
@ -272,165 +347,166 @@ void RsCertificate::scan_ip(const std::string& ip_string, unsigned short port,un
|
||||
ip_and_port[5] = port & 0xff ;
|
||||
}
|
||||
|
||||
bool RsCertificate::initializeFromString(const std::string& instr,uint32_t& err_code)
|
||||
/*static*/ std::unique_ptr<RsCertificate> RsCertificate::fromString(
|
||||
const std::string& instr, uint32_t& err_code )
|
||||
{
|
||||
try
|
||||
Dbg3() << __PRETTY_FUNCTION__ << std::endl;
|
||||
|
||||
std::unique_ptr<RsCertificate> crt(new RsCertificate);
|
||||
|
||||
std::string str;
|
||||
err_code = CERTIFICATE_PARSING_ERROR_NO_ERROR;
|
||||
|
||||
// 0 - clean the string and check that it is pure radix64
|
||||
for(uint32_t i=0;i<instr.length();++i)
|
||||
{
|
||||
std::string str ;
|
||||
err_code = CERTIFICATE_PARSING_ERROR_NO_ERROR ;
|
||||
if(instr[i] == ' ' || instr[i] == '\t' || instr[i] == '\n')
|
||||
continue;
|
||||
|
||||
// 0 - clean the string and check that it is pure radix64
|
||||
//
|
||||
for(uint32_t i=0;i<instr.length();++i)
|
||||
{
|
||||
if(instr[i] == ' ' || instr[i] == '\t' || instr[i] == '\n')
|
||||
continue ;
|
||||
if(! is_acceptable_radix64Char(instr[i]))
|
||||
return nullptr;
|
||||
|
||||
if(! is_acceptable_radix64Char(instr[i]))
|
||||
return false ;
|
||||
|
||||
str += instr[i] ;
|
||||
}
|
||||
#ifdef DEBUG_RSCERTIFICATE
|
||||
std::cerr << "Decoding from:" << str << std::endl;
|
||||
#endif
|
||||
// 1 - decode the string.
|
||||
//
|
||||
std::vector<uint8_t> bf = Radix64::decode(str) ;
|
||||
size_t size = bf.size();
|
||||
|
||||
bool checksum_check_passed = false;
|
||||
unsigned char *buf = bf.data();
|
||||
size_t total_s = 0;
|
||||
only_pgp = true;
|
||||
uint8_t certificate_version = 0x00;
|
||||
|
||||
while(total_s < size)
|
||||
{
|
||||
uint8_t ptag = buf[0];
|
||||
buf = &buf[1];
|
||||
|
||||
unsigned char *buf2 = buf;
|
||||
uint32_t s = PGPKeyParser::read_125Size(buf);
|
||||
|
||||
total_s += 1 + ((size_t)buf-(size_t)buf2) ;
|
||||
|
||||
if(total_s > size)
|
||||
{
|
||||
err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_RSCERTIFICATE
|
||||
std::cerr << "Packet parse: read ptag " << (int)ptag << ", size " << s << ", total_s = " << total_s << ", expected total = " << size << std::endl;
|
||||
#endif
|
||||
switch(ptag)
|
||||
{
|
||||
case CERTIFICATE_PTAG_VERSION_SECTION:
|
||||
certificate_version = buf[0];
|
||||
break;
|
||||
case CERTIFICATE_PTAG_PGP_SECTION:
|
||||
binary_pgp_key = new unsigned char[s];
|
||||
memcpy(binary_pgp_key,buf,s);
|
||||
binary_pgp_key_size = s;
|
||||
break;
|
||||
case CERTIFICATE_PTAG_NAME_SECTION:
|
||||
location_name = std::string((char *)buf,s);
|
||||
break;
|
||||
case CERTIFICATE_PTAG_SSLID_SECTION:
|
||||
if(s != location_id.SIZE_IN_BYTES)
|
||||
{
|
||||
err_code = CERTIFICATE_PARSING_ERROR_INVALID_LOCATION_ID;
|
||||
return false;
|
||||
}
|
||||
location_id = RsPeerId(buf);
|
||||
only_pgp = false;
|
||||
break;
|
||||
case CERTIFICATE_PTAG_DNS_SECTION:
|
||||
dns_name = std::string((char *)buf,s);
|
||||
break;
|
||||
case CERTIFICATE_PTAG_HIDDENNODE_SECTION:
|
||||
hidden_node_address = std::string((char *)buf,s);
|
||||
hidden_node = true;
|
||||
break;
|
||||
case CERTIFICATE_PTAG_LOCIPANDPORT_SECTION:
|
||||
if(s != 6)
|
||||
{
|
||||
err_code = CERTIFICATE_PARSING_ERROR_INVALID_LOCAL_IP;
|
||||
return false;
|
||||
}
|
||||
memcpy(ipv4_internal_ip_and_port,buf,s);
|
||||
break;
|
||||
case CERTIFICATE_PTAG_EXTIPANDPORT_SECTION:
|
||||
if(s != 6)
|
||||
{
|
||||
err_code = CERTIFICATE_PARSING_ERROR_INVALID_EXTERNAL_IP;
|
||||
return false;
|
||||
}
|
||||
memcpy(ipv4_external_ip_and_port,buf,s);
|
||||
break;
|
||||
case CERTIFICATE_PTAG_CHECKSUM_SECTION:
|
||||
{
|
||||
if(s != 3 || total_s+3 != size)
|
||||
{
|
||||
err_code =
|
||||
CERTIFICATE_PARSING_ERROR_INVALID_CHECKSUM_SECTION;
|
||||
return false;
|
||||
}
|
||||
uint32_t computed_crc =
|
||||
PGPKeyManagement::compute24bitsCRC(bf.data(),size-5);
|
||||
uint32_t certificate_crc =
|
||||
buf[0] + (buf[1] << 8) + (buf[2] << 16);
|
||||
if(computed_crc != certificate_crc)
|
||||
{
|
||||
err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR;
|
||||
return false;
|
||||
}
|
||||
else checksum_check_passed = true;
|
||||
break;
|
||||
}
|
||||
case CERTIFICATE_PTAG_EXTRA_LOCATOR:
|
||||
mLocators.insert(RsUrl(std::string((char *)buf, s)));
|
||||
break;
|
||||
default:
|
||||
std::cerr << "(WW) unknwown PTAG 0x" << std::hex << ptag
|
||||
<< std::dec << " in certificate! Ignoring it."
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
buf = &buf[s];
|
||||
total_s += s ;
|
||||
}
|
||||
|
||||
if(!checksum_check_passed)
|
||||
{
|
||||
err_code = CERTIFICATE_PARSING_ERROR_MISSING_CHECKSUM ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
if(certificate_version != CERTIFICATE_VERSION_06)
|
||||
{
|
||||
err_code = CERTIFICATE_PARSING_ERROR_WRONG_VERSION ;
|
||||
return false ;
|
||||
}
|
||||
#ifdef DEBUG_RSCERTIFICATE
|
||||
std::cerr << "Certificate is version " << (int)certificate_version << std::endl;
|
||||
#endif
|
||||
|
||||
if(total_s != size)
|
||||
std::cerr << "(EE) Certificate contains trailing characters. Weird." << std::endl;
|
||||
|
||||
return true ;
|
||||
str += instr[i];
|
||||
}
|
||||
catch(std::exception& e)
|
||||
|
||||
Dbg4() << __PRETTY_FUNCTION__ << " Decoding from: " << str << std::endl;
|
||||
|
||||
// 1 - decode the string.
|
||||
|
||||
std::vector<uint8_t> bf = Radix64::decode(str);
|
||||
size_t size = bf.size();
|
||||
|
||||
bool checksum_check_passed = false;
|
||||
unsigned char* buf = bf.data();
|
||||
size_t total_s = 0;
|
||||
crt->only_pgp = true;
|
||||
uint8_t certificate_version = 0x00;
|
||||
|
||||
while(total_s < size)
|
||||
{
|
||||
if(binary_pgp_key != NULL)
|
||||
delete[] binary_pgp_key ;
|
||||
uint8_t ptag = buf[0];
|
||||
buf = &buf[1];
|
||||
|
||||
err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR ;
|
||||
return false ;
|
||||
unsigned char *buf2 = buf;
|
||||
uint32_t s = PGPKeyParser::read_125Size(buf);
|
||||
|
||||
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 nullptr;
|
||||
}
|
||||
|
||||
Dbg3() << __PRETTY_FUNCTION__ << " Read ptag: "
|
||||
<< static_cast<uint32_t>(ptag)
|
||||
<< ", size " << s << ", total_s = " << total_s
|
||||
<< ", expected total = " << size << std::endl;
|
||||
|
||||
switch(ptag)
|
||||
{
|
||||
case CERTIFICATE_PTAG_VERSION_SECTION:
|
||||
certificate_version = buf[0];
|
||||
break;
|
||||
case CERTIFICATE_PTAG_PGP_SECTION:
|
||||
crt->binary_pgp_key = new unsigned char[s];
|
||||
memcpy(crt->binary_pgp_key, buf, s);
|
||||
crt->binary_pgp_key_size = s;
|
||||
break;
|
||||
case CERTIFICATE_PTAG_NAME_SECTION:
|
||||
crt->location_name =
|
||||
std::string(reinterpret_cast<char*>(buf), s);
|
||||
break;
|
||||
case CERTIFICATE_PTAG_SSLID_SECTION:
|
||||
if(s != crt->location_id.SIZE_IN_BYTES)
|
||||
{
|
||||
err_code = CERTIFICATE_PARSING_ERROR_INVALID_LOCATION_ID;
|
||||
return nullptr;
|
||||
}
|
||||
crt->location_id = RsPeerId(buf);
|
||||
crt->only_pgp = false;
|
||||
break;
|
||||
case CERTIFICATE_PTAG_DNS_SECTION:
|
||||
crt->dns_name = std::string(reinterpret_cast<char*>(buf), s);
|
||||
break;
|
||||
case CERTIFICATE_PTAG_HIDDENNODE_SECTION:
|
||||
crt->hidden_node_address =
|
||||
std::string(reinterpret_cast<char*>(buf),s);
|
||||
crt->hidden_node = true;
|
||||
break;
|
||||
case CERTIFICATE_PTAG_LOCIPANDPORT_SECTION:
|
||||
if(s != 6)
|
||||
{
|
||||
err_code = CERTIFICATE_PARSING_ERROR_INVALID_LOCAL_IP;
|
||||
return nullptr;
|
||||
}
|
||||
memcpy(crt->ipv4_internal_ip_and_port, buf, s);
|
||||
break;
|
||||
case CERTIFICATE_PTAG_EXTIPANDPORT_SECTION:
|
||||
if(s != 6)
|
||||
{
|
||||
err_code = CERTIFICATE_PARSING_ERROR_INVALID_EXTERNAL_IP;
|
||||
return nullptr;
|
||||
}
|
||||
memcpy(crt->ipv4_external_ip_and_port, buf, s);
|
||||
break;
|
||||
case CERTIFICATE_PTAG_CHECKSUM_SECTION:
|
||||
{
|
||||
if(s != 3 || total_s+3 != size)
|
||||
{
|
||||
err_code =
|
||||
CERTIFICATE_PARSING_ERROR_INVALID_CHECKSUM_SECTION;
|
||||
return nullptr;
|
||||
}
|
||||
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 nullptr;
|
||||
}
|
||||
else checksum_check_passed = true;
|
||||
break;
|
||||
}
|
||||
case CERTIFICATE_PTAG_EXTRA_LOCATOR:
|
||||
crt->mLocators.insert(
|
||||
RsUrl(std::string(reinterpret_cast<char*>(buf), s)));
|
||||
break;
|
||||
default:
|
||||
RsWarn() << __PRETTY_FUNCTION__ << " unknwown ptag: "
|
||||
<< static_cast<uint32_t>(ptag)
|
||||
<< " in certificate! Ignoring it." << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
buf = &buf[s];
|
||||
total_s += s;
|
||||
}
|
||||
|
||||
if(!checksum_check_passed)
|
||||
{
|
||||
err_code = CERTIFICATE_PARSING_ERROR_MISSING_CHECKSUM;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(certificate_version != CERTIFICATE_VERSION_06)
|
||||
{
|
||||
err_code = CERTIFICATE_PARSING_ERROR_WRONG_VERSION;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Dbg3() << __PRETTY_FUNCTION__ << " Certificate version: "
|
||||
<< static_cast<uint32_t>(certificate_version) << std::endl;
|
||||
|
||||
if(total_s != size)
|
||||
RsWarn() << __PRETTY_FUNCTION__ << " Certificate contains trailing "
|
||||
<< "characters. Weird." << std::endl;
|
||||
|
||||
return crt; // Implicit move semantic
|
||||
}
|
||||
|
||||
std::string RsCertificate::hidden_node_string() const
|
||||
@ -450,6 +526,7 @@ std::string RsCertificate::ext_ip_string() const
|
||||
os << (int)ipv4_external_ip_and_port[0] << "." << (int)ipv4_external_ip_and_port[1] << "." << (int)ipv4_external_ip_and_port[2] << "." << (int)ipv4_external_ip_and_port[3] ;
|
||||
return os.str() ;
|
||||
}
|
||||
|
||||
std::string RsCertificate::loc_ip_string() const
|
||||
{
|
||||
std::ostringstream os ;
|
||||
@ -467,28 +544,21 @@ unsigned short RsCertificate::loc_port_us() const
|
||||
return (int)ipv4_internal_ip_and_port[4]*256 + (int)ipv4_internal_ip_and_port[5] ;
|
||||
}
|
||||
|
||||
bool RsCertificate::cleanCertificate(const std::string& input,std::string& output,Format& format,int& error_code,bool check_content)
|
||||
bool RsCertificate::cleanCertificate(
|
||||
const std::string& input, std::string& output, Format& format,
|
||||
int& error_code, bool check_content )
|
||||
{
|
||||
if(cleanCertificate(input,output,error_code))
|
||||
{
|
||||
format = RS_CERTIFICATE_RADIX ;
|
||||
|
||||
if(!check_content)
|
||||
return true ;
|
||||
|
||||
try
|
||||
{
|
||||
RsCertificate c(input) ;
|
||||
return true ;
|
||||
}
|
||||
catch(uint32_t err_code)
|
||||
{
|
||||
error_code = err_code ;
|
||||
return false;
|
||||
}
|
||||
format = RS_CERTIFICATE_RADIX;
|
||||
if(!check_content) return true;
|
||||
uint32_t errCode;
|
||||
auto crt = RsCertificate::fromString(input, errCode);
|
||||
error_code = static_cast<int>(errCode);
|
||||
return crt != nullptr;
|
||||
}
|
||||
|
||||
return false ;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string RsCertificate::armouredPGPKey() const
|
||||
|
@ -3,7 +3,8 @@
|
||||
* *
|
||||
* libretroshare: retroshare core library *
|
||||
* *
|
||||
* Copyright 2016 Cyril Soler <csoler@users.sourceforge.net> *
|
||||
* Copyright (C) 2016 Cyril Soler <csoler@users.sourceforge.net> *
|
||||
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License as *
|
||||
@ -23,9 +24,12 @@
|
||||
|
||||
#include "retroshare/rstypes.h"
|
||||
#include "util/rsurl.h"
|
||||
#include "util/rsmemory.h"
|
||||
#include "util/rsdebug.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
struct RsPeerDetails;
|
||||
|
||||
@ -35,30 +39,30 @@ public:
|
||||
typedef enum { RS_CERTIFICATE_OLD_FORMAT, RS_CERTIFICATE_RADIX } Format;
|
||||
|
||||
/**
|
||||
* @brief Costruct an empty certificate, use toghether with
|
||||
* if(initializeFromString) for safe certificate radix string parsing
|
||||
* @brief Create certificate object from certificate string
|
||||
* @param[in] str radix format certificate string
|
||||
* @param[out] errorCode Optional storage for eventual error code,
|
||||
* meaningful only on failure
|
||||
* @return nullptr on failure, pointer to the generated certificate
|
||||
* otherwise
|
||||
*/
|
||||
RsCertificate() :
|
||||
ipv4_external_ip_and_port{0,0,0,0,0,0},
|
||||
ipv4_internal_ip_and_port{0,0,0,0,0,0},
|
||||
binary_pgp_key(nullptr), binary_pgp_key_size(0),
|
||||
pgp_version("Version: OpenPGP:SDK v0.9"), only_pgp(true),
|
||||
hidden_node(false) {}
|
||||
static std::unique_ptr<RsCertificate> fromString(
|
||||
const std::string& str,
|
||||
uint32_t& errorCode = RS_DEFAULT_STORAGE_PARAM(uint32_t) );
|
||||
|
||||
/**
|
||||
* @brief Initialize from certificate string
|
||||
* @param[in] str radix format string
|
||||
* @param[out] errCode storage for eventual error code
|
||||
* @return false on failure, true otherwise
|
||||
* @brief Create certificate object from peer details and PGP memory block
|
||||
* @param[in] details peer details
|
||||
* @param[in] binary_pgp_block pointer to PGP memory block
|
||||
* @param[in] binary_pgp_block_size size of PGP memory block
|
||||
* @return nullptr on failure, pointer to the generated certificate
|
||||
* otherwise
|
||||
*/
|
||||
bool initializeFromString(const std::string& str, uint32_t& errCode);
|
||||
static std::unique_ptr<RsCertificate> fromMemoryBlock(
|
||||
const RsPeerDetails& details, const uint8_t* binary_pgp_block,
|
||||
size_t binary_pgp_block_size );
|
||||
|
||||
/// Constructs from binary gpg key, and RsPeerDetails.
|
||||
RsCertificate( const RsPeerDetails& details,
|
||||
const unsigned char *gpg_mem_block,
|
||||
size_t gpg_mem_block_size );
|
||||
|
||||
virtual ~RsCertificate();
|
||||
~RsCertificate();
|
||||
|
||||
/// Convert to certificate radix string
|
||||
std::string toStdString() const;
|
||||
@ -86,10 +90,12 @@ public:
|
||||
|
||||
/**
|
||||
* @deprecated using this costructor may raise exception that cause
|
||||
* crash if not handled, use empty constructor + if(initFromString) for a
|
||||
* safer behaviour.
|
||||
* crash if not handled.
|
||||
*/
|
||||
RS_DEPRECATED explicit RsCertificate(const std::string& input_string);
|
||||
RS_DEPRECATED_FOR("RsCertificate::fromMemoryBlock(...)")
|
||||
RsCertificate( const RsPeerDetails& details,
|
||||
const unsigned char *gpg_mem_block,
|
||||
size_t gpg_mem_block_size );
|
||||
|
||||
private:
|
||||
// new radix format
|
||||
@ -105,6 +111,14 @@ private:
|
||||
RsCertificate(const RsCertificate&) {} /// non copy-able
|
||||
const RsCertificate& operator=(const RsCertificate&); /// non copy-able
|
||||
|
||||
/// @brief Costruct an empty certificate
|
||||
RsCertificate() :
|
||||
ipv4_external_ip_and_port{0,0,0,0,0,0},
|
||||
ipv4_internal_ip_and_port{0,0,0,0,0,0},
|
||||
binary_pgp_key(nullptr), binary_pgp_key_size(0),
|
||||
pgp_version("Version: OpenPGP:SDK v0.9"), only_pgp(true),
|
||||
hidden_node(false) {}
|
||||
|
||||
unsigned char ipv4_external_ip_and_port[6];
|
||||
unsigned char ipv4_internal_ip_and_port[6];
|
||||
|
||||
@ -120,5 +134,7 @@ private:
|
||||
|
||||
bool only_pgp ; /// does the cert contain only pgp info?
|
||||
bool hidden_node; /// IP or hidden Node Address.
|
||||
|
||||
RS_SET_CONTEXT_DEBUG_LEVEL(1)
|
||||
};
|
||||
|
||||
|
@ -1217,9 +1217,10 @@ bool p3Peers::loadCertificateFromString(
|
||||
const std::string& cert, RsPeerId& ssl_id,
|
||||
RsPgpId& gpg_id, std::string& error_string )
|
||||
{
|
||||
RsCertificate crt;
|
||||
uint32_t errNum = 0;
|
||||
if(!crt.initializeFromString(cert,errNum))
|
||||
auto crt = RsCertificate::fromString(cert, errNum);
|
||||
|
||||
if(!crt)
|
||||
{
|
||||
error_string = "RsCertificate failed with errno: "
|
||||
+ std::to_string(errNum) + " parsing: " + cert;
|
||||
@ -1227,11 +1228,11 @@ bool p3Peers::loadCertificateFromString(
|
||||
}
|
||||
|
||||
RsPgpId gpgid;
|
||||
bool res = AuthGPG::getAuthGPG()->
|
||||
LoadCertificateFromString(crt.armouredPGPKey(), gpgid,error_string);
|
||||
bool res = AuthGPG::getAuthGPG()->LoadCertificateFromString(
|
||||
crt->armouredPGPKey(), gpgid, error_string );
|
||||
|
||||
gpg_id = gpgid;
|
||||
ssl_id = crt.sslid();
|
||||
ssl_id = crt->sslid();
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -1240,63 +1241,53 @@ bool p3Peers::loadDetailsFromStringCert( const std::string &certstr,
|
||||
RsPeerDetails &pd,
|
||||
uint32_t& error_code )
|
||||
{
|
||||
#ifdef P3PEERS_DEBUG
|
||||
std::cerr << "p3Peers::LoadCertificateFromString() " << std::endl;
|
||||
#endif
|
||||
//parse the text to get ip address
|
||||
try
|
||||
{
|
||||
RsCertificate cert(certstr) ;
|
||||
Dbg3() << __PRETTY_FUNCTION__ << std::endl;
|
||||
|
||||
if(!AuthGPG::getAuthGPG()->getGPGDetailsFromBinaryBlock(cert.pgp_key(),cert.pgp_key_size(), pd.gpg_id,pd.name,pd.gpgSigners))
|
||||
return false;
|
||||
auto certPtr = RsCertificate::fromString(certstr, error_code);
|
||||
if(!certPtr) return false;
|
||||
|
||||
#ifdef P3PEERS_DEBUG
|
||||
std::cerr << "Parsing cert for sslid, location, ext and local address details. : " << certstr << std::endl;
|
||||
#endif
|
||||
RsCertificate& cert = *certPtr;
|
||||
|
||||
pd.id = cert.sslid() ;
|
||||
pd.location = cert.location_name_string();
|
||||
|
||||
pd.isOnlyGPGdetail = pd.id.isNull();
|
||||
pd.service_perm_flags = RS_NODE_PERM_DEFAULT ;
|
||||
|
||||
if (!cert.hidden_node_string().empty())
|
||||
{
|
||||
pd.isHiddenNode = true;
|
||||
|
||||
std::string domain;
|
||||
uint16_t port;
|
||||
if (splitAddressString(cert.hidden_node_string(), domain, port))
|
||||
{
|
||||
pd.hiddenNodeAddress = domain;
|
||||
pd.hiddenNodePort = port;
|
||||
pd.hiddenType = mPeerMgr->hiddenDomainToHiddenType(domain);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pd.isHiddenNode = false;
|
||||
pd.localAddr = cert.loc_ip_string();
|
||||
pd.localPort = cert.loc_port_us();
|
||||
pd.extAddr = cert.ext_ip_string();
|
||||
pd.extPort = cert.ext_port_us();
|
||||
pd.dyndns = cert.dns_string();
|
||||
for(const RsUrl& locator : cert.locators())
|
||||
pd.ipAddressList.push_back(locator.toString());
|
||||
}
|
||||
}
|
||||
catch(uint32_t e)
|
||||
{
|
||||
std::cerr << "ConnectFriendWizard : Parse ip address error :" << e << std::endl;
|
||||
error_code = e;
|
||||
return false ;
|
||||
}
|
||||
|
||||
if (pd.gpg_id.isNull())
|
||||
if(!AuthGPG::getAuthGPG()->getGPGDetailsFromBinaryBlock(
|
||||
cert.pgp_key(), cert.pgp_key_size(),
|
||||
pd.gpg_id, pd.name, pd.gpgSigners ))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
||||
Dbg4() << __PRETTY_FUNCTION__ << " Parsing cert for sslid, location, ext "
|
||||
<< " and local address details. : " << certstr << std::endl;
|
||||
|
||||
pd.id = cert.sslid();
|
||||
pd.location = cert.location_name_string();
|
||||
|
||||
pd.isOnlyGPGdetail = pd.id.isNull();
|
||||
pd.service_perm_flags = RS_NODE_PERM_DEFAULT;
|
||||
|
||||
if (!cert.hidden_node_string().empty())
|
||||
{
|
||||
pd.isHiddenNode = true;
|
||||
|
||||
std::string domain;
|
||||
uint16_t port;
|
||||
if (splitAddressString(cert.hidden_node_string(), domain, port))
|
||||
{
|
||||
pd.hiddenNodeAddress = domain;
|
||||
pd.hiddenNodePort = port;
|
||||
pd.hiddenType = mPeerMgr->hiddenDomainToHiddenType(domain);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pd.isHiddenNode = false;
|
||||
pd.localAddr = cert.loc_ip_string();
|
||||
pd.localPort = cert.loc_port_us();
|
||||
pd.extAddr = cert.ext_ip_string();
|
||||
pd.extPort = cert.ext_port_us();
|
||||
pd.dyndns = cert.dns_string();
|
||||
for(const RsUrl& locator : cert.locators())
|
||||
pd.ipAddressList.push_back(locator.toString());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Peers::cleanCertificate(const std::string &certstr, std::string &cleanCert,int& error_code)
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "retroshare/rspeers.h"
|
||||
#include "util/rsurl.h"
|
||||
#include "util/rsdeprecate.h"
|
||||
#include "util/rsdebug.h"
|
||||
|
||||
class p3LinkMgr;
|
||||
class p3PeerMgr;
|
||||
@ -170,6 +171,8 @@ private:
|
||||
p3LinkMgr *mLinkMgr;
|
||||
p3PeerMgr *mPeerMgr;
|
||||
p3NetMgr *mNetMgr;
|
||||
|
||||
RS_SET_CONTEXT_DEBUG_LEVEL(1)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user