mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-26 01:31:30 -05:00
Merge pull request #1549 from G10h4ck/rscert_cleanup
Safer RsCertificate API
This commit is contained in:
commit
ccf7dc24b8
@ -3,8 +3,8 @@
|
|||||||
* *
|
* *
|
||||||
* libretroshare: retroshare core library *
|
* libretroshare: retroshare core library *
|
||||||
* *
|
* *
|
||||||
* Copyright 2016 Cyril Soler <csoler@users.sourceforge.net> *
|
* Copyright (C) 2016 Cyril Soler <csoler@users.sourceforge.net> *
|
||||||
* Copyright 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
|
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||||
* *
|
* *
|
||||||
* This program is free software: you can redistribute it and/or modify *
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
@ -31,6 +31,7 @@
|
|||||||
#include "rscertificate.h"
|
#include "rscertificate.h"
|
||||||
#include "util/rsstring.h"
|
#include "util/rsstring.h"
|
||||||
#include "util/stacktrace.h"
|
#include "util/stacktrace.h"
|
||||||
|
#include "util/rsdebug.h"
|
||||||
|
|
||||||
//#define DEBUG_RSCERTIFICATE
|
//#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 == '=' ;
|
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '+' || c == '/' || c == '=' ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RsCertificate::~RsCertificate()
|
RsCertificate::~RsCertificate()
|
||||||
{
|
{
|
||||||
delete[] binary_pgp_key ;
|
delete[] binary_pgp_key ;
|
||||||
@ -166,28 +168,16 @@ std::string RsCertificate::toStdString() const
|
|||||||
return out2 ;
|
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)
|
RsCertificate::RsCertificate(const RsPeerDetails& Detail, const unsigned char *binary_pgp_block,size_t binary_pgp_block_size)
|
||||||
:pgp_version("Version: OpenPGP:SDK v0.9")
|
:pgp_version("Version: OpenPGP:SDK v0.9")
|
||||||
{
|
{
|
||||||
if(binary_pgp_block_size == 0 || binary_pgp_block == NULL)
|
if(binary_pgp_block_size == 0 || binary_pgp_block == nullptr)
|
||||||
throw std::runtime_error("Cannot init a certificate with a void key block.") ;
|
{
|
||||||
|
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] ;
|
binary_pgp_key = new unsigned char[binary_pgp_block_size] ;
|
||||||
memcpy(binary_pgp_key,binary_pgp_block,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)
|
void RsCertificate::scan_ip(const std::string& ip_string, unsigned short port,unsigned char *ip_and_port)
|
||||||
{
|
{
|
||||||
int d0,d1,d2,d3 ;
|
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 ;
|
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 ;
|
if(instr[i] == ' ' || instr[i] == '\t' || instr[i] == '\n')
|
||||||
err_code = CERTIFICATE_PARSING_ERROR_NO_ERROR ;
|
continue;
|
||||||
|
|
||||||
// 0 - clean the string and check that it is pure radix64
|
if(! is_acceptable_radix64Char(instr[i]))
|
||||||
//
|
return nullptr;
|
||||||
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]))
|
str += 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 ;
|
|
||||||
}
|
}
|
||||||
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)
|
uint8_t ptag = buf[0];
|
||||||
delete[] binary_pgp_key ;
|
buf = &buf[1];
|
||||||
|
|
||||||
err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR ;
|
unsigned char *buf2 = buf;
|
||||||
return false ;
|
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
|
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] ;
|
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() ;
|
return os.str() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RsCertificate::loc_ip_string() const
|
std::string RsCertificate::loc_ip_string() const
|
||||||
{
|
{
|
||||||
std::ostringstream os ;
|
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] ;
|
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))
|
if(cleanCertificate(input,output,error_code))
|
||||||
{
|
{
|
||||||
format = RS_CERTIFICATE_RADIX ;
|
format = RS_CERTIFICATE_RADIX;
|
||||||
|
if(!check_content) return true;
|
||||||
if(!check_content)
|
uint32_t errCode;
|
||||||
return true ;
|
auto crt = RsCertificate::fromString(input, errCode);
|
||||||
|
error_code = static_cast<int>(errCode);
|
||||||
try
|
return crt != nullptr;
|
||||||
{
|
|
||||||
RsCertificate c(input) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
catch(uint32_t err_code)
|
|
||||||
{
|
|
||||||
error_code = err_code ;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false ;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RsCertificate::armouredPGPKey() const
|
std::string RsCertificate::armouredPGPKey() const
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
* *
|
* *
|
||||||
* libretroshare: retroshare core library *
|
* 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 *
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
@ -23,9 +24,12 @@
|
|||||||
|
|
||||||
#include "retroshare/rstypes.h"
|
#include "retroshare/rstypes.h"
|
||||||
#include "util/rsurl.h"
|
#include "util/rsurl.h"
|
||||||
|
#include "util/rsmemory.h"
|
||||||
|
#include "util/rsdebug.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
struct RsPeerDetails;
|
struct RsPeerDetails;
|
||||||
|
|
||||||
@ -35,30 +39,30 @@ public:
|
|||||||
typedef enum { RS_CERTIFICATE_OLD_FORMAT, RS_CERTIFICATE_RADIX } Format;
|
typedef enum { RS_CERTIFICATE_OLD_FORMAT, RS_CERTIFICATE_RADIX } Format;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Costruct an empty certificate, use toghether with
|
* @brief Create certificate object from certificate string
|
||||||
* if(initializeFromString) for safe certificate radix string parsing
|
* @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() :
|
static std::unique_ptr<RsCertificate> fromString(
|
||||||
ipv4_external_ip_and_port{0,0,0,0,0,0},
|
const std::string& str,
|
||||||
ipv4_internal_ip_and_port{0,0,0,0,0,0},
|
uint32_t& errorCode = RS_DEFAULT_STORAGE_PARAM(uint32_t) );
|
||||||
binary_pgp_key(nullptr), binary_pgp_key_size(0),
|
|
||||||
pgp_version("Version: OpenPGP:SDK v0.9"), only_pgp(true),
|
|
||||||
hidden_node(false) {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize from certificate string
|
* @brief Create certificate object from peer details and PGP memory block
|
||||||
* @param[in] str radix format string
|
* @param[in] details peer details
|
||||||
* @param[out] errCode storage for eventual error code
|
* @param[in] binary_pgp_block pointer to PGP memory block
|
||||||
* @return false on failure, true otherwise
|
* @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();
|
||||||
RsCertificate( const RsPeerDetails& details,
|
|
||||||
const unsigned char *gpg_mem_block,
|
|
||||||
size_t gpg_mem_block_size );
|
|
||||||
|
|
||||||
virtual ~RsCertificate();
|
|
||||||
|
|
||||||
/// Convert to certificate radix string
|
/// Convert to certificate radix string
|
||||||
std::string toStdString() const;
|
std::string toStdString() const;
|
||||||
@ -86,10 +90,12 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated using this costructor may raise exception that cause
|
* @deprecated using this costructor may raise exception that cause
|
||||||
* crash if not handled, use empty constructor + if(initFromString) for a
|
* crash if not handled.
|
||||||
* safer behaviour.
|
|
||||||
*/
|
*/
|
||||||
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:
|
private:
|
||||||
// new radix format
|
// new radix format
|
||||||
@ -105,6 +111,14 @@ private:
|
|||||||
RsCertificate(const RsCertificate&) {} /// non copy-able
|
RsCertificate(const RsCertificate&) {} /// non copy-able
|
||||||
const RsCertificate& operator=(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_external_ip_and_port[6];
|
||||||
unsigned char ipv4_internal_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 only_pgp ; /// does the cert contain only pgp info?
|
||||||
bool hidden_node; /// IP or hidden Node Address.
|
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,
|
const std::string& cert, RsPeerId& ssl_id,
|
||||||
RsPgpId& gpg_id, std::string& error_string )
|
RsPgpId& gpg_id, std::string& error_string )
|
||||||
{
|
{
|
||||||
RsCertificate crt;
|
|
||||||
uint32_t errNum = 0;
|
uint32_t errNum = 0;
|
||||||
if(!crt.initializeFromString(cert,errNum))
|
auto crt = RsCertificate::fromString(cert, errNum);
|
||||||
|
|
||||||
|
if(!crt)
|
||||||
{
|
{
|
||||||
error_string = "RsCertificate failed with errno: "
|
error_string = "RsCertificate failed with errno: "
|
||||||
+ std::to_string(errNum) + " parsing: " + cert;
|
+ std::to_string(errNum) + " parsing: " + cert;
|
||||||
@ -1227,11 +1228,11 @@ bool p3Peers::loadCertificateFromString(
|
|||||||
}
|
}
|
||||||
|
|
||||||
RsPgpId gpgid;
|
RsPgpId gpgid;
|
||||||
bool res = AuthGPG::getAuthGPG()->
|
bool res = AuthGPG::getAuthGPG()->LoadCertificateFromString(
|
||||||
LoadCertificateFromString(crt.armouredPGPKey(), gpgid,error_string);
|
crt->armouredPGPKey(), gpgid, error_string );
|
||||||
|
|
||||||
gpg_id = gpgid;
|
gpg_id = gpgid;
|
||||||
ssl_id = crt.sslid();
|
ssl_id = crt->sslid();
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -1240,63 +1241,53 @@ bool p3Peers::loadDetailsFromStringCert( const std::string &certstr,
|
|||||||
RsPeerDetails &pd,
|
RsPeerDetails &pd,
|
||||||
uint32_t& error_code )
|
uint32_t& error_code )
|
||||||
{
|
{
|
||||||
#ifdef P3PEERS_DEBUG
|
Dbg3() << __PRETTY_FUNCTION__ << std::endl;
|
||||||
std::cerr << "p3Peers::LoadCertificateFromString() " << std::endl;
|
|
||||||
#endif
|
|
||||||
//parse the text to get ip address
|
|
||||||
try
|
|
||||||
{
|
|
||||||
RsCertificate cert(certstr) ;
|
|
||||||
|
|
||||||
if(!AuthGPG::getAuthGPG()->getGPGDetailsFromBinaryBlock(cert.pgp_key(),cert.pgp_key_size(), pd.gpg_id,pd.name,pd.gpgSigners))
|
auto certPtr = RsCertificate::fromString(certstr, error_code);
|
||||||
return false;
|
if(!certPtr) return false;
|
||||||
|
|
||||||
#ifdef P3PEERS_DEBUG
|
RsCertificate& cert = *certPtr;
|
||||||
std::cerr << "Parsing cert for sslid, location, ext and local address details. : " << certstr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pd.id = cert.sslid() ;
|
if(!AuthGPG::getAuthGPG()->getGPGDetailsFromBinaryBlock(
|
||||||
pd.location = cert.location_name_string();
|
cert.pgp_key(), cert.pgp_key_size(),
|
||||||
|
pd.gpg_id, pd.name, pd.gpgSigners ))
|
||||||
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())
|
|
||||||
return false;
|
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)
|
bool p3Peers::cleanCertificate(const std::string &certstr, std::string &cleanCert,int& error_code)
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "retroshare/rspeers.h"
|
#include "retroshare/rspeers.h"
|
||||||
#include "util/rsurl.h"
|
#include "util/rsurl.h"
|
||||||
#include "util/rsdeprecate.h"
|
#include "util/rsdeprecate.h"
|
||||||
|
#include "util/rsdebug.h"
|
||||||
|
|
||||||
class p3LinkMgr;
|
class p3LinkMgr;
|
||||||
class p3PeerMgr;
|
class p3PeerMgr;
|
||||||
@ -170,6 +171,8 @@ private:
|
|||||||
p3LinkMgr *mLinkMgr;
|
p3LinkMgr *mLinkMgr;
|
||||||
p3PeerMgr *mPeerMgr;
|
p3PeerMgr *mPeerMgr;
|
||||||
p3NetMgr *mNetMgr;
|
p3NetMgr *mNetMgr;
|
||||||
|
|
||||||
|
RS_SET_CONTEXT_DEBUG_LEVEL(1)
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user