From 4bd5aaa9b28ad0bfd4084ca595d5d3eeca174dcc Mon Sep 17 00:00:00 2001
From: csoler <csoler@users.sourceforge.net>
Date: Sun, 9 Jun 2019 15:03:48 +0200
Subject: [PATCH] added parsing of short invites in connect friend wizard (not
 working yet)

---
 libretroshare/src/pgp/rscertificate.cc        | 18 +++++--
 libretroshare/src/pgp/rscertificate.h         |  5 +-
 libretroshare/src/retroshare/rspeers.h        |  2 +-
 libretroshare/src/rsserver/p3peers.cc         | 13 ++++-
 libretroshare/src/rsserver/p3peers.h          |  2 +-
 .../src/gui/connect/ConnectFriendWizard.cpp   | 53 ++++++++++++++-----
 6 files changed, 69 insertions(+), 24 deletions(-)

diff --git a/libretroshare/src/pgp/rscertificate.cc b/libretroshare/src/pgp/rscertificate.cc
index 11ada52a6..fff50fd61 100644
--- a/libretroshare/src/pgp/rscertificate.cc
+++ b/libretroshare/src/pgp/rscertificate.cc
@@ -552,14 +552,22 @@ 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))
+	if(cleanRadix64(input,output,error_code))
 	{
+        RsPeerDetails details;
+
+        if(rsPeers->parseShortInvite(output,details))
+        {
+            format = RS_CERTIFICATE_SHORT_RADIX;
+            return true;
+        }
+
 		format = RS_CERTIFICATE_RADIX;
+
 		if(!check_content) return true;
+
 		uint32_t errCode;
 		auto crt = RsCertificate::fromString(input, errCode);
 		error_code = static_cast<int>(errCode);
@@ -576,7 +584,7 @@ std::string RsCertificate::armouredPGPKey() const
 
 // Yeah, this is simple, and that is what's good about the radix format. Can't be broken ;-)
 //
-bool RsCertificate::cleanCertificate(const std::string& instr,std::string& str,int& error_code)
+bool RsCertificate::cleanRadix64(const std::string& instr,std::string& str,int& error_code)
 {
 	error_code = RS_PEER_CERT_CLEANING_CODE_NO_ERROR ;
 
diff --git a/libretroshare/src/pgp/rscertificate.h b/libretroshare/src/pgp/rscertificate.h
index 7f80a30d1..2d506d03f 100644
--- a/libretroshare/src/pgp/rscertificate.h
+++ b/libretroshare/src/pgp/rscertificate.h
@@ -36,7 +36,7 @@ struct RsPeerDetails;
 class RsCertificate
 {
 public:
-	typedef enum { RS_CERTIFICATE_OLD_FORMAT, RS_CERTIFICATE_RADIX } Format;
+	typedef enum { RS_CERTIFICATE_OLD_FORMAT, RS_CERTIFICATE_RADIX, RS_CERTIFICATE_SHORT_RADIX } Format;
 
 	/**
 	 * @brief Create certificate object from certificate string
@@ -99,8 +99,7 @@ public:
 
 private:
 	// new radix format
-	static bool cleanCertificate( const std::string& input,
-	                              std::string& output, int&);
+	static bool cleanRadix64( const std::string& input, std::string& output, int&);
 
 	static void scan_ip( const std::string& ip_string, unsigned short port,
 	                     unsigned char *destination_memory );
diff --git a/libretroshare/src/retroshare/rspeers.h b/libretroshare/src/retroshare/rspeers.h
index 7f1551f69..f15272397 100644
--- a/libretroshare/src/retroshare/rspeers.h
+++ b/libretroshare/src/retroshare/rspeers.h
@@ -717,7 +717,7 @@ public:
 	        uint32_t& errorCode ) = 0;
 
 	// Certificate utils
-	virtual	bool cleanCertificate(const std::string &certstr, std::string &cleanCert,int& error_code) = 0;
+	virtual	bool cleanCertificate(const std::string &certstr, std::string &cleanCert,bool& is_short_format,int& error_code) = 0;
 	virtual	bool saveCertificateToFile(const RsPeerId& id, const std::string &fname) = 0;
 	virtual	std::string saveCertificateToString(const RsPeerId &id) = 0;
 
diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc
index 1c68d5c71..eadc2fd75 100644
--- a/libretroshare/src/rsserver/p3peers.cc
+++ b/libretroshare/src/rsserver/p3peers.cc
@@ -1536,11 +1536,20 @@ bool p3Peers::loadDetailsFromStringCert( const std::string &certstr,
 	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,bool& is_short_format,int& error_code)
 {
 	RsCertificate::Format format ;
 
-	return RsCertificate::cleanCertificate(certstr,cleanCert,format,error_code,true) ;
+	bool res = RsCertificate::cleanCertificate(certstr,cleanCert,format,error_code,true) ;
+
+    if(format == RsCertificate::RS_CERTIFICATE_RADIX)
+        is_short_format = false;
+    else if(format == RsCertificate::RS_CERTIFICATE_SHORT_RADIX)
+        is_short_format = true;
+    else
+        return false ;
+
+    return res;
 }
 
 bool 	p3Peers::saveCertificateToFile(const RsPeerId &id, const std::string &/*fname*/)
diff --git a/libretroshare/src/rsserver/p3peers.h b/libretroshare/src/rsserver/p3peers.h
index c6bc82704..5e1dd5fed 100644
--- a/libretroshare/src/rsserver/p3peers.h
+++ b/libretroshare/src/rsserver/p3peers.h
@@ -157,7 +157,7 @@ public:
 	virtual	bool loadCertificateFromString(const std::string& cert, RsPeerId& ssl_id,RsPgpId& pgp_id, std::string& error_string);
 	virtual	bool loadDetailsFromStringCert(const std::string &cert, RsPeerDetails &pd, uint32_t& error_code);
 
-	virtual	bool cleanCertificate(const std::string &certstr, std::string &cleanCert,int& error_code);
+	virtual	bool cleanCertificate(const std::string &certstr, std::string &cleanCert, bool &is_short_format, int& error_code) override;
 	virtual	bool saveCertificateToFile(const RsPeerId &id, const std::string &fname);
 	virtual	std::string saveCertificateToString(const RsPeerId &id);
 
diff --git a/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp b/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp
index b58e8f94d..2368b7bc3 100755
--- a/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp
+++ b/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp
@@ -299,8 +299,6 @@ void ConnectFriendWizard::setCertificate(const QString &certificate, bool friend
 		{
 			mCertificate = certificate.toUtf8().constData();
 
-			// Cyril: I disabled this because it seems to be not used anymore.
-			//setStartId(friendRequest ? Page_FriendRequest : Page_Conclusion);
 			setStartId(Page_Conclusion);
 			if (friendRequest){
 				ui->cp_Label->show();
@@ -309,7 +307,31 @@ void ConnectFriendWizard::setCertificate(const QString &certificate, bool friend
 				ui->ConclusionPage->setSubTitle(tr("Details about the request"));
 			}
 		}
-    } else {
+    }
+    else if(rsPeers->parseShortInvite(certificate.toUtf8().constData(),peerDetails))
+    {
+		if(peerDetails.id == rsPeers->getOwnId())
+		{
+			setField("errorMessage", tr("This is your own certificate! You would not want to make friend with yourself. Wouldn't you?") ) ;
+			error = false;
+			setStartId(Page_ErrorMessage);
+		}
+		else
+		{
+			mCertificate = certificate.toUtf8().constData();
+
+			setStartId(Page_Conclusion);
+
+			if (friendRequest){
+				ui->cp_Label->show();
+				ui->requestinfolabel->show();
+				setTitleText(ui->ConclusionPage, tr("Friend request"));
+				ui->ConclusionPage->setSubTitle(tr("Details about the request"));
+			}
+		}
+	}
+    else
+    {
 		// error message
 		setField("errorMessage", tr("Certificate Load Failed") + ": \n\n" + getErrorString(cert_load_error_code)) ;
 		setStartId(Page_ErrorMessage);
@@ -702,7 +724,8 @@ bool ConnectFriendWizard::validateCurrentPage()
 			std::string certstr = ui->friendCertEdit->toPlainText().toUtf8().constData();
 			uint32_t cert_load_error_code;
 
-			if (rsPeers->loadDetailsFromStringCert(certstr, peerDetails, cert_load_error_code)) {
+			if (rsPeers->loadDetailsFromStringCert(certstr, peerDetails, cert_load_error_code) || rsPeers->parseShortInvite(certstr,peerDetails))
+            {
 				mCertificate = certstr;
 #ifdef FRIEND_WIZARD_DEBUG
 				std::cerr << "ConnectFriendWizard got id : " << peerDetails.id << "; gpg_id : " << peerDetails.gpg_id << std::endl;
@@ -742,7 +765,8 @@ bool ConnectFriendWizard::validateCurrentPage()
 				}
 
 				uint32_t cert_error_code;
-				if (rsPeers->loadDetailsFromStringCert(certstr, peerDetails, cert_error_code)) {
+				if (rsPeers->loadDetailsFromStringCert(certstr, peerDetails, cert_error_code) || rsPeers->parseShortInvite(certstr,peerDetails))
+                {
 					mCertificate = certstr;
 #ifdef FRIEND_WIZARD_DEBUG
 					std::cerr << "ConnectFriendWizard got id : " << peerDetails.id << "; gpg_id : " << peerDetails.gpg_id << std::endl;
@@ -1058,18 +1082,23 @@ void ConnectFriendWizard::cleanFriendCert()
 	} else {
 		std::string cleanCert;
 		int error_code;
+        bool is_short_format;
 
-		if (rsPeers->cleanCertificate(cert, cleanCert, error_code)) {
+		if (rsPeers->cleanCertificate(cert, cleanCert, is_short_format, error_code))
+        {
 			certValid = true;
-			if (cert != cleanCert) {
-				disconnect(ui->friendCertEdit, SIGNAL(textChanged()), this, SLOT(friendCertChanged()));
+
+			if (cert != cleanCert)
+            {
 				QTextCursor textCursor = ui->friendCertEdit->textCursor();
-				ui->friendCertEdit->setPlainText(QString::fromUtf8(cleanCert.c_str()));
-				ui->friendCertEdit->setTextCursor(textCursor);
+
+				whileBlocking(ui->friendCertEdit)->setPlainText(QString::fromUtf8(cleanCert.c_str()));
+				whileBlocking(ui->friendCertEdit)->setTextCursor(textCursor);
+
 				ui->friendCertCleanLabel->setStyleSheet("");
-				connect(ui->friendCertEdit, SIGNAL(textChanged()), this, SLOT(friendCertChanged()));
 			}
-			errorMsg = tr("Certificate appears to be valid");
+			errorMsg = tr("Valid certificate") + (is_short_format?" (Short format)":" (plain format with profile key)");
+
 			ui->friendCertCleanLabel->setPixmap(QPixmap(":/images/accepted16.png"));
 		} else {
 			if (error_code > 0) {