From bc07b16737f04b4ada03e3e4d53c1b25794d9893 Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 11 Aug 2012 20:43:10 +0000 Subject: [PATCH] - added new class for certificate handling. Has two input/output format: classical pgp armoured block (old) and new pure radix format, which is easier to parse and much more robust. - added test program to load/parse certificates in both formats. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@5403 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 2 + libretroshare/src/pgp/pgpkeyutil.cc | 75 +++- libretroshare/src/pgp/pgpkeyutil.h | 10 + libretroshare/src/pgp/rscertificate.cc | 400 ++++++++++++++++++ libretroshare/src/pgp/rscertificate.h | 42 ++ libretroshare/src/tests/pgp/Makefile | 7 +- .../src/tests/pgp/test_certificate.cc | 54 +++ libretroshare/src/util/rsid.h | 1 + 8 files changed, 567 insertions(+), 24 deletions(-) create mode 100644 libretroshare/src/pgp/rscertificate.cc create mode 100644 libretroshare/src/pgp/rscertificate.h create mode 100644 libretroshare/src/tests/pgp/test_certificate.cc diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 1d7ac0863..75ddcbc16 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -376,6 +376,7 @@ HEADERS += pqi/authssl.h \ pqi/authgpg.h \ pgp/pgphandler.h \ pgp/pgpkeyutil.h \ + pgp/rscertificate.h \ pqi/cleanupxpgp.h \ pqi/p3cfgmgr.h \ pqi/p3peermgr.h \ @@ -515,6 +516,7 @@ SOURCES += pqi/authgpg.cc \ pqi/authssl.cc \ pgp/pgphandler.cc \ pgp/pgpkeyutil.cc \ + pgp/rscertificate.cc \ pqi/cleanupxpgp.cc \ pqi/p3cfgmgr.cc \ pqi/p3peermgr.cc \ diff --git a/libretroshare/src/pgp/pgpkeyutil.cc b/libretroshare/src/pgp/pgpkeyutil.cc index 42b088aa4..c24c3a2de 100644 --- a/libretroshare/src/pgp/pgpkeyutil.cc +++ b/libretroshare/src/pgp/pgpkeyutil.cc @@ -24,28 +24,8 @@ bool PGPKeyManagement::createMinimalKey(const std::string& pgp_certificate,std:: { // 0 - Extract Radix64 portion of the certificate // - int n = pgp_certificate.length() ; - int i=0 ; - std::string version_string = "" ; - - while(i < n && pgp_certificate[i] != '\n') ++i ; // remove first part -----BEGIN PGP CERTIFICATE----- - ++i ; - while(i < n && pgp_certificate[i] != '\n') version_string += pgp_certificate[i++] ; // remove first part Version: [fdfdfdf] - ++i ; - while(i < n && pgp_certificate[i] != '\n') ++i ; // remove blank line - - ++i ; - - int j=n-1 ; - - while(j>0 && pgp_certificate[j] != '=' && j>=i) --j ; - - std::string radix_cert = pgp_certificate.substr(i,j-i) ; - -#ifdef DEBUG_PGPUTIL - std::cerr << "extracted radix cert: " << std::endl; - std::cerr << radix_cert ; -#endif + std::string version_string ; + std::string radix_cert = PGPKeyParser::extractRadixPartFromArmouredKey(pgp_certificate,version_string) ; // 1 - Convert armored key into binary key // @@ -106,6 +86,34 @@ bool PGPKeyManagement::createMinimalKey(const std::string& pgp_certificate,std:: } } +std::string PGPKeyParser::extractRadixPartFromArmouredKey(const std::string& pgp_certificate,std::string& version_string) +{ + int n = pgp_certificate.length() ; + int i=0 ; + version_string = "" ; + + while(i < n && pgp_certificate[i] != '\n') ++i ; // remove first part -----BEGIN PGP CERTIFICATE----- + ++i ; + while(i < n && pgp_certificate[i] != '\n') version_string += pgp_certificate[i++] ; // remove first part Version: [fdfdfdf] + ++i ; + while(i < n && pgp_certificate[i] != '\n') ++i ; // remove blank line + + ++i ; + + int j=n-1 ; + + while(j>0 && pgp_certificate[j] != '=' && j>=i) --j ; + + std::string radix_cert = pgp_certificate.substr(i,j-i) ; + +#ifdef DEBUG_PGPUTIL + std::cerr << "extracted radix cert: " << std::endl; + std::cerr << radix_cert ; +#endif + return radix_cert ; +} + + std::string PGPKeyManagement::makeArmouredKey(const unsigned char *keydata,size_t key_size,const std::string& version_string) { std::string outstring ; @@ -164,6 +172,29 @@ uint64_t PGPKeyParser::read_KeyID(unsigned char *& data) return val ; } +uint32_t PGPKeyParser::write_125Size(unsigned char *data,uint32_t size) +{ + if(size < 192) + { + data[0] = size ; + return 1; + } + + if(size < 8384) + { + data[0] = (size >> 8) + 192 ; + data[1] = (size & 255) - 192 ; + } + + data[0] = 0xff ; + data[1] = (size >> 24) & 255 ; + data[2] = (size >> 16) & 255 ; + data[3] = (size >> 8) & 255 ; + data[4] = (size ) & 255 ; + + return 5 ; +} + uint32_t PGPKeyParser::read_125Size(unsigned char *& data) { uint8_t b1 = *data ; diff --git a/libretroshare/src/pgp/pgpkeyutil.h b/libretroshare/src/pgp/pgpkeyutil.h index 1fd7ed9ab..c432408fb 100644 --- a/libretroshare/src/pgp/pgpkeyutil.h +++ b/libretroshare/src/pgp/pgpkeyutil.h @@ -75,10 +75,20 @@ class PGPKeyParser static const uint8_t PGP_PACKET_TAG_USER_ID = 13 ; static const uint8_t PGP_PACKET_TAG_SIGNATURE = 2 ; + // These functions read and move the data pointer to the next byte after the read section. + // static uint64_t read_KeyID(unsigned char *& data) ; static uint32_t read_125Size(unsigned char *& data) ; static uint32_t read_partialBodyLength(unsigned char *& data) ; static void read_packetHeader(unsigned char *& data,uint8_t& packet_tag,uint32_t& packet_length) ; + + // These functions write, and indicate how many bytes where written. + // + static uint32_t write_125Size(unsigned char *data,uint32_t size) ; + + // Helper functions + // + static std::string extractRadixPartFromArmouredKey(const std::string& pgp_cert,std::string& version_string); }; diff --git a/libretroshare/src/pgp/rscertificate.cc b/libretroshare/src/pgp/rscertificate.cc new file mode 100644 index 000000000..27e265f68 --- /dev/null +++ b/libretroshare/src/pgp/rscertificate.cc @@ -0,0 +1,400 @@ +#include +#include +#include +#include + +#include +#include +#include "rscertificate.h" + +static const std::string PGP_CERTIFICATE_START ( "-----BEGIN PGP PUBLIC KEY BLOCK-----" ); +static const std::string PGP_CERTIFICATE_END ( "-----END PGP PUBLIC KEY BLOCK-----" ); +static const std::string EXTERNAL_IP_BEGIN_SECTION ( "--EXT--" ); +static const std::string LOCAL_IP_BEGIN_SECTION ( "--LOCAL--" ); +static const std::string SSLID_BEGIN_SECTION ( "--SSLID--" ); +static const std::string LOCATION_BEGIN_SECTION ( "--LOCATION--" ); + +static const uint8_t CERTIFICATE_PTAG_PGP_SECTION = 0x01 ; +static const uint8_t CERTIFICATE_PTAG_EXTIPANDPORT_SECTION = 0x02 ; +static const uint8_t CERTIFICATE_PTAG_LOCIPANDPORT_SECTION = 0x03 ; +static const uint8_t CERTIFICATE_PTAG_DNS_SECTION = 0x04 ; +static const uint8_t CERTIFICATE_PTAG_SSLID_SECTION = 0x05 ; +static const uint8_t CERTIFICATE_PTAG_NAME_SECTION = 0x06 ; + +std::string RsCertificate::toStdString_oldFormat() const +{ + std::string res ; + + res += PGPKeyManagement::makeArmouredKey(binary_pgp_key,binary_pgp_key_size,pgp_version) ; + + res += SSLID_BEGIN_SECTION ; + res += location_id.toStdString() ; + res += ";" ; + res += LOCATION_BEGIN_SECTION ; + res += location_name ; + res += ";\n" ; + + std::ostringstream os ; + os << LOCAL_IP_BEGIN_SECTION ; + os << (int)ipv4_internal_ip_and_port[0] << "." << (int)ipv4_internal_ip_and_port[1] << "." << (int)ipv4_internal_ip_and_port[2] << "." << (int)ipv4_internal_ip_and_port[3] ; + os << ":" ; + os << ipv4_internal_ip_and_port[4]*256+ipv4_internal_ip_and_port[5] ; + os << ";" ; + + os << EXTERNAL_IP_BEGIN_SECTION ; + 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 << ":" ; + os << ipv4_external_ip_and_port[4]*256+ipv4_external_ip_and_port[5] ; + os << ";" ; + + res += os.str() ; + res += "\n" ; + + return res ; +} + +RsCertificate::~RsCertificate() +{ + delete[] binary_pgp_key ; +} + +void RsCertificate::addPacket(uint8_t ptag, const unsigned char *mem, size_t size, unsigned char *& buf, size_t& offset, size_t& buf_size) +{ + // Check that the buffer has sufficient size. If not, increase it. + + while(offset + size + 6 >= buf_size) + { + unsigned char *newbuf = new unsigned char[2*buf_size] ; + + memcpy(newbuf, buf, buf_size) ; + buf_size *= 2 ; + + delete[] buf ; + + buf = newbuf ; + } + + // Write ptag and size + + buf[offset] = ptag ; + offset += 1 ; + + offset += PGPKeyParser::write_125Size(&buf[offset],size) ; + + // Copy the data + + memcpy(&buf[offset], mem, size) ; + offset += size ; +} + +std::string RsCertificate::toStdString() const +{ + std::string res ; + size_t BS = 1000 ; + size_t p = 0 ; + unsigned char *buf = new unsigned char[BS] ; + + addPacket( CERTIFICATE_PTAG_PGP_SECTION , binary_pgp_key , binary_pgp_key_size , buf, p, BS ) ; + addPacket( CERTIFICATE_PTAG_EXTIPANDPORT_SECTION, ipv4_external_ip_and_port , 6 , buf, p, BS ) ; + addPacket( CERTIFICATE_PTAG_LOCIPANDPORT_SECTION, ipv4_internal_ip_and_port , 6 , buf, p, BS ) ; + addPacket( CERTIFICATE_PTAG_DNS_SECTION , (unsigned char *)dns_name.c_str() , dns_name.length() , buf, p, BS ) ; + addPacket( CERTIFICATE_PTAG_NAME_SECTION , (unsigned char *)location_name.c_str() ,location_name.length() , buf, p, BS ) ; + addPacket( CERTIFICATE_PTAG_SSLID_SECTION , location_id.toByteArray() ,location_id.SIZE_IN_BYTES, buf, p, BS ) ; + + std::string out_string ; + + Radix64::encode((char *)buf, p, out_string) ; + + delete[] buf ; + return out_string ; +} + +RsCertificate::RsCertificate(const std::string& str) + : + location_name(""), + pgp_version(""), + dns_name("") +{ + std::string err_string ; + + if(!initFromString(str,err_string) && !initFromString_oldFormat(str,err_string)) + throw std::runtime_error(err_string) ; +} + +bool RsCertificate::initFromString(const std::string& instr,std::string& err_string) +{ + std::string str ; + + // 0 - clean the string and check that it is pure radix64 + // + for(uint32_t i=0;i= '0' && instr[i] <= '9') || (instr[i] >= 'a' && instr[i] <= 'z') || (instr[i] >= 'A' && instr[i] <= 'Z') || (instr[i] == '+' || instr[i] == '/') || instr[i] == '=')) + return false ; + + str += instr[i] ; + } + + std::cerr << "Decodign from:" << str << std::endl; + // 1 - decode the string. + // + char *bf = NULL ; + size_t size ; + Radix64::decode(str,bf, size) ; + + unsigned char *buf = (unsigned char *)bf ; + size_t total_s = 0 ; + + 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 + ((unsigned long)buf-(unsigned long)buf2) ; + + std::cerr << "Packet parse: read ptag " << (int)ptag << ", size " << size << ", total_s = " << total_s << std::endl; + + switch(ptag) + { + case CERTIFICATE_PTAG_PGP_SECTION: binary_pgp_key = new unsigned char[s] ; + memcpy(binary_pgp_key,buf,s) ; + binary_pgp_key_size = s ; + buf = &buf[s] ; + break ; + + case CERTIFICATE_PTAG_NAME_SECTION: location_name = std::string((char *)buf,s) ; + buf = &buf[s] ; + break ; + + case CERTIFICATE_PTAG_SSLID_SECTION: + if(s != location_id.SIZE_IN_BYTES) + { + err_string = "Inconsistent size in certificate section 'location ID'" ; + return false ; + } + + location_id = SSLIdType(buf) ; + buf = &buf[s] ; + break ; + + case CERTIFICATE_PTAG_DNS_SECTION: dns_name = std::string((char *)buf,s) ; + buf = &buf[s] ; + break ; + + case CERTIFICATE_PTAG_LOCIPANDPORT_SECTION: + if(s != 6) + { + err_string = "Inconsistent size in certificate section 'external IP'" ; + return false ; + } + + memcpy(ipv4_internal_ip_and_port,buf,s) ; + buf = &buf[s] ; + break ; + case CERTIFICATE_PTAG_EXTIPANDPORT_SECTION: + if(s != 6) + { + err_string = "Inconsistent size in certificate section 'external IP'" ; + return false ; + } + + memcpy(ipv4_external_ip_and_port,buf,s) ; + buf = &buf[s] ; + break ; + default: + err_string = "Cannot read certificate. Parsing error in binary packets." ; + return false ; + } + + total_s += s ; + } + + delete[] bf ; + return true ; +} + +bool RsCertificate::initFromString_oldFormat(const std::string& certstr,std::string& err_string) +{ + //parse the text to get ip address + try + { + const std::string CERT_SSL_ID = "--SSLID--"; + const std::string CERT_LOCATION = "--LOCATION--"; + const std::string CERT_LOCAL_IP = "--LOCAL--"; + const std::string CERT_EXT_IP = "--EXT--"; + const std::string CERT_DYNDNS = "--DYNDNS--"; + + std::string cert; + std::string peerInfo; + + /* search for -----END CERTIFICATE----- */ + std::string pgpend("-----END PGP PUBLIC KEY BLOCK-----"); + + size_t pos = certstr.find(pgpend); + + if (pos != std::string::npos) + { + pos += pgpend.length(); + cert = certstr.substr(0, pos); + if (pos + 1 < certstr.length()) + peerInfo = certstr.substr(pos + 1); + } + + if(cert.empty()) + return false ; + + // find radix 64 part. + + std::string radix_cert = PGPKeyParser::extractRadixPartFromArmouredKey(certstr,pgp_version) ; + + char *key_bin ; + Radix64::decode(radix_cert,key_bin,binary_pgp_key_size) ; + + binary_pgp_key = (unsigned char *)key_bin ; + +#ifdef P3PEERS_DEBUG + std::cerr << "Parsing cert for sslid, location, ext and local address details. : " << certstr << std::endl; +#endif + + //let's parse the ssl id + size_t parsePosition = peerInfo.find(CERT_SSL_ID); + std::cerr << "sslid position : " << parsePosition << std::endl; + if (parsePosition != std::string::npos) { + parsePosition += CERT_SSL_ID.length(); + std::string subCert = peerInfo.substr(parsePosition); + parsePosition = subCert.find(";"); + if (parsePosition != std::string::npos) { + std::string ssl_id = subCert.substr(0, parsePosition); + std::cerr << "SSL id : " << ssl_id << std::endl; + + location_id = SSLIdType(ssl_id) ; + } + } + + //let's parse the location + parsePosition = peerInfo.find(CERT_LOCATION); + std::cerr << "location position : " << parsePosition << std::endl; + if (parsePosition != std::string::npos) { + parsePosition += CERT_LOCATION.length(); + std::string subCert = peerInfo.substr(parsePosition); + parsePosition = subCert.find(";"); + if (parsePosition != std::string::npos) { + std::string location = subCert.substr(0, parsePosition); + std::cerr << "location : " << location << std::endl; + + location_name = location; + } + } + + //let's parse ip local address + parsePosition = peerInfo.find(CERT_LOCAL_IP); + std::cerr << "local ip position : " << parsePosition << std::endl; + if (parsePosition != std::string::npos) { + parsePosition += CERT_LOCAL_IP.length(); + std::string subCert = peerInfo.substr(parsePosition); + parsePosition = subCert.find(":"); + if (parsePosition != std::string::npos) { + std::string local_ip = subCert.substr(0, parsePosition); + std::cerr << "Local Ip : " << local_ip << std::endl; + + unsigned short localPort ; + + //let's parse local port + subCert = subCert.substr(parsePosition + 1); + parsePosition = subCert.find(";"); + if (parsePosition != std::string::npos) { + std::string local_port = subCert.substr(0, parsePosition); + std::cerr << "Local port : " << local_port << std::endl; + sscanf(local_port.c_str(), "%hu", &localPort); + } + + int d0,d1,d2,d3 ; + + if(4 != sscanf(local_ip.c_str(),"%d.%d.%d.%d",&d0,&d1,&d2,&d3)) + { + err_string = "Cannot parse ip from given string." ; + return false ; + } + ipv4_internal_ip_and_port[0] = d0 ; + ipv4_internal_ip_and_port[1] = d1 ; + ipv4_internal_ip_and_port[2] = d2 ; + ipv4_internal_ip_and_port[3] = d3 ; + + ipv4_internal_ip_and_port[4] = (localPort >> 8 ) & 0xff ; + ipv4_internal_ip_and_port[5] = localPort & 0xff ; + } + } + + //let's parse ip ext address + parsePosition = peerInfo.find(CERT_EXT_IP); + std::cerr << "Ext ip position : " << parsePosition << std::endl; + if (parsePosition != std::string::npos) { + parsePosition = parsePosition + CERT_EXT_IP.length(); + std::string subCert = peerInfo.substr(parsePosition); + parsePosition = subCert.find(":"); + if (parsePosition != std::string::npos) { + std::string ext_ip = subCert.substr(0, parsePosition); + std::cerr << "Ext Ip : " << ext_ip << std::endl; + + unsigned short extPort ; + //let's parse ext port + subCert = subCert.substr(parsePosition + 1); + parsePosition = subCert.find(";"); + if (parsePosition != std::string::npos) { + std::string ext_port = subCert.substr(0, parsePosition); + std::cerr << "Ext port : " << ext_port << std::endl; + sscanf(ext_port.c_str(), "%hu", &extPort); + } + + int d0,d1,d2,d3 ; + + if(4 != sscanf(ext_ip.c_str(),"%d.%d.%d.%d",&d0,&d1,&d2,&d3)) + { + err_string = "Cannot parse ip from given string." ; + return false ; + } + ipv4_external_ip_and_port[0] = d0 ; + ipv4_external_ip_and_port[1] = d1 ; + ipv4_external_ip_and_port[2] = d2 ; + ipv4_external_ip_and_port[3] = d3 ; + + ipv4_external_ip_and_port[4] = (extPort >> 8 ) & 0xff ; + ipv4_external_ip_and_port[5] = extPort & 0xff ; + } + } + + //let's parse DynDNS + parsePosition = peerInfo.find(CERT_DYNDNS); + std::cerr << "location DynDNS : " << parsePosition << std::endl; + if (parsePosition != std::string::npos) { + parsePosition += CERT_DYNDNS.length(); + std::string subCert = peerInfo.substr(parsePosition); + parsePosition = subCert.find(";"); + if (parsePosition != std::string::npos) { + std::string DynDNS = subCert.substr(0, parsePosition); + std::cerr << "DynDNS : " << DynDNS << std::endl; + + dns_name = DynDNS; + } + } + + } + catch (...) + { + std::cerr << "ConnectFriendWizard : Parse ip address error." << std::endl; + return false ; + } + + return true; +} + + + + + diff --git a/libretroshare/src/pgp/rscertificate.h b/libretroshare/src/pgp/rscertificate.h new file mode 100644 index 000000000..d76a71d4c --- /dev/null +++ b/libretroshare/src/pgp/rscertificate.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include + +static const int SSL_ID_SIZE = 16 ; + +typedef t_RsGenericIdType SSLIdType ; + +class RsCertificate +{ + public: + // Constructs from text + RsCertificate(const std::string& input_string) ; + + virtual ~RsCertificate(); + + // Outut to text + std::string toStdString_oldFormat() const ; + std::string toStdString() const ; + + private: + bool initFromString(const std::string& str,std::string& err_string) ; + bool initFromString_oldFormat(const std::string& str,std::string& err_string) ; + + static void addPacket(uint8_t ptag, const unsigned char *mem, size_t size, unsigned char *& buf, size_t& offset, size_t& buf_size) ; + + RsCertificate(const RsCertificate&) {} // non copy-able + const RsCertificate& operator=(const RsCertificate&) { return *this ;} // non copy-able + + unsigned char ipv4_external_ip_and_port[6] ; + unsigned char ipv4_internal_ip_and_port[6] ; + + unsigned char *binary_pgp_key ; + size_t binary_pgp_key_size ; + + std::string location_name ; + SSLIdType location_id ; + std::string pgp_version ; + std::string dns_name ; +}; + diff --git a/libretroshare/src/tests/pgp/Makefile b/libretroshare/src/tests/pgp/Makefile index 70b5d2570..8ad431885 100644 --- a/libretroshare/src/tests/pgp/Makefile +++ b/libretroshare/src/tests/pgp/Makefile @@ -10,13 +10,16 @@ OPENPGP_INCLUDE_DIR = ../../../../openpgpsdk/src include $(RS_TOP_DIR)/tests/scripts/config.mk ############################################################### -TESTOBJ = test_pgp_handler.o test_pgp_signature_parsing.o test_key_parsing.o -TESTS = test_pgp_handler test_pgp_signature_parsing test_key_parsing +TESTOBJ = test_pgp_handler.o test_pgp_signature_parsing.o test_key_parsing.o test_certificate.o +TESTS = test_pgp_handler test_pgp_signature_parsing test_key_parsing test_certificate #rsbaseitem_test all: tests +test_certificate : test_certificate.o + $(CC) $(CFLAGS) -o test_certificate test_certificate.o $(OBJ) $(LIBS) -L../../../../openpgpsdk/src/lib/ -lops -lbz2 + test_pgp_handler : test_pgp_handler.o $(CC) $(CFLAGS) -o test_pgp_handler test_pgp_handler.o $(OBJ) $(LIBS) -L../../../../openpgpsdk/src/lib/ -lops -lbz2 diff --git a/libretroshare/src/tests/pgp/test_certificate.cc b/libretroshare/src/tests/pgp/test_certificate.cc new file mode 100644 index 000000000..f06c1df39 --- /dev/null +++ b/libretroshare/src/tests/pgp/test_certificate.cc @@ -0,0 +1,54 @@ +#include + +#include "argstream.h" +#include + +int main(int argc,char *argv[]) +{ + try + { + argstream as(argc,argv) ; + std::string keyfile ; + + as >> parameter('i',"input",keyfile,"input certificate file (old or new formats)",true) + >> help() ; + + as.defaultErrorHandling() ; + + FILE *f = fopen(keyfile.c_str(),"rb") ; + + if(f == NULL) + throw std::runtime_error("Cannot open file. Sorry.") ; + + std::string res ; + char c ; + + while( (c = fgetc(f)) != EOF) + res += c ; + + fclose(f) ; + + std::cerr << "Read this string from the file:" << std::endl; + std::cerr << "==========================================" << std::endl; + std::cerr << res << std::endl; + std::cerr << "==========================================" << std::endl; + std::cerr << "Parsing..." << std::endl; + + RsCertificate cert(res) ; + + std::cerr << "Output from certificate:" << std::endl; + + std::cerr << cert.toStdString_oldFormat() << std::endl ; + + std::cerr << "Output from certificate (new format):" << std::endl; + std::cerr << cert.toStdString() << std::endl ; + + return 0; + } + catch(std::exception& e) + { + std::cerr << "Exception never handled: " << e.what() << std::endl; + return 1 ; + } +} + diff --git a/libretroshare/src/util/rsid.h b/libretroshare/src/util/rsid.h index 464999a5d..51b529c08 100644 --- a/libretroshare/src/util/rsid.h +++ b/libretroshare/src/util/rsid.h @@ -27,6 +27,7 @@ // #include #include +#include template class t_RsGenericIdType {