Review1
This commit is contained in:
		
							
								
								
									
										22
									
								
								asymcrypt.go
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								asymcrypt.go
									
									
									
									
									
								
							@@ -66,41 +66,41 @@ func Decrypt(privateKey string, data []byte) ([]byte, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error().Msg("Message decryption b64 failed")
 | 
							log.Error().Msg("Message decryption b64 failed")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	decrypted, err := helper.DecryptBinaryMessageArmored(string(priv), []byte(""), string(data))
 | 
						decrypted, err := helper.DecryptBinaryMessageArmored(string(priv), nil, string(data))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error().Msg("Message decryption failed")
 | 
							log.Error().Msg("Message decryption failed")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return []byte(decrypted), err
 | 
						return []byte(decrypted), err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func EncryptAndSign(publicKey string, privateKey string, data []byte) ([]byte, []byte, error) {
 | 
					func EncryptAndSign(publicEncKey string, privateSignKey string, data []byte) ([]byte, []byte, error) {
 | 
				
			||||||
	pub, err := base64.StdEncoding.DecodeString(publicKey)
 | 
						pub, err := base64.StdEncoding.DecodeString(publicEncKey)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error().Msg("Message encryption and sign b64 failed")
 | 
							log.Error().Msg("Message encryption and sign b64 failed")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	priv, err := base64.StdEncoding.DecodeString(privateKey)
 | 
						priv, err := base64.StdEncoding.DecodeString(privateSignKey)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error().Msg("Message encryption and sign b64 failed")
 | 
							log.Error().Msg("Message encryption and sign b64 failed")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	armor, signature, err := helper.EncryptSignBinaryDetached(string(pub), string(priv), []byte(""), data)
 | 
						encrypted, signature, err := helper.EncryptSignBinaryDetached(string(pub), string(priv), nil, data)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error().Msg("Message encryption and sign failed")
 | 
							log.Error().Msg("Message encryption and sign failed")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return []byte(armor), []byte(signature), err
 | 
						return []byte(encrypted), []byte(signature), err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func DecryptAndSign(publicKey string, privateKey string, data []byte, signature []byte) ([]byte, error) {
 | 
					func DecryptAndCheck(MyPrivateEncryptionKey string, peerContactPublicKey string, data []byte, signature []byte) (DecryptedMessage []byte, err error) {
 | 
				
			||||||
	pub, err := base64.StdEncoding.DecodeString(publicKey)
 | 
						pub, err := base64.StdEncoding.DecodeString(MyPrivateEncryptionKey)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error().Msg("Message decryption and sign b64 failed")
 | 
							log.Error().Msg("Message decryption and sign b64 failed")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	priv, err := base64.StdEncoding.DecodeString(privateKey)
 | 
						priv, err := base64.StdEncoding.DecodeString(peerContactPublicKey)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error().Msg("Message decryption and sign b64 failed")
 | 
							log.Error().Msg("Message decryption and sign b64 failed")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	decrypted, err := helper.DecryptVerifyBinaryDetached(string(pub), string(priv), []byte(""), data, string(signature))
 | 
						DecryptedMessage, err = helper.DecryptVerifyBinaryDetached(string(pub), string(priv), nil, data, string(signature))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error().Msg("Message decryption and sign failed")
 | 
							log.Error().Msg("Message decryption and sign failed")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return decrypted, err
 | 
						return DecryptedMessage, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,8 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestNewKeyPair(t *testing.T) {
 | 
					func TestNewKeyPair(t *testing.T) {
 | 
				
			||||||
@@ -21,7 +23,36 @@ func TestGetKey(t *testing.T) {
 | 
				
			|||||||
	//	fmt.Println(key.Armor())
 | 
						//	fmt.Println(key.Armor())
 | 
				
			||||||
	Armpubkey, _ := key.GetArmoredPublicKey()
 | 
						Armpubkey, _ := key.GetArmoredPublicKey()
 | 
				
			||||||
	pubkey := base64.StdEncoding.EncodeToString([]byte(Armpubkey))
 | 
						pubkey := base64.StdEncoding.EncodeToString([]byte(Armpubkey))
 | 
				
			||||||
	if kp.Public != pubkey {
 | 
						assert.Equal(t, kp.Public, pubkey, "The two public keys should be the same.")
 | 
				
			||||||
		log.Fatal("error in public key")
 | 
						//if kp.Public != pubkey {
 | 
				
			||||||
	}
 | 
						//	log.Fatal("error in public key")
 | 
				
			||||||
 | 
						//}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestEncryptDecrypt(t *testing.T) {
 | 
				
			||||||
 | 
						kp := NewKeyPair()
 | 
				
			||||||
 | 
						foo := "totoaimelesfrites!"
 | 
				
			||||||
 | 
						encMess, err := Encrypt(kp.Public, []byte(foo))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						decMess, err2 := Decrypt(kp.Private, encMess)
 | 
				
			||||||
 | 
						if err2 != nil {
 | 
				
			||||||
 | 
							log.Println(err2.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						assert.Equal(t, foo, decMess, "The two messages should be the same.")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestEncryptDecryptSigned(t *testing.T) {
 | 
				
			||||||
 | 
						kp := NewKeyPair()
 | 
				
			||||||
 | 
						foo := "totoaimelesfrites!"
 | 
				
			||||||
 | 
						encMess, sign, err := EncryptAndSign(kp.Public, kp.Private, []byte(foo))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Println(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						decMess, err2 := DecryptAndCheck(kp.Private, kp.Public, encMess, sign)
 | 
				
			||||||
 | 
						if err2 != nil {
 | 
				
			||||||
 | 
							log.Println(err2.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						assert.Equal(t, foo, string(decMess), "The two messages should be the same.")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,12 +35,12 @@ No phone number or email check will be performed, unlike main instant messaging
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
\subsubsection{Trustable server based communication}
 | 
					\subsubsection{Trustable server based communication}
 | 
				
			||||||
Like most widely available messaging softwares, (Whatsapp, Signal, Viber, Telegram...), \textffm{Meow} provides a simple server based messaging.
 | 
					Like most widely available messaging softwares, (Whatsapp, Signal, Viber, Telegram...), \textffm{Meow} provides a simple server based messaging.
 | 
				
			||||||
The main difference is that allows to explicitly choose which server you want to use.
 | 
					The main difference is it allows to explicitly choose which server you want to use.
 | 
				
			||||||
The server code being open source, we strongly encourage you to run your own server at home or in your company.
 | 
					The server code being open source, we strongly encourage you to run your own server at home or in your company.
 | 
				
			||||||
The server requires very few ressources and will run on any low cost single board computer.
 | 
					The server requires very few ressources and will run on any low cost single board computer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\subsubsection{Anonymized message transfer}
 | 
					\subsubsection{Anonymized message transfer}
 | 
				
			||||||
\textffm{Meow} also provides an anonymizing transfer services very similar to the Tor Onion protocol, we called it the Matriochka protocol.
 | 
					\textffm{Meow} also provides an anonymizing transfer services very similar to the Tor Onion protocol, we call it the Matriochka protocol.
 | 
				
			||||||
Any server can be used for building the transfer chain. 
 | 
					Any server can be used for building the transfer chain. 
 | 
				
			||||||
Some of them might be marked as trusted.
 | 
					Some of them might be marked as trusted.
 | 
				
			||||||
It is strongly advised to use trusted servers as your first node and message server (the one that holds your incoming messages).
 | 
					It is strongly advised to use trusted servers as your first node and message server (the one that holds your incoming messages).
 | 
				
			||||||
@@ -51,16 +51,16 @@ The presence protocol is simply activated by setting a flag in the message poll
 | 
				
			|||||||
If that flag is set, your encrypted IP will be published on the server, allowing your only your peer(s) to decrypt it and directly communicate with your terminal.
 | 
					If that flag is set, your encrypted IP will be published on the server, allowing your only your peer(s) to decrypt it and directly communicate with your terminal.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\subsubsection{Peer based privacy settings}
 | 
					\subsubsection{Peer based privacy settings}
 | 
				
			||||||
You might define specific communication privacy preferences for each of your contacts : 
 | 
					You might define specific communication privacy preferences for each of your contacts: 
 | 
				
			||||||
\begin{itemize}
 | 
					\begin{itemize}
 | 
				
			||||||
    \item simple server based communication allowed for Joe, 
 | 
					    \item simple server based communication allowed for Joe, 
 | 
				
			||||||
    \item direct communication prefered with Julian, fallback to my own server, 
 | 
					    \item preferred direct communication with Julian, fallback to my own server, 
 | 
				
			||||||
    \item matriochka protocol required for Edward, first node is one of my trusted servers, my message node is my own server, randomly switch from trusted server lists for others.
 | 
					    \item required matriochka protocol for Edward, first node is one of my trusted servers, my message node is my own server, randomly switch from trusted server lists for others.
 | 
				
			||||||
    \item ...
 | 
					    \item ...
 | 
				
			||||||
\end{itemize}
 | 
					\end{itemize}
 | 
				
			||||||
\subsection{Multiple devices support}
 | 
					\subsection{Multiple devices support}
 | 
				
			||||||
\textffm{Meow} allows you to be connected from multiple devices and offers chat synchronization capability.
 | 
					\textffm{Meow} allows you to be connected from multiple devices and offers chat synchronization capability.
 | 
				
			||||||
A device might be revoqued anytime from an other any one. Proof of your identity (password or other) shall be provided in order to grant device revocation.
 | 
					A device might be revoqued anytime from any other one. Proof of your identity (password or other) shall be provided in order to grant device revocation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\subsection{Adding contacts}
 | 
					\subsection{Adding contacts}
 | 
				
			||||||
If you want to add a new contact, keys and uuids will be generated, then a rendez-vous card will be created.
 | 
					If you want to add a new contact, keys and uuids will be generated, then a rendez-vous card will be created.
 | 
				
			||||||
@@ -68,8 +68,8 @@ That rendez-vous card might be sent by any trustable communication means, or pre
 | 
				
			|||||||
In return your contact will provide the exact same data, encrypted with your public key and delivered to the address specified in the initial rendez-vous card.
 | 
					In return your contact will provide the exact same data, encrypted with your public key and delivered to the address specified in the initial rendez-vous card.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\subsection{Contacts forwarding}
 | 
					\subsection{Contacts forwarding}
 | 
				
			||||||
Using the \textffm{Meow} protocol a user won't be able to forward your contact information without your consent.
 | 
					By using the \textffm{Meow} protocol a user won't be able to forward your contact information without your consent.
 | 
				
			||||||
Each user knows you as a different identity, thus forwarding a known identity to another user is meaningless. Any message to that identity signed by another user thna you would be discarded.
 | 
					Each user knows you as a different identity, thus forwarding a known identity to another user is meaningless. Any message to that identity signed by another user than you would be discarded.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\subsection{Group conversation}
 | 
					\subsection{Group conversation}
 | 
				
			||||||
@@ -81,18 +81,18 @@ A local (server based) emergency broadcast service will be provided. It will pro
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\subsection{Public networks shortage resilience}
 | 
					\subsection{Public networks shortage resilience}
 | 
				
			||||||
\textffm{Meow} may run without Internet connection, either on an isolated wifi access point, either on a meshed network of wifi routers or even via serial IOT transport layers (LoRa,...)
 | 
					\textffm{Meow} may run without Internet connection, either on an isolated wifi access point, or on a meshed network of wifi routers or even via serial IOT transport layers (LoRa,...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
\subsection{User directory service}
 | 
					\subsection{User directory service}
 | 
				
			||||||
This service allows to restore a lost functionality of Internet historic chat services (like ICQ). You could simply set a "Free for chat" status that allowed other people to contact you, either randomly or based on a short description that you might provide.
 | 
					This service allows to restore a lost functionality of Internet historic chat services (like ICQ). You could simply set a "Free for chat" status that would allow other people to contact you, either randomly or based on a short description that you might provide.
 | 
				
			||||||
Why providing that service while the internet is suffocating due to the abundance of social networks ?\\
 | 
					Why providing that service while the internet is suffocating due to the abundance of social networks ?\\
 | 
				
			||||||
Well, that option offered a few advantages :
 | 
					Well, that option offers a few advantages :
 | 
				
			||||||
\begin{itemize}
 | 
					\begin{itemize}
 | 
				
			||||||
    \item you're still an anonymous user chatting with other anonymous users.
 | 
					    \item you are still an anonymous user chatting with other anonymous users;
 | 
				
			||||||
    \item no social network algorithm will select people that think/behave/vote/eat... just like you. Diversity makes a better world.
 | 
					    \item no social network algorithm will select people that think/behave/vote/eat... just like you. Diversity makes a better world;
 | 
				
			||||||
    \item a smaller community of users, skilled enough to operate a \textffm{Meow} chat app... that might provide a first filter. 
 | 
					    \item a smaller community of users, skilled enough to operate a \textffm{Meow} chat app... that might provide a first filter;
 | 
				
			||||||
    It's a bit like in the old times, when people had to be able to start a win98 computer, connect it to internet, then download and install ICQ...
 | 
					    It's a bit like in the old times, when people had to be able to start a win98 computer, connect it to internet, then download and install ICQ...
 | 
				
			||||||
    If you lost some time in social networks, and experienced ICQ in the 2000's, you know what I mean.
 | 
					    If you lost some time in social networks, and experienced ICQ in the 2000's, you know what I mean.
 | 
				
			||||||
\end{itemize}
 | 
					\end{itemize}
 | 
				
			||||||
@@ -104,45 +104,43 @@ Each \textffm{Meow} user has a unique identity. That identity is strictly privat
 | 
				
			|||||||
Let's call that one the User Key Pair (Ukp)
 | 
					Let's call that one the User Key Pair (Ukp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\subsection{Contact identity}
 | 
					\subsection{Contact identity}
 | 
				
			||||||
Each of your contacts will know you as a different identity, we'll call that one the Contact Key Pair (Ckp)
 | 
					Each of your contacts will know you under a different identity, we'll call that one the Contact Key Pair (Ckp)
 | 
				
			||||||
That contact Key Pair will not change once it's agreed between the two peerr : An initial key will be exchanged as part of the peer invitation process.
 | 
					That contact Key Pair will not change once it's agreed between both peers: an initial key will be exchanged as part of the peer invitation process.
 | 
				
			||||||
As other people myth have seen your key
 | 
					As other people might have seen your key, this means that :
 | 
				
			||||||
This means that :
 | 
					 | 
				
			||||||
\begin{itemize}
 | 
					\begin{itemize}
 | 
				
			||||||
    \item none of your contacts will be able to forward your id to another person without your consent
 | 
					    \item none of your contacts will be able to forward your id to another person without your consent;
 | 
				
			||||||
    \item any message to that Ckp, not signed by the user associated to it, will be discarded.
 | 
					    \item any message to that Ckp, not signed by its associated user, will be discarded.
 | 
				
			||||||
\end{itemize}
 | 
					\end{itemize}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\subsection{Conversation encryption}
 | 
					\subsection{Conversation encryption}
 | 
				
			||||||
Each conversation with one of your contacts will be encrypted using an encryption keypair (Ekp)
 | 
					Each conversation with one of your contacts will be encrypted using an encryption keypair (Ekp) allowing cyphering your conversation.
 | 
				
			||||||
The Ekp might be changed anytime by its owner and the new public key will be sent along the last message.
 | 
					The Ekp might be changed anytime by its owner and the new public key will be sent along the last message.
 | 
				
			||||||
The Ekp is used to cypher your conversation.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
\subsection{Conversation lookup}
 | 
					\subsection{Conversation lookup}
 | 
				
			||||||
A contact conversation Lookup Key Pair(Lkp) is also associated with your conversation. The Lkp public key is used to identify your conversation on a server.
 | 
					A contact conversation Lookup Key Pair(Lkp) is also associated with your conversation. The Lkp public key is used to identify your conversation on a server.
 | 
				
			||||||
the private key allows you to sign your request and prove the server that you are the legitimate recipient for a message.
 | 
					The private key allows you to sign your request and prove the server that you are the legitimate recipient for a message.
 | 
				
			||||||
This Lkp can be changed anytime by it's owner and the new public key will be sent along the last message. 
 | 
					This Lkp can be changed anytime by its owner and the new public key will be sent along the last message. 
 | 
				
			||||||
The Lkp and the Ekp are only changed, once the change has beeen acknowledged by your contact.
 | 
					The Lkp and the Ekp are only changed once the change has beeen acknowledged by your contact.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\subsection{Server identity}
 | 
					\subsection{Server identity}
 | 
				
			||||||
Each server has a Server key (Skp). That key allows you to cypher the messages that you're sending to the server.
 | 
					Each server has a Server key (Skp). That key allows you to cypher the messages that you're sending to the server.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\subsection{Device identity}
 | 
					\subsection{Device identity}
 | 
				
			||||||
Each device is identified by a key (Dkp), that device key allows you to perform secured exchanges between your devices for synchronization/revocation purposes.
 | 
					Each device is identified by a device key (Dkp) that allows you to perform secured exchanges between your devices for synchronization/revocation purposes.
 | 
				
			||||||
Communication between devices is achieved using the same principle as the user to user communication. A device might be considered as any another user. The messages content are based on a synchronization protocol.
 | 
					Communication between devices is achieved using the same principle as the user to user communication. A device might be considered as any another user. The messages content is based on a synchronization protocol.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\section{Contact management}
 | 
					\section{Contact management}
 | 
				
			||||||
\subsection{Adding a contact}
 | 
					\subsection{Adding a contact}
 | 
				
			||||||
Rendez-vous card, containing : 
 | 
					Rendez-vous card, containing : 
 | 
				
			||||||
\begin{itemize}
 | 
					\begin{itemize}
 | 
				
			||||||
    \item Your public key for that contact
 | 
					    \item Your public key for that contact;
 | 
				
			||||||
    \item An initial conversation public key for getting encrypted messages from that contact
 | 
					    \item An initial conversation public key for getting encrypted messages from that contact;
 | 
				
			||||||
    \item An initial conversation uuid that you'll use to lookup for incoming messages on the servers
 | 
					    \item An initial conversation uuid that you'll use to lookup for incoming messages on the servers;
 | 
				
			||||||
    \item A list of your prefered message servers
 | 
					    \item A list of your preferred message servers;
 | 
				
			||||||
    \item A signature to prevent transmission of tampered data
 | 
					    \item A signature to prevent transmission of tampered data.
 | 
				
			||||||
\end{itemize}
 | 
					\end{itemize}
 | 
				
			||||||
\subsection{Sharing a contact}
 | 
					\subsection{Sharing a contact}
 | 
				
			||||||
If a user wants to forward one of his contacts to you, that will be handled as a double request :
 | 
					If a user wants to forward one of his contacts to you, it will be handled as a double request:
 | 
				
			||||||
\begin{enumerate}
 | 
					\begin{enumerate}
 | 
				
			||||||
    \item I'm receiving a contact name, without any key
 | 
					    \item I'm receiving a contact name, without any key
 | 
				
			||||||
    \item 
 | 
					    \item 
 | 
				
			||||||
@@ -164,7 +162,7 @@ TODO
 | 
				
			|||||||
\section{Transport protocols}
 | 
					\section{Transport protocols}
 | 
				
			||||||
\subsection{URLs}
 | 
					\subsection{URLs}
 | 
				
			||||||
Server urls do define the protocol used for communicating with the server.
 | 
					Server urls do define the protocol used for communicating with the server.
 | 
				
			||||||
Some of the protocols will be described hereafter, but that list is not exhaustive, and might be extended in the future.\\
 | 
					Some of the protocols will be described hereafter, but that list is not exhaustive and might be extended in the future.\\
 | 
				
			||||||
Examples of a valid url:
 | 
					Examples of a valid url:
 | 
				
			||||||
\begin{verbatim}
 | 
					\begin{verbatim}
 | 
				
			||||||
http://myserver.com
 | 
					http://myserver.com
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@ func TestEndToEnd(t *testing.T) {
 | 
				
			|||||||
	// Create my own identity
 | 
						// Create my own identity
 | 
				
			||||||
	//
 | 
						//
 | 
				
			||||||
	fmt.Println("Trying to load identity from file.")
 | 
						fmt.Println("Trying to load identity from file.")
 | 
				
			||||||
	me, err := LoadIdentity("test.id")
 | 
						me, err := LoadIdentity("id.enc")
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Failed : creating New identity...")
 | 
							fmt.Println("Failed : creating New identity...")
 | 
				
			||||||
		me = CreateIdentity("myname")
 | 
							me = CreateIdentity("myname")
 | 
				
			||||||
@@ -36,6 +36,8 @@ func TestEndToEnd(t *testing.T) {
 | 
				
			|||||||
		// Simulate peer invitation response : generate the friend's keypair
 | 
							// Simulate peer invitation response : generate the friend's keypair
 | 
				
			||||||
		fmt.Println("Simulating first friend answer...")
 | 
							fmt.Println("Simulating first friend answer...")
 | 
				
			||||||
		var receivedContact ContactCard
 | 
							var receivedContact ContactCard
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Friend simulated invitation
 | 
				
			||||||
		firstFriendContactKp := NewKeyPair()
 | 
							firstFriendContactKp := NewKeyPair()
 | 
				
			||||||
		firstFriendEncryptionKp := NewKeyPair()
 | 
							firstFriendEncryptionKp := NewKeyPair()
 | 
				
			||||||
		firstFriendLookupKp := NewKeyPair()
 | 
							firstFriendLookupKp := NewKeyPair()
 | 
				
			||||||
@@ -45,9 +47,12 @@ func TestEndToEnd(t *testing.T) {
 | 
				
			|||||||
		receivedContact.LookupPublicKey = firstFriendLookupKp.Public
 | 
							receivedContact.LookupPublicKey = firstFriendLookupKp.Public
 | 
				
			||||||
		var friendsMessageServers ServerList
 | 
							var friendsMessageServers ServerList
 | 
				
			||||||
		friendsMessageServers.AddUrls([]string{"http://myfriend.org/meow/"})
 | 
							friendsMessageServers.AddUrls([]string{"http://myfriend.org/meow/"})
 | 
				
			||||||
 | 
							// end Friend simulated invitation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for _, srv := range friendsMessageServers.Servers {
 | 
							for _, srv := range friendsMessageServers.Servers {
 | 
				
			||||||
			receivedContact.PullServers = append(receivedContact.PullServers, srv.ServerData)
 | 
								receivedContact.PullServers = append(receivedContact.PullServers, srv.ServerData)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// End simulating contact invitation response
 | 
							// End simulating contact invitation response
 | 
				
			||||||
		//
 | 
							//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -55,7 +60,7 @@ func TestEndToEnd(t *testing.T) {
 | 
				
			|||||||
		// Finalize the contact with the invitation response
 | 
							// Finalize the contact with the invitation response
 | 
				
			||||||
		//
 | 
							//
 | 
				
			||||||
		me.FinalizeInvitation(myFirstFriend, &receivedContact)
 | 
							me.FinalizeInvitation(myFirstFriend, &receivedContact)
 | 
				
			||||||
		err = me.Save("test.id")
 | 
							err = me.Save("id.enc")
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			fmt.Println(err.Error())
 | 
								fmt.Println(err.Error())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -63,10 +68,27 @@ func TestEndToEnd(t *testing.T) {
 | 
				
			|||||||
		a, _ = json.Marshal(me)
 | 
							a, _ = json.Marshal(me)
 | 
				
			||||||
		ioutil.WriteFile("id.json", a, 0644)
 | 
							ioutil.WriteFile("id.json", a, 0644)
 | 
				
			||||||
		fmt.Println(string(a))
 | 
							fmt.Println(string(a))
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// go me.CheckMessages()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//myFirstFriend.SetComMethod()
 | 
							// create message to simulated friend
 | 
				
			||||||
	//msg := myFirstFriend.SendText()
 | 
							sentmessage := "Hello friend!"
 | 
				
			||||||
 | 
							lookupK, EncMsg, MsgSignature, Servers, err := myFirstFriend.CreateMessage([]byte(sentmessage))
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								fmt.Println(err.Error())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							fmt.Println(lookupK)
 | 
				
			||||||
 | 
							fmt.Println(len(Servers))
 | 
				
			||||||
 | 
							// simulated friend decoding the message
 | 
				
			||||||
 | 
							//ReadMessage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// simulates if peer can decrypt my message
 | 
				
			||||||
 | 
							//Message := "toto"
 | 
				
			||||||
 | 
							//Signature := "test"
 | 
				
			||||||
 | 
							decMess, err2 := DecryptAndCheck(myFirstFriend.EncryptionKp.Private, myFirstFriend.Contact.EncryptionPublicKey, []byte(EncMsg), MsgSignature)
 | 
				
			||||||
 | 
							if err2 != nil {
 | 
				
			||||||
 | 
								fmt.Println(err2.Error())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							fmt.Println(decMess)
 | 
				
			||||||
 | 
							//
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								go.mod
									
									
									
									
									
								
							@@ -5,9 +5,10 @@ go 1.16
 | 
				
			|||||||
require (
 | 
					require (
 | 
				
			||||||
	github.com/ProtonMail/gopenpgp/v2 v2.2.4
 | 
						github.com/ProtonMail/gopenpgp/v2 v2.2.4
 | 
				
			||||||
	github.com/go-resty/resty/v2 v2.6.0
 | 
						github.com/go-resty/resty/v2 v2.6.0
 | 
				
			||||||
 | 
						github.com/golang/protobuf v1.5.2 // indirect
 | 
				
			||||||
	github.com/google/uuid v1.3.0
 | 
						github.com/google/uuid v1.3.0
 | 
				
			||||||
	github.com/makiuchi-d/gozxing v0.1.1
 | 
						github.com/makiuchi-d/gozxing v0.1.1
 | 
				
			||||||
	github.com/rs/zerolog v1.25.0
 | 
						github.com/rs/zerolog v1.25.0
 | 
				
			||||||
	github.com/stretchr/testify v1.4.0
 | 
						github.com/stretchr/testify v1.4.0
 | 
				
			||||||
	google.golang.org/protobuf v1.27.1
 | 
						google.golang.org/protobuf v1.28.1
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								go.sum
									
									
									
									
									
								
							@@ -13,6 +13,8 @@ github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKY
 | 
				
			|||||||
github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q=
 | 
					github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q=
 | 
				
			||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 | 
					github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 | 
				
			||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 | 
					github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 | 
				
			||||||
 | 
					github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
 | 
				
			||||||
 | 
					github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 | 
				
			||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
 | 
					github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
 | 
				
			||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
					github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
				
			||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 | 
					github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 | 
				
			||||||
@@ -82,8 +84,11 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
 | 
				
			|||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 | 
					golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 | 
				
			||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
					golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
				
			||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 | 
					google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 | 
				
			||||||
 | 
					google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 | 
				
			||||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
 | 
					google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
 | 
				
			||||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 | 
					google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 | 
				
			||||||
 | 
					google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
 | 
				
			||||||
 | 
					google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 | 
				
			||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 | 
					gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 | 
				
			||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
					gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
				
			||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 | 
					gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										33
									
								
								https.go
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								https.go
									
									
									
									
									
								
							@@ -1,33 +0,0 @@
 | 
				
			|||||||
package meowlib
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"crypto/tls"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/go-resty/resty/v2"
 | 
					 | 
				
			||||||
	"github.com/rs/zerolog/log"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Https struct {
 | 
					 | 
				
			||||||
	url string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (https *Https) Send(msg []byte) ([]byte, error) {
 | 
					 | 
				
			||||||
	client := resty.New().SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	resp, err := client.R().
 | 
					 | 
				
			||||||
		SetHeader("Content-Type", "application/json").
 | 
					 | 
				
			||||||
		SetBody(msg).
 | 
					 | 
				
			||||||
		Post(https.url + "/message/add/")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Error().Msg(err.Error())
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return resp.Body(), err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (https *Https) Start(callback *func() []InternalMessage) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (https *Https) Stop() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										243
									
								
								id.enc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								id.enc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,243 @@
 | 
				
			|||||||
 | 
					-----BEGIN PGP MESSAGE-----
 | 
				
			||||||
 | 
					Comment: https://gopenpgp.org
 | 
				
			||||||
 | 
					Version: GopenPGP 2.2.4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					wy4ECQMIY2ILWmkTKZ3gEBHjp5QyF+9sL3U/bV8QzCkfmQHVRz/gWPYqk5VzHHJ8
 | 
				
			||||||
 | 
					0u0B+18piB+b4wbrfEfnULF1eLssc+EI6PDl4CoWhk7rncXR6sxQ93CEtCstSgtW
 | 
				
			||||||
 | 
					c8+k8oMXFlFxbqjGQs7vFM3NoNB6da6wN83N+WtT6fQgxpq4IatOU4eG9Lyr9kVP
 | 
				
			||||||
 | 
					mNzazv0yzRwY7B1WfOAgs+s7wjPh6KPqlDJWizsWqyrPXMcdbFt+x5IuBXYOa4J/
 | 
				
			||||||
 | 
					G0cKHrwyon3LKup8+zvitklzuVpiLNg4C6F2BZU7EVNYVPzwetnI+srTZkUAQ4O+
 | 
				
			||||||
 | 
					iXLiiESt16JIVZjLVfxAsDRkwZyeP788Ey7JA2bvxD8rnwoDf5hmZAte96TeIQxa
 | 
				
			||||||
 | 
					kxQ9n7sWbDEcZVjiS33ViQYua76hzBc4yKUyMOWYd7PYjwd1eY/+m7jKHncVxj0l
 | 
				
			||||||
 | 
					c2RwV0OBKZl9xCk5ASO/vG6U25BtuFBf8nUs0Pit3eoviMePbFKm1FxrDnPYh3EA
 | 
				
			||||||
 | 
					kP7qyLSLpMPY65S88muuh+uyI7KM9T0Gz8ZG/ZVBiAQ+Ujbyghg27Med1DllxJ5W
 | 
				
			||||||
 | 
					qUQ6FAv4GSVY06FF471kKIFtU46K4YzLo2d/H2wI+MGIIL9QnZ0GL79g1pj9yYRX
 | 
				
			||||||
 | 
					EScgZvHXg722xdIe1XisPh0pzvUWpDwoad9RO+Ht0QfEKxLRGBZ+OZcVbQSALhs7
 | 
				
			||||||
 | 
					jdgCKGYdLbALrTJ8QJ7hdSU+iEQMrz+dYZ0BxdcClN4/3inUirjyzv53VCb3kBt6
 | 
				
			||||||
 | 
					P53yHg8PoeqLOsdohynQVX+C0KB0ahuFeWe7NvcG0+zCzF1r6vjCPDwakqhy2Sce
 | 
				
			||||||
 | 
					edsj/Op599Rkwaw1Yy06axr+aoPqpnMX/YSnZ/tXfqFT2UbKjp5Jh7ag0IcKCwWB
 | 
				
			||||||
 | 
					wZmtnYtc/C0yKMD+NE3LdnH8axGQpjWVExJjAwKuwtLK+fDnAVh/gKZNU9QOH+vM
 | 
				
			||||||
 | 
					oGDdnhGqBWyhZlWPA7lva03XO5uG2vBkVDmpcFBKOy4cCKWy5WDw3X4lXxCM5fsP
 | 
				
			||||||
 | 
					Porub2ryixeM0nFoso3n+35Y0XZ87MjFpkgZRKUn4qLOYO7nS0RCtj6ZRXfgO9o9
 | 
				
			||||||
 | 
					iCjnuXpdTCXN2290ot088UOdH5bcpcneE/23onVWHVZchXYkQqZF5M/lAj6ftNOl
 | 
				
			||||||
 | 
					VupADVqsLh9vZXFSrWhS/qrk+ybOkVACdFCPSp35zBldJjsijfBKpmsRJ+6UTEus
 | 
				
			||||||
 | 
					Ko1suYy23LrcfwN2unaFtJ1Aw+emOnHqUlhQOD4ntHHYEAJP4Dl5bfpimpEpU1Bz
 | 
				
			||||||
 | 
					n58nz0/p59kpP+HDypOka0jhLf6BDEry42qrawmpZPhpCtAABvJgeFEXn3pUk88w
 | 
				
			||||||
 | 
					TAXSouW21YY6iBXjaUNygCdXEZuSW9t4uAfSMTHpS99PfKHw+ljnsYDdb80ArdXf
 | 
				
			||||||
 | 
					KEzq6UsgXB1fYr/rDnY7iis7VkX1xP29BQiOe/bIUcuruL+n/W/dxdxGVkB9ULET
 | 
				
			||||||
 | 
					FeeBOhdaTbaZefAbkTctNNFz0dw32t6N2qPXrUo3dsZWRQNRLljpVlCn+3L1QOm5
 | 
				
			||||||
 | 
					/KGG1Fm23MaYRExl4c0I31QeO8sXe2dZzXng59tC244IeM84Ra/lB3zmzGr2cL5w
 | 
				
			||||||
 | 
					ABv94Ok3ITmKUVmtfeCpxp9tdpqXdv5Upn2ONEXjCGR/Ps21TW2IHKZHUQY+a9AP
 | 
				
			||||||
 | 
					fCi92UYFH97LxLC1jBbGP82D1aBFzFFRsHO05Mc7bSzNV0ZslQz+CfJHz8k26qTT
 | 
				
			||||||
 | 
					kR9tSAbC/pKBzKScVCSblbrDnsINuGQqkdhx+XMzbE+504B9N57wyFiW2XpCLOd3
 | 
				
			||||||
 | 
					+dtoMVBqi0jVTrlrciOuhocO53UldXiNh1rk/aWALsnC6RysAA7cXvxdq1r58Kin
 | 
				
			||||||
 | 
					Sn6zH1VT6mlaUdyeYkrsCIc7B5ukCeJUYUKxbb2Qj94XQhU2Uw33f+9dgxdVosij
 | 
				
			||||||
 | 
					zhFNFNSgfI3kKV68u4g8IT/rBjSlCE6P0sbm67JuMhE+ClEk/wRfxivEL9kOf4eC
 | 
				
			||||||
 | 
					EydRzA0mqfZbNzfRSYuTAnf274f9dcZ+OZtTarcAelXbFqh6j80iMAaNQSaKExi7
 | 
				
			||||||
 | 
					t5GBgGq/z/1xkH+18yKuHZbHijkB7MWMbfu1wMAqbXVrjZpC0+OCprMFgIICDCnn
 | 
				
			||||||
 | 
					aBS+N2fCewSl+cKOuEKqdOOlqTzCPwLThSa5XQ/u83P/cgaMrsIdCzmiUiZG5lgN
 | 
				
			||||||
 | 
					WASEUQbSBUm/dVDcvQspUCjRbXtd2GJEqoCWVNSZCthQ5fgGxGx5UPvoFu54OW0J
 | 
				
			||||||
 | 
					Am9MyjhCdkipnqLRKmHU5DHnAklhMhC3NSnbDFhAEwpfsFwFzbYTMG87ZYJIqwv9
 | 
				
			||||||
 | 
					ugp6Z88mUYx5K3BZigMeNA3sFCQkZG6vmvBKdCqy43YJ4MaR0BsuUFAYLq06r5Gd
 | 
				
			||||||
 | 
					WX/cEtnbnvVLbMOTnj4vyEbXJkQJES8SfxTVXdUi1uGAT+rmjohbR2saoRcbaMi7
 | 
				
			||||||
 | 
					dj0ZvJOnYivqC2Eu3XkmC/dVUKMlWzhcCeXJKdgSU7geKWXyYvsaaaqMty5Hla6T
 | 
				
			||||||
 | 
					V3JUnaG/kjwu77H97zzUYhLEIv/AYJAUPEOll44V8OBa1nyfKGTKVmc/VjvXNPh7
 | 
				
			||||||
 | 
					o+gua4W6rFn9sgqSfzChV/mWzozPQwdbQ3RMTFRQcDlnXaoATPuwrK+K75KLYh2T
 | 
				
			||||||
 | 
					WVO+6Irw74ROGokSU3yo9Vkr7PLw4XIFScrqd90en9YRfRTYeznsf9q1h2HUml5C
 | 
				
			||||||
 | 
					whoLY/czjW4Mr7s20kUnbieVRxx0QLADVz6d4FrVCw092PReJGWzdxbzu6FDRs2E
 | 
				
			||||||
 | 
					0uq1Xr5KhnWvTIbppSsyotcbuvMLwrh/bZmnwsjbr+Yb7kpmVrK++sJAmG7XFoj9
 | 
				
			||||||
 | 
					qoZpEV3Oq+vK+vWiNE4qgzas+W1NCde8Zv3hmc/OtWfRZLUy8RDf3kcIiDr6/5Vd
 | 
				
			||||||
 | 
					tCnmzJznLI/N3MoETeGVrHu3C2e9UthOUIVp7qP4mltwduLK00Nd7nXbt+FzwQq4
 | 
				
			||||||
 | 
					cwmdZsmGLVAgoQoYWlDnIcgbyRH5wnlZVh/A21lrFrR+JHu30oF7yyRAkJlAETr6
 | 
				
			||||||
 | 
					YIg8E17RJI6J9HpsN2BL7AgPPnwF81fKDGjs3wwm48wQLuUeJEkwMUVDwKJUS/dm
 | 
				
			||||||
 | 
					DzxOYbynMp4yL57I11UhB0z9FHWgpwiuG8zhMjSZ+jP9Vn4+qLCklKHf8Pe8/I2f
 | 
				
			||||||
 | 
					mwmeXMNmJzBt6EZYAGM9251iMyJkBXX/4SdOWh0FzRWCC5secuYyL8/8L5oHoyaK
 | 
				
			||||||
 | 
					cmkeavyxmHA4A37G3Mi8wXh/bf86/fmVlLu/+tYuXaErn3kW+oqr/REnNKClAjqf
 | 
				
			||||||
 | 
					LvmSqPRMzrfUXAcCo4XV68SQ1rapAX4yhts0OlgVkn/s0YggbJnUvyhhS+Y+oRLl
 | 
				
			||||||
 | 
					HTvTVOEfjLRJYvTfxtR5HGPp9ejJIKFtjnBpvEHgfYwrheUGW3Zws4i85IDyNB8y
 | 
				
			||||||
 | 
					LvfAKf6GCvkrlGPjtCTkGh4tMEQeLgF0IGHmR+TyuaAzP8bDfYhLfzpoY/c/OecO
 | 
				
			||||||
 | 
					kdgS558aLvQTXjzddXDEqBvBU1QVJZp6UjbleKHVjwlFVI7NAF4EZKXg4OSF1whu
 | 
				
			||||||
 | 
					5Ez8fbHGdsuDWZ0rLoyzUiUZIsiS3YYxcQCjsO24C8ogq8017wCnYW5nfGiw09dF
 | 
				
			||||||
 | 
					hU++rL/gwn7S2VFlcfLbCz3qG/rr9mfhLLWYDRlxJyvBHjX9AuY4l28E3NL9vuXM
 | 
				
			||||||
 | 
					tjrAO9g/9osIbMkHo12j0AeEjn7Bm4AIviZCUTHFUUqePMo1h6dzxRoGe8gfElRY
 | 
				
			||||||
 | 
					ONNYP+e6gmR97U8kpB7cZo9JRqXEzKBvDg+novRmttuk2EBsKjkVBx9gnvynQBT7
 | 
				
			||||||
 | 
					T9eOngSn8NSJ6zt0412Ffn5I7W4JT8OQ05m47Kreo0rH5RKXTt78OCkV+dYOkqN7
 | 
				
			||||||
 | 
					Q0y/Wk6TZK2OUBpW1ZHCJ9OsRdIBRx0LBDlxWv9UiA39zP3cS6cmbp9ybl+8o11m
 | 
				
			||||||
 | 
					rNDk4yA4Zkav8iF0urlf7v0oEp92vA6/6sREqZGmrvd/lgNheu8G+5S9PWUhB3p+
 | 
				
			||||||
 | 
					ksVKzp1zNCnoEBs9Rm8BmlxIg/nFEbTk+ca6GU8Re1UN/6TdEH4fpXTPZk5RX/lr
 | 
				
			||||||
 | 
					n/JTQVQ/p683CoEAynBYsNWu+XKo2shw01O8n+Lk1MyhtTJexUP9u9bKkiXEFN0w
 | 
				
			||||||
 | 
					cpkLKUf96mgF6CPhDErHoOLrQDDjuD3LlldfRh6I51LkXBciQ7v/658XalNqIZcZ
 | 
				
			||||||
 | 
					9YlYS/y0XF1JFuis/fqakaPYl6ZbHqh0+G5rV7nCuMrkQK8gRisQgVlg6wuH/uhD
 | 
				
			||||||
 | 
					V491p5EWodJokZ8rUw5tGlfcWE/gn7nzOdQI/Dv5D3i8Ixrg9mojP4WIKUAdNsCD
 | 
				
			||||||
 | 
					IBIlyLhehjISTYxH2EB9vSkkqcgYRhDoPdACZLx7yFWweU9xvt9UEHi5zVmurDBl
 | 
				
			||||||
 | 
					Xua0av6z/Nwit2ZEUn1qNUs9N5neh1ETowwGW+M8/CzvcNQx40PSyR58ShofAQrt
 | 
				
			||||||
 | 
					eF4cOY4eQynBxBY3FMNOiB23l6eeLlPPG1AIe8HGJcYwNZ93jA5EjctgyboURpWL
 | 
				
			||||||
 | 
					Y6fEF6AxA8qjkbuI5fM18cfXdY/4MrHQuuJxJEKaxdE2j/4uL/4MrLaamn8TUJiT
 | 
				
			||||||
 | 
					ylqdw7ya45WDsFYpyvz1SiKr8uXNvDn5j0SjS8Vz2qI0J+eODQ9JsGApJOUFzj8p
 | 
				
			||||||
 | 
					zHz/iGDxjJCG4S7TnMJcpwor98cD8ZhJz06hVMYVspD7OzluCTbW9y29/QuHDcHj
 | 
				
			||||||
 | 
					YeGhdHHGlS9mc3KtoxyJwIfOYS8Raj6GEhpnhdvmf3suKRn8jMx5NV7dK914NN2/
 | 
				
			||||||
 | 
					QM59OlK+1CN6z9fDiiaVGO0W/FlXA8SmH8zPWf+O+k7lCsRVXS6vtDOI6QuHF88M
 | 
				
			||||||
 | 
					Ch34g0XKh+NYUqWTkT8AhcFxNyAVYgNI+4ozzvDZEr+dmAhatNVjQ9ZeX5oBCtO0
 | 
				
			||||||
 | 
					mcMZQn9y5IxKOJgFstC0W2nZQuAu+dbZDipKAyY2moUqfgqnKMi1NFrJ/Od3ll0i
 | 
				
			||||||
 | 
					LVoOHnb6FcrQ/hhCb5yT0YpftgtgQAW199HZIM1g8gv32afWiLpxn2ggQe+MrPZF
 | 
				
			||||||
 | 
					mOPe3ZJGCCut6mLvGWV1IoCpbTBRjnmNNY4CT99xKpa3cbC2HFzd9JOm2sJb5EsJ
 | 
				
			||||||
 | 
					+b2joPQJ8Ak7dYBRENNZhRl0ueQq+UghzXe8oJe5F/IX5u7IaWktkR/bJx79d407
 | 
				
			||||||
 | 
					riaPDGkKF0O/hgbL60NRjBsA0UjTvw5UEeWlEQvXjRQ1tM4AeAI/SNgS3oD9Lmai
 | 
				
			||||||
 | 
					ko5q8DOmQZkmnEQZT6vxZU4VyzyI4kW57eDpNEt5rMAh3rR/HADZqaJS3wrw2hfo
 | 
				
			||||||
 | 
					VRrS5nU8q+oz1XQ01+PkL+utbT/k6QZ1pYJyZUZL+aRnV5E5XgYwPT7KkWClIR5h
 | 
				
			||||||
 | 
					O0FS8C6ZAmujlqvhW0GBZA2Y1nHGeu9TL8Cn+SnIfKSq2t8ep2c4F4TmlPKpNYgR
 | 
				
			||||||
 | 
					VnJ7cBzylqaUvwHcuMpohKaRQLTKoxrHVwhh75tCn/5Gtp9ihrZ4+c/wGlYSaukB
 | 
				
			||||||
 | 
					c83KcN9caBmkmzoeioO+Cfnhsf4QjC060Cw3NSqUMVFqZj1dbxx6/ez8FDlaHhe0
 | 
				
			||||||
 | 
					Cb7wJsGk86HnQo46XGgTJCxLWEqC03ZvajHOVARENhwIFPWfVcomUAszxxW33n/k
 | 
				
			||||||
 | 
					zRQub0QI4O37wE2BVerYOhiwG63mzGndcFz2/7AKlBsBWJmWdvD4cb2uwe9jo1hN
 | 
				
			||||||
 | 
					NWjo/i/C8KwMrGfJpWYTAcVg09Npu6IjHZ8C5DfzPN3vjG7Xee/vhf4JQtDLWlTF
 | 
				
			||||||
 | 
					gdVnVKxvdoS5IZqTsuRXOnolZZEybX89RecXNyURGLZdTCwBaj8OTcgBRHryOpcv
 | 
				
			||||||
 | 
					I0U1Cei4zJkdHHqgOLSR65xdr1fek9uz/mbLew87YQnUwiAgxu1M74Y8vK0I8GUM
 | 
				
			||||||
 | 
					qCOYh7+vD+9uPBauaO32j8OLgRc28OeV0hWAXlx0huokpp9HUGVgyBu4rNXrNFi7
 | 
				
			||||||
 | 
					7xJvt4XSmnbfFWjB8wbrhZD6Kh3aX8/y0EQoXQoncpL0rJULRcuyjfwIMt28dA24
 | 
				
			||||||
 | 
					i07upCfPpk0pI775TB0VJ87HTmKJO16ZvYLJKoJelre9OjqkBizmCwesOtIYOtVa
 | 
				
			||||||
 | 
					fgGsDSktm5ESyvDpqVoyshSFwHTpxR3ChtdizMQ7XVqBjyJTb4BKQYKcCZ7T46Sw
 | 
				
			||||||
 | 
					TFviqROZl+gQmzLET3Q0i9puF9dtmnkJaZoOBIogqYw+8unp/60g1zp8P+C/8+eb
 | 
				
			||||||
 | 
					EukZOW1b1su8TdTfprWBFXGGqxx7eF7lTCA9A0o3rCX3rHSVP+uLw0f0tYNv7FI0
 | 
				
			||||||
 | 
					GKWpBVwgouzJGjh360FOqrTklSw1k+ja1+uruvep1DvY3PNLPFt2KAQ5zdjW1rwx
 | 
				
			||||||
 | 
					AlIEV+gHyDTm2lJJJq+UsIFEGupfsXUbf+Vfr0STAQEfGftk1XaOHWfaqdMYCkpk
 | 
				
			||||||
 | 
					4jPsVrd/LDV7ZB9JDMi5GwaY9cBBexP0shl3x24O8dbg0uZYa/O6Lk9dHvX5rTdM
 | 
				
			||||||
 | 
					Gt2vl3GYcNIFGCw0//BJOPiw+UV2ZylNwgdfJ5xKFHFM1Sz1Zbq3Vc83/YqYY5ou
 | 
				
			||||||
 | 
					2gE2+8p1+h+MyY1JCsDmtYVblgimA9Vo4j+L9wymjQPuS5LaqHNkjy9vLYl1T4t/
 | 
				
			||||||
 | 
					AmEPpygdFl9sZxTMgdzM5GZbdHdDlfphR1SWCY+Gzmhw9OSPasS3pznsvxrgVUCf
 | 
				
			||||||
 | 
					aH0Mfymw6fva7wKTrN0TuEVtuSH+30qJ47jFfSEssCV07QwrGd76Jrd4KmdyRxaX
 | 
				
			||||||
 | 
					s7EvX+9W60oFSb/MCmk3qQBpreu9yDE2wWsbMJyM/qtQtuqZTiBxIYx2WCvPuuCx
 | 
				
			||||||
 | 
					LS6vz6aDqWtXYCQyhv/EfK/+ldYAqEaZKSWUEMsr63C3ywHu88r4vnCKqohAaGiv
 | 
				
			||||||
 | 
					6nYmCl9IlIurn+FC2jx2vO7Kd8AuWUT6MRgxpaDm+E44ADM5+FGuhgZu47KRDncD
 | 
				
			||||||
 | 
					Vf2x7dzsDF6os0bU0wKGTnlMy8I6ifBgglQ9CYkEx0EjspEXNDFuY4qdNrLKxuq9
 | 
				
			||||||
 | 
					0ujJQJZ/jNScnWMAkobe3GOVlo95RbvyAwdjIMcMbKb8bzgb1d6u3b5mUTfUWytC
 | 
				
			||||||
 | 
					SMRVBswSV6DbsruMQiRUAK2CBig1bmly2KUHqGh3YVIizhJAsAcLsnZ0WUkX3wJm
 | 
				
			||||||
 | 
					qn6GD0mgT9r0HSzEqaoJocnIMKZZtmqSiD1TVUyc/u6TOhVVuQtXWrIyharDE7fQ
 | 
				
			||||||
 | 
					XnXTYvUFVDFVoafrFcKWP6Lupjf7rDdO1+GT2nwcfllkuYr4a0sxuQlOvvUm5HHC
 | 
				
			||||||
 | 
					+HQnFJZnC4Z+Itu0wFCHJYrgkljoGpb5xyljvbWsjqr1rNpkmU2JCsXi0LLNlZzn
 | 
				
			||||||
 | 
					Hy91rFW7SwOUVHcfWu2xwwhLQOCgPfgxS8FDfiwC9uTyn0C5DRCvlnS6+NuoVF5x
 | 
				
			||||||
 | 
					uz7Szp97GZvYmGiWeWd/LXhUR3i7gHyKvfxu9+WGnZd6pARXq6r2bxuf2PyEvui4
 | 
				
			||||||
 | 
					Xxyb40TKRTmEcmIwLFRzML61z7Gc19BwG3RK4uHebk+vwQHDLMPqI1XqkAB05jJu
 | 
				
			||||||
 | 
					QOgNrYMrp72O2OZNkN3tMn2hirobQexWXi1jGL7X0vSNDanH/kWEKDNUKCgpe8o+
 | 
				
			||||||
 | 
					JVtEM1hGdme2yyoWHt3bF1E3qpVVU140JIlz8zXzuJ7j0mcHUKlHdajBcdqWJKY1
 | 
				
			||||||
 | 
					+H4GRSZPOvx9+ROb/wozY3bkct9SzAAiCsR3MA+qCv7MOsZ8kYWYU0iwhSGLcK9f
 | 
				
			||||||
 | 
					L6QQb2vB4Me0hw+rjoqc5Bs0JlYdt0F/a41G6FOX8RWX7uB8i/7DOtcOr2SGm1sz
 | 
				
			||||||
 | 
					ka4ikfrtqogSL69iVE4e8yX4xyKYAE0V4klac0Lotd1a2iK/oM1N/gY6onovPjAU
 | 
				
			||||||
 | 
					/Cm9XRmfqd1UlOKDS6OTXMlQA/Z9ipgL/Y/a041e2gtb3EqGhZkDgsOYbXpuapbp
 | 
				
			||||||
 | 
					ae2cjdP1GDU0VYEYtJo/6iIrWyzJyhIP9HnWooYZI6Xpe1bn+svCSoJegXqcQxqV
 | 
				
			||||||
 | 
					7lsDSvM0bQ5l7Rpx3uK2Z5lKsM4kfwQwGKvTalYnqXgxAY12O52uYrT8fra0DSSX
 | 
				
			||||||
 | 
					Gkmuz63DyddjXLSRO4nWt62GdNxQNNT4AX0SjITPJamhfn6Eb0sTKhXTU0sT+IA7
 | 
				
			||||||
 | 
					jMIP7cLsHxnC9Qsp+CkE1BRKMcfjsuosgeVmRUkI9AUn9yXd8r0Bva1XLl4JVyJF
 | 
				
			||||||
 | 
					8hxEACin9eRVQ2N+IawnpYNgE2S1ZbUA/swQqV5cMLQ9/Afyq1ZZAldPm5LBQiaU
 | 
				
			||||||
 | 
					nfCT7nURoXqc/EKmkG1nk0R5BO5lBouZM3OERe3S6DnPWvTeC0yNMk1SzPwpTwO+
 | 
				
			||||||
 | 
					ROnEoiNKlPMQ2nENJskrbsETqaT8oprIymeC7xujz7T742Tk6ZjM8bvAKePL7aUR
 | 
				
			||||||
 | 
					ywWeiRu6sWJEaxX+J3VMgLSvmTWvwp0k6cfi3wx+LstjLc+pW7A6hsQKfspdC7Ta
 | 
				
			||||||
 | 
					uz8sGDRkc5S87oSa++UHG7zKXLxXiIQ49kTKZQVlvOJkiDpvpj4+5OP/1dyzoLmy
 | 
				
			||||||
 | 
					F6CGqW+eBXMFiiUu8Kc69u5JUdUsZcL9cOvyd+J4oUGBpP4aJFqh6CHAdIRJRwDK
 | 
				
			||||||
 | 
					AAg6rIZmH0zRl05e5OIgmN58gyW33kyK/QhhpE4MnNvT0BJDq45j3dSvotE84AU2
 | 
				
			||||||
 | 
					qGXNtNQrEn/aV9CVm4u5tdi6lOjrSK3YJWPMDTe/fBfr12NaKPfa1UDBsxiU6ShK
 | 
				
			||||||
 | 
					EqUy87DIkHrPrWHZWNAXaiis3ZXqmOI/FvgJW832dtPJt5Sczue5pnplICFnpwLZ
 | 
				
			||||||
 | 
					D7TGmJIUMFIBeVO+6qRMhivP/veA2V6lv4fRTdjRtKoKHyYpjT7MsBJVk/MlzMaU
 | 
				
			||||||
 | 
					mLzlShLQ1wfXsfsI27OZxYy6u3ED3KVCel37jilBxuHBe2FgwYXTfFgMMi0A8851
 | 
				
			||||||
 | 
					vfwZ2WxiIRl8xro7CgcpqoA8NMHhiAUYn9YtB9OyuLEI4ha7J74PK1LnsQyyvFyG
 | 
				
			||||||
 | 
					1KBNp77NuNq1L8vHWgd0tXsRdcxOluYQ64zxI3FEpD0NIzrSLOSMKNa2uyDGPA/n
 | 
				
			||||||
 | 
					gRse2I1qUzoICGOOyXN3PYLsQpLD0dL4HVHHHoyceu02U0n8kzjnkmbn83A3OqBc
 | 
				
			||||||
 | 
					++A9dNKi5mwq7AocShCcZ+vSWz86Dy4aTOO7JmP3VYOGKNMoYfktAHpjKLDrIgDX
 | 
				
			||||||
 | 
					pOKY6iqMwlNr6KJhzaLXKDa3vOti9jdWOqgHWAWqDDMYsfehuovk8XnOT3vSvaZx
 | 
				
			||||||
 | 
					4/q+bP6wuuYFtxF1LsB6Yxu2VGNbEELd/6+KrV2Y4yl5ArojQZ3XuYm1oj6U4Kkn
 | 
				
			||||||
 | 
					lns30S4yuvdmtg9IGs+KrpLAH1DR/1X10VqUGdvutp73RUkaU6K5jffEEBe8RciB
 | 
				
			||||||
 | 
					VnLdWk3vR3UhiPyEGYfopQ+G8KvD8MbYRT+ftDTTnu04uoJ5sYHBQDNc7/AvJEhc
 | 
				
			||||||
 | 
					VzhQMsgb2VQ7EPXSVIJqrePGM7eDeAtXWWRl/UCDKuZPSub4w32cLLtXjQA+T5sI
 | 
				
			||||||
 | 
					7heW+m4uoDyfiv68n9FZKWSh12/849Pc6eQJXVw+ojj7w1Py6DDbU9F0lvgVWqe9
 | 
				
			||||||
 | 
					SvJ0W1VlVFnL6mVmpPrspkE+DGK+LNr+sRFpYu1dzSx4HyWEXMcFFS17IZkFTfK/
 | 
				
			||||||
 | 
					IXYqXr7k7ar5C5LzP/ZfoANZghcaaK8FhK4Hjdv2M4gj9iWFxkUxY6eDC41v79dS
 | 
				
			||||||
 | 
					iU6Y3iwgwDkgU8uI1cA+kGS/kHLZ1Sfd7GCXPpKD36F9geF7SNstOqDzJ0GqPuJj
 | 
				
			||||||
 | 
					SxTupLQCx+Tr2NWVx/Psq0s2FdQnlW9dtFCAJGAbB+UR+QH4yjFexnOSR/Y0v7ns
 | 
				
			||||||
 | 
					GLk/mSuoA4EJ0d8BFLtcgog1w5Uz3VE/jpBtCfqv+GgYhFdHTlpznoFiIXQKC8KW
 | 
				
			||||||
 | 
					82x1t3NJIVD5Z1pFVktQowtq7Q3EiWCwICvrTdxN+d8jWRnZ+u728f35rM+ndU7E
 | 
				
			||||||
 | 
					MkGMak4/4jSu2TDXtVmsUqDxOho/i6xi1z6FNA1Z+mZ4UPAA4u6QRUcwotszH6/K
 | 
				
			||||||
 | 
					JSWmQ6xQ7QBREujCz9rYmW9laXmEHyFcTQgNccqI7NqEr+Sem0T37DVvr+LpvKE8
 | 
				
			||||||
 | 
					m6CSunmIwGPXo3s1WmJZnvd5apeZX2WwyTDfQX8oneaG65bR7yoGWnk81IWXmSBj
 | 
				
			||||||
 | 
					sMyzwCw3M7NHGcFebSczyWF1cMjVBmzguhfpytTqUsLPKKynvaZOMOzJJ7JvAv/7
 | 
				
			||||||
 | 
					0erT7ePotcBgk5NNezIv8+5zPZhudEMAwx7VXvmf+BZ/f1fNxtO9jV0CM55zgD2h
 | 
				
			||||||
 | 
					DVxUZdgZvPAuYwLuygPmrfc5UZYWI6ZEK1BAZftMos/A6U7GWf5+iLDT85Ojqc2m
 | 
				
			||||||
 | 
					6C4PqtMfMUFddkv4LTclFjPDk61Oo73Tc/C1bmdk8VI5AW5cKerI4E+eBRq7os1x
 | 
				
			||||||
 | 
					lYzh8vc3RTpGv7BQNt7lPyAMRDmPoTQHRmoillqa35XP+apxPXBlY11FWjLuc8wv
 | 
				
			||||||
 | 
					2oUNSpViW39aiFZfpZCZqIVOxKtEH3W/4kHGE/JqFoBEzxUlRs5Tv5cBGdI7pH0D
 | 
				
			||||||
 | 
					VBpdg3uIeolbk27Y5J7nSCwP9mTXhY4d40cp8Kf/RJP5jt4Lo8YQZLJNb8dijz1C
 | 
				
			||||||
 | 
					OS+Pj3oxFxNi1BVcASZ7D2XbfAjgWaH1Ikh4/GmDnErWs0hziN2eKatjnejI/imm
 | 
				
			||||||
 | 
					roAKbTLYHIIN41tJdYogfVhZVEbvfysvq3MBF8dbypraxdcWFZY5cjboG/Pfss7y
 | 
				
			||||||
 | 
					EfYhNNPYZC8SY5im3MfQkw2fnLGscXUdbzeBGrnnggP/uUlej2EE4QU0O6sK9VNC
 | 
				
			||||||
 | 
					5tr1NvQLkMsgY9d0+izxW/7L3QvrYa/L7TNkR68sS9r+991kr9GpVAXvjO3GcsZP
 | 
				
			||||||
 | 
					4QmtRDyV5xoale+YHzoAcCCY8xkcOp15qb6+WzEYCquMfn18IXoQ6vHaj9ZvG58H
 | 
				
			||||||
 | 
					IBnBhppaRPcqB/f+YTCovNEdiY/xAHWncjOGmadatnMarbNSXv/hPiya4A6BWLCO
 | 
				
			||||||
 | 
					PdThBRjR+eREFAWx7W5PK00fbwndK41QirML+yzm6vHLinbLNqu0UwGzoeVty4Md
 | 
				
			||||||
 | 
					oqA+lkI366qkXEpXVTTxTn1btEdzb6Pl53kS02u1Yt2KZLKcXKd5i5OConxuXLfx
 | 
				
			||||||
 | 
					id4zC5yMylrdiimmwmUxa897ByP2TIOWeRTK+P+TFwjoQct8LSoIJMF6WNZVq28J
 | 
				
			||||||
 | 
					LQ1aAm8ZliiKNNmfYlPuqKdS3/EEblv9SzKl9M0JEfl5UvRp5jLGTFad1VyFAxvj
 | 
				
			||||||
 | 
					lnEwOT3wdSd1XIYSnMTf3RCUbJaM40LCN+hToLkjZC3xmOEiU69LK8T6cx2hyWB9
 | 
				
			||||||
 | 
					fiZJImlc3NMtRdpt21GYGSc5CQyPkIQXm1A7LkSOsbbMcTpn3lCY6mVrrTBx4Y5q
 | 
				
			||||||
 | 
					tTkrYK8iVEOiMHNDHiwRAsnZbKZozfldJ/Bgs0G3AwUGjmOpmKlV3tgnX/AuWWxD
 | 
				
			||||||
 | 
					HID5hBIbXXRhKUa/Je/GgarC2VsJoLGrW4mZIgA5PPwn2bs0WRFtWL1QIvhNncK3
 | 
				
			||||||
 | 
					BcNjd7exuQfLJmtn91LaT/h3azTsk4uD8ntWVpxFpIgZTpLCwSJqT9qtovKHUPpu
 | 
				
			||||||
 | 
					Xug5Oe+rVr403jdBD+FWPspGZcGdRADyD+MHOPdN80V8KealvUzQdaOElTdaDFxe
 | 
				
			||||||
 | 
					eq1rZwOCim6UkgxTkWkXIwprDz62YuZNhcgc3+HsSLeoErhURUMIdN5dblseG/qu
 | 
				
			||||||
 | 
					Byf/ncdnsARZuoZDJRbLs2N8WJDmd4UCbFAKGrcQsMB+5BFgBhZt08HTlK0sIiiX
 | 
				
			||||||
 | 
					y2yfaJK48BG9JAj4d4XWqzaH2V/GtM84uapeJCc+Bj+vbWYwGCE8rwxoOQTLuWOp
 | 
				
			||||||
 | 
					7uxnNxcT1EwEdUsDN3oWVvetd5v0ZoQVYKUJQyzpK6lWZcGtVBsGb+H3toEwhfUz
 | 
				
			||||||
 | 
					uxrGpuQ8fbt+uB5+JpEMvjRO1wQ2XHf45niHT9rbuHrvcC9t/hZtuRdbIVUNA3j0
 | 
				
			||||||
 | 
					aLZsCuEq+JqIhZhZE2XuXN/RYxAeN8zcX35zd7i6jkkm83Gwx87bSsrMaFTQKV0/
 | 
				
			||||||
 | 
					C5aabMF76IlxJgTS5nQ+5hbfJvn34NWr93QhxyjAO59XpwEbhsLsMMIqePldRsjN
 | 
				
			||||||
 | 
					xBSaNehjxQb86uyLYWBAn8Bb+k+20+4BdCPpX9efz9/q8Oiom0Ox75Q6sYZcn2wX
 | 
				
			||||||
 | 
					/1nRw7/GOVXJeoddWcUPZtRtXPlHTYqML8A6B7UuTZLUWF893K7f1IQhIxYtQzsb
 | 
				
			||||||
 | 
					Gs7xfFMkQnP9b2bEfXFZN1XeeM/iVSyw/J1f4Vv6WFoFLn4GAFs49rMg4Ramy17U
 | 
				
			||||||
 | 
					BrP6Jv3oaX/UXTte0Pe2njMiy1RW6uJnvtvcvNKTb8/Qk6dWUUb5ZeiCVWvjwRA1
 | 
				
			||||||
 | 
					U3iQwWLo2hu7JwyDi+WP+OESsXtbs95SIyOAtbss67VxjdTAg/5fMeWruYOtN49U
 | 
				
			||||||
 | 
					v/j+1btovNmYUcpRbGqqGjkXBPMAWfuiqzRnfKOOdibHMLWXMm4r3Ybg65wCBnH9
 | 
				
			||||||
 | 
					08NQdpV54/lKEX42JChYF9F3wh7Q6JbsTtCEeWkpckfOzOfSndYwiU2r7cCcHpMX
 | 
				
			||||||
 | 
					EQny2VXHrAoTN8BavNczsncQ5BArzRp7A2j5pFXdlgem/okco/bXCYANyOsl3L/R
 | 
				
			||||||
 | 
					WHKs/MCt8b/v/Z7ICnrYvFHDvuK9vgiRtroWY2PTgGIiwRnWt7Pxd3GBVBaf7SZk
 | 
				
			||||||
 | 
					FTdOyNhsp1svMwmelksy8C3Iwx4IxVlmymI1PQ8FbBquKL23BL5YAQkCX0wQlTrH
 | 
				
			||||||
 | 
					RhkrEQ1Ngsw4Jm38Pq1UgqsVL07wviIaNxYgBSJJbbNkFpOVUapLqjjJU8wRlybu
 | 
				
			||||||
 | 
					YshsYo5L0ZeknhbkTmQOVPvI4JBkOQ0jFp9PecTYqsqwAq84N012zUcgd+E7YTx5
 | 
				
			||||||
 | 
					nq6qwoftVcdmW8MyD3MwYE2NXQwy13YF6FTqsINMsg77XEkmPR7NhwdQWkVszbdi
 | 
				
			||||||
 | 
					HziojBN6/Cb+79oM4MjBMbeicOF8vW+4DnCDNqxmEreKC/9SndxbunjXRK4pHi6u
 | 
				
			||||||
 | 
					Icj07QWvUoI+1+QDRvS9RNrs4KaYYgb/UL9NnSumnhAWEm6TpH9h2hK7tH9H5iDA
 | 
				
			||||||
 | 
					vbNgGrFPzVBzOtKWQwBVVvM5P5lKapsQNBupYTgERFyoah5XjOb+dUKFv31jpCuI
 | 
				
			||||||
 | 
					Rxu5j9G5tzLWNrP0iNKrRzPYoYY0k/6K7lCQ2tKBBTIddTx1uLVbQ35bZrqomm+W
 | 
				
			||||||
 | 
					kq9+KXcosegH1bE6PUrDfyxTelHq0/wNo0ddloC2pVTvXzoc6eXbAo+wChr8IQAP
 | 
				
			||||||
 | 
					AIN83sTtq96HMnqrTPqgLntNPnInilSblSU9Yrt5AmJ0QnuR3rta0UrjTLmD1WNX
 | 
				
			||||||
 | 
					VbgeZciqfOwkdrn5P1PDPZfVRP7Qk9mRjp62eIhr3LHOxM3bGnIJw1es1HnMZX30
 | 
				
			||||||
 | 
					+SV4JRVcSNPPhD3NtOyTBzboWjETH/SUKC3ZoiQQVmkxLioY3iCRh10bLgHl9iXe
 | 
				
			||||||
 | 
					cgGiXrtFKnT8lP7nrBp2cwI/09UInCopqsGUrH4YL+2bGJ8i4+3dl72cDxiefqvE
 | 
				
			||||||
 | 
					vv05g7BmV4N+P/O4Sb6euZouLQUHaOIn4NVDgEnVzwVzOI545ziOo9fI4kwzX+1Z
 | 
				
			||||||
 | 
					Zvc3XrUTJa1SipuOaFNFgr45uo3tHJNlYfitQmKfxAeLtFm8OE04HsHP3LNtxPm6
 | 
				
			||||||
 | 
					UHymksc6/lL/sxaRejbrMnn+rM6OGu9gYFhT+GbsA+CVvDMPEaxFMU02rWJonmyS
 | 
				
			||||||
 | 
					xkPuX8vSQwjly5z8+fV+YJULBpKpZY8HpmAAxWZTjFg1ABMUJAeXQg8UADbng4Lk
 | 
				
			||||||
 | 
					OKDu3cfzmc5om3kstjUvmAjbiqHRgYO+xOCuwI1WCw8oBfpmumToWPWEbkd5XaCA
 | 
				
			||||||
 | 
					hvU5A1YC5Br7n0k6WJya58yAeQ+4aPXDdsZnx1ohf0M9+vyFc1B9If++sPkyi3kL
 | 
				
			||||||
 | 
					YV1BUPJ8qpYAztFwj3imjI1hZZ4vX+jkhGgMcMkaRePIYI5K9J9CgzEArTuLmFRv
 | 
				
			||||||
 | 
					HTQUkYpFHk206Y5URsFdfbUcc4/x8yZcv8w5dSNTd4hh7lOds1+Apj++7Q6RB4Vy
 | 
				
			||||||
 | 
					ZuyGLhd0r81Gk2CxBd8YqELdKfnWJb2lxDFdI054igi/4FLPqDJ8HS0tqHcfW2ir
 | 
				
			||||||
 | 
					3h09gr8Knd0tRUKQ2EMKyKgzt0/qpTtveM8+S7pGKRfVhKQ/mT7Nt+lWKYMOTKhZ
 | 
				
			||||||
 | 
					RQbadW8NsMIQYymWHwVdbdIXWmqmdAkaKewZ8GFQrkqT+TnoTAW6NNz4ndKZCH2E
 | 
				
			||||||
 | 
					vPo7+HopGuiwVRPV5FwaHtSlBXMG+3N8ZrAqbsaVVrS9QtacYdFj119oy9cKoSp/
 | 
				
			||||||
 | 
					uQc2Z9wSRH46CiPcq1Gyaa4yosu839+37N83CaPkloWc4poWbcO4mX2lQJashlIr
 | 
				
			||||||
 | 
					QFBFoE9/N0+8MArhALYqEvL2VXV3G+0bQsEUvic9/hr5DU86JZN3s37Rkq94aDkm
 | 
				
			||||||
 | 
					q3boHdJ0F/F/6IMMnuG6ETdwqhyfj6EhB/Kz9rvAxtaihf9hNzqkh1dL2WaN+O+E
 | 
				
			||||||
 | 
					tdViv2N4RFWPf9WcViPuAQjNMzoxVIlvlx5j0J8/LPqXtKFmEdxxdiIMKb//U5kc
 | 
				
			||||||
 | 
					nv3Fui5I1ECFcDWNlOTWKL1lbnQWADx8cMy+8cdozb4LOxHRCXrrrQgFgsoV0RAf
 | 
				
			||||||
 | 
					zxFiB92FWjz2iT9iahGhKTH+otqRKLD35qsNNIBnOXDHZoLuHvmB7sSCxuVjnNWt
 | 
				
			||||||
 | 
					2amcUTIhUq0LjMFLAXOx3/hK+ZmuEp9clZBAIihiekxKpQXmEA10aNiO7rKBx6BU
 | 
				
			||||||
 | 
					uZ5ybCFZa/EoFFPqEHK3pW1S2ImFQmUGePD5bM+BUnsJy0spJqelgP6SrOiVV4Ux
 | 
				
			||||||
 | 
					YW8v4V3ezVoe1X3AYEN+cdLELxznQXZUCGFdNH0XZGLjmglJM3AhKO5ONQx5/kTw
 | 
				
			||||||
 | 
					QdS07ukMEJyKG83ptFUOmFsDuDqIs2Tp5xWoenm7V6MdWUzUb1Cd/w3wm4LvJP2+
 | 
				
			||||||
 | 
					f1QGjkAC56yVDYFOkFq8U7DEvtLxhd0cG5RZWxXe8aoq3cix6uejc2jYNOIXUVNs
 | 
				
			||||||
 | 
					kZzuqwxnA/t29H3NlSwkbaBYmqG/TI6RuSqzWtiAP4zICKoSAJE9b8VY7WgrzqG3
 | 
				
			||||||
 | 
					8lUuzPb0bLC839TajiFwUZ5A6Y/hQiDAcpvqtyxFWvw//npGcXMFalJVTLeGQXRb
 | 
				
			||||||
 | 
					PwsItw+yWfSckKI/AK/5+UyYLRve7AQGLe6YiPsB6PnzUwjfLIMVdzz6Q43SAhM5
 | 
				
			||||||
 | 
					cHtjeg1H2RE0jxYX8xRLnhIRP9LfIfPGC/aZcPPh+y9BbYcmnWpfKMGAO/O8imCo
 | 
				
			||||||
 | 
					GqyH27tYewa7CLcI5NnSy2libOcMXOjcjyCZe/dDb2jWVeIrIIiYQX9IuJv+8y8b
 | 
				
			||||||
 | 
					2/2QEV69AiUkQll33Wn5yhlGjbBJai/xFGn+abMi0+/RcsCNileIQTtHGFWyRDCr
 | 
				
			||||||
 | 
					=zCs9
 | 
				
			||||||
 | 
					-----END PGP MESSAGE-----
 | 
				
			||||||
							
								
								
									
										12
									
								
								identity.go
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								identity.go
									
									
									
									
									
								
							@@ -53,14 +53,6 @@ func (*Identity) FinalizeInvitation(peer *Peer, receivedContact *ContactCard) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (*Identity) AddPeer(name string, peerPublicKey string) string {
 | 
					 | 
				
			||||||
	var peer Peer
 | 
					 | 
				
			||||||
	peer.Me = NewKeyPair()
 | 
					 | 
				
			||||||
	peer.Contact.Name = name
 | 
					 | 
				
			||||||
	peer.Contact.ContactPublicKey = peerPublicKey
 | 
					 | 
				
			||||||
	return peer.Me.Public
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func LoadIdentity(file string) (*Identity, error) {
 | 
					func LoadIdentity(file string) (*Identity, error) {
 | 
				
			||||||
	var id Identity
 | 
						var id Identity
 | 
				
			||||||
	indata, err := ioutil.ReadFile(file)
 | 
						indata, err := ioutil.ReadFile(file)
 | 
				
			||||||
@@ -68,10 +60,10 @@ func LoadIdentity(file string) (*Identity, error) {
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	pass, err := helper.DecryptMessageWithPassword([]byte(key), string(indata))
 | 
						pass, err := helper.DecryptMessageWithPassword([]byte(key), string(indata))
 | 
				
			||||||
	if err == nil {
 | 
						if err != nil {
 | 
				
			||||||
		err = json.Unmarshal([]byte(pass), &id)
 | 
					 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						err = json.Unmarshal([]byte(pass), &id)
 | 
				
			||||||
	return &id, err
 | 
						return &id, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,8 @@ package meowlib
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestCreate(t *testing.T) {
 | 
					func TestCreate(t *testing.T) {
 | 
				
			||||||
@@ -10,21 +12,10 @@ func TestCreate(t *testing.T) {
 | 
				
			|||||||
	id.Save("test.id")
 | 
						id.Save("test.id")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestSave(t *testing.T) {
 | 
					 | 
				
			||||||
	id := Identity{Nickname: "myname",
 | 
					 | 
				
			||||||
		PublicKey:  "pubk",
 | 
					 | 
				
			||||||
		PrivateKey: "privk",
 | 
					 | 
				
			||||||
		Status:     "online",
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	id.Save("test.id")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestLoad(t *testing.T) {
 | 
					func TestLoad(t *testing.T) {
 | 
				
			||||||
	id, err := LoadIdentity("test.id")
 | 
						id, err := LoadIdentity("test.id")
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Fatal((err.Error()))
 | 
							log.Println(err.Error())
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if id.Nickname != "myname" {
 | 
					 | 
				
			||||||
		log.Fatal("failed")
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						assert.Equal(t, id.Nickname, "myname", "The two words should be the same.")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								invitation.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								invitation.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 530 B  | 
@@ -1,7 +1,7 @@
 | 
				
			|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
 | 
					// Code generated by protoc-gen-go. DO NOT EDIT.
 | 
				
			||||||
// versions:
 | 
					// versions:
 | 
				
			||||||
// 	protoc-gen-go v1.26.0
 | 
					// 	protoc-gen-go v1.28.1
 | 
				
			||||||
// 	protoc        v3.6.1
 | 
					// 	protoc        v3.21.5
 | 
				
			||||||
// source: messages.proto
 | 
					// source: messages.proto
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package meowlib
 | 
					package meowlib
 | 
				
			||||||
@@ -688,15 +688,17 @@ type UserMessage_ConversationStatus struct {
 | 
				
			|||||||
	sizeCache     protoimpl.SizeCache
 | 
						sizeCache     protoimpl.SizeCache
 | 
				
			||||||
	unknownFields protoimpl.UnknownFields
 | 
						unknownFields protoimpl.UnknownFields
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	LocalUuid        string `protobuf:"bytes,1,opt,name=LocalUuid,proto3" json:"LocalUuid,omitempty"`
 | 
						LocalUuid      string `protobuf:"bytes,1,opt,name=LocalUuid,proto3" json:"LocalUuid,omitempty"`
 | 
				
			||||||
	LocalSequence    uint64 `protobuf:"varint,2,opt,name=LocalSequence,proto3" json:"LocalSequence,omitempty"`
 | 
						LocalSequence  uint64 `protobuf:"varint,2,opt,name=LocalSequence,proto3" json:"LocalSequence,omitempty"`
 | 
				
			||||||
	Sent             uint64 `protobuf:"varint,3,opt,name=Sent,proto3" json:"Sent,omitempty"`
 | 
						Sent           uint64 `protobuf:"varint,3,opt,name=Sent,proto3" json:"Sent,omitempty"`
 | 
				
			||||||
	Received         uint64 `protobuf:"varint,4,opt,name=Received,proto3" json:"Received,omitempty"`
 | 
						Received       uint64 `protobuf:"varint,4,opt,name=Received,proto3" json:"Received,omitempty"`
 | 
				
			||||||
	Processed        uint64 `protobuf:"varint,5,opt,name=Processed,proto3" json:"Processed,omitempty"`
 | 
						Processed      uint64 `protobuf:"varint,5,opt,name=Processed,proto3" json:"Processed,omitempty"`
 | 
				
			||||||
	NextCcid         string `protobuf:"bytes,6,opt,name=NextCcid,proto3" json:"NextCcid,omitempty"`
 | 
						NextCkey       string `protobuf:"bytes,6,opt,name=NextCkey,proto3" json:"NextCkey,omitempty"`              // conversation key
 | 
				
			||||||
	NextCcidAck      bool   `protobuf:"varint,7,opt,name=NextCcidAck,proto3" json:"NextCcidAck,omitempty"` // false when proposing a new id, true for accepting it
 | 
						NextCkeyAck    bool   `protobuf:"varint,7,opt,name=NextCkeyAck,proto3" json:"NextCkeyAck,omitempty"`       // false when proposing a new id, true for accepting it
 | 
				
			||||||
	NextCcpkey       string `protobuf:"bytes,8,opt,name=NextCcpkey,proto3" json:"NextCcpkey,omitempty"`
 | 
						NextEkey       string `protobuf:"bytes,8,opt,name=NextEkey,proto3" json:"NextEkey,omitempty"`              // encrypted key
 | 
				
			||||||
	NextKeyCcpkeyAck bool   `protobuf:"varint,9,opt,name=NextKeyCcpkeyAck,proto3" json:"NextKeyCcpkeyAck,omitempty"` // false when proposing a new key, true for accpeting it
 | 
						NextKeyEkeyAck bool   `protobuf:"varint,9,opt,name=NextKeyEkeyAck,proto3" json:"NextKeyEkeyAck,omitempty"` // false when proposing a new key, true for accpeting it
 | 
				
			||||||
 | 
						NextLkey       string `protobuf:"bytes,10,opt,name=NextLkey,proto3" json:"NextLkey,omitempty"`             // lookup key
 | 
				
			||||||
 | 
						NextLkeyAck    bool   `protobuf:"varint,11,opt,name=NextLkeyAck,proto3" json:"NextLkeyAck,omitempty"`      // false when proposing a new id, true for accepting it
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (x *UserMessage_ConversationStatus) Reset() {
 | 
					func (x *UserMessage_ConversationStatus) Reset() {
 | 
				
			||||||
@@ -766,30 +768,44 @@ func (x *UserMessage_ConversationStatus) GetProcessed() uint64 {
 | 
				
			|||||||
	return 0
 | 
						return 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (x *UserMessage_ConversationStatus) GetNextCcid() string {
 | 
					func (x *UserMessage_ConversationStatus) GetNextCkey() string {
 | 
				
			||||||
	if x != nil {
 | 
						if x != nil {
 | 
				
			||||||
		return x.NextCcid
 | 
							return x.NextCkey
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ""
 | 
						return ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (x *UserMessage_ConversationStatus) GetNextCcidAck() bool {
 | 
					func (x *UserMessage_ConversationStatus) GetNextCkeyAck() bool {
 | 
				
			||||||
	if x != nil {
 | 
						if x != nil {
 | 
				
			||||||
		return x.NextCcidAck
 | 
							return x.NextCkeyAck
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (x *UserMessage_ConversationStatus) GetNextCcpkey() string {
 | 
					func (x *UserMessage_ConversationStatus) GetNextEkey() string {
 | 
				
			||||||
	if x != nil {
 | 
						if x != nil {
 | 
				
			||||||
		return x.NextCcpkey
 | 
							return x.NextEkey
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ""
 | 
						return ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (x *UserMessage_ConversationStatus) GetNextKeyCcpkeyAck() bool {
 | 
					func (x *UserMessage_ConversationStatus) GetNextKeyEkeyAck() bool {
 | 
				
			||||||
	if x != nil {
 | 
						if x != nil {
 | 
				
			||||||
		return x.NextKeyCcpkeyAck
 | 
							return x.NextKeyEkeyAck
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *UserMessage_ConversationStatus) GetNextLkey() string {
 | 
				
			||||||
 | 
						if x != nil {
 | 
				
			||||||
 | 
							return x.NextLkey
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *UserMessage_ConversationStatus) GetNextLkeyAck() bool {
 | 
				
			||||||
 | 
						if x != nil {
 | 
				
			||||||
 | 
							return x.NextLkeyAck
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -939,7 +955,7 @@ var file_messages_proto_rawDesc = []byte{
 | 
				
			|||||||
	0x4b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x0e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x53, 0x65,
 | 
						0x4b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x0e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x53, 0x65,
 | 
				
			||||||
	0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6d, 0x65,
 | 
						0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6d, 0x65,
 | 
				
			||||||
	0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0e, 0x54, 0x72,
 | 
						0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0e, 0x54, 0x72,
 | 
				
			||||||
	0x75, 0x73, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0x94, 0x05, 0x0a,
 | 
						0x75, 0x73, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0xca, 0x05, 0x0a,
 | 
				
			||||||
	0x0b, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b,
 | 
						0x0b, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b,
 | 
				
			||||||
	0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
 | 
						0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
 | 
				
			||||||
	0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12,
 | 
						0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12,
 | 
				
			||||||
@@ -957,7 +973,7 @@ var file_messages_proto_rawDesc = []byte{
 | 
				
			|||||||
	0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
 | 
						0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
 | 
				
			||||||
	0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73,
 | 
						0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73,
 | 
				
			||||||
	0x61, 0x67, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70,
 | 
						0x61, 0x67, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70,
 | 
				
			||||||
	0x1a, 0xb0, 0x02, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f,
 | 
						0x1a, 0xe6, 0x02, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f,
 | 
				
			||||||
	0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
 | 
						0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
 | 
				
			||||||
	0x55, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4c, 0x6f, 0x63, 0x61,
 | 
						0x55, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4c, 0x6f, 0x63, 0x61,
 | 
				
			||||||
	0x6c, 0x55, 0x75, 0x69, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x65,
 | 
						0x6c, 0x55, 0x75, 0x69, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x65,
 | 
				
			||||||
@@ -968,22 +984,26 @@ var file_messages_proto_rawDesc = []byte{
 | 
				
			|||||||
	0x04, 0x52, 0x08, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x50,
 | 
						0x04, 0x52, 0x08, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x50,
 | 
				
			||||||
	0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09,
 | 
						0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09,
 | 
				
			||||||
	0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x4e, 0x65, 0x78,
 | 
						0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x4e, 0x65, 0x78,
 | 
				
			||||||
	0x74, 0x43, 0x63, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4e, 0x65, 0x78,
 | 
						0x74, 0x43, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4e, 0x65, 0x78,
 | 
				
			||||||
	0x74, 0x43, 0x63, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x63, 0x69,
 | 
						0x74, 0x43, 0x6b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x6b, 0x65,
 | 
				
			||||||
	0x64, 0x41, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x4e, 0x65, 0x78, 0x74,
 | 
						0x79, 0x41, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x4e, 0x65, 0x78, 0x74,
 | 
				
			||||||
	0x43, 0x63, 0x69, 0x64, 0x41, 0x63, 0x6b, 0x12, 0x1e, 0x0a, 0x0a, 0x4e, 0x65, 0x78, 0x74, 0x43,
 | 
						0x43, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x4e, 0x65, 0x78, 0x74, 0x45,
 | 
				
			||||||
	0x63, 0x70, 0x6b, 0x65, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4e, 0x65, 0x78,
 | 
						0x6b, 0x65, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4e, 0x65, 0x78, 0x74, 0x45,
 | 
				
			||||||
	0x74, 0x43, 0x63, 0x70, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x10, 0x4e, 0x65, 0x78, 0x74, 0x4b,
 | 
						0x6b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x0e, 0x4e, 0x65, 0x78, 0x74, 0x4b, 0x65, 0x79, 0x45, 0x6b,
 | 
				
			||||||
	0x65, 0x79, 0x43, 0x63, 0x70, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28,
 | 
						0x65, 0x79, 0x41, 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x4e, 0x65, 0x78,
 | 
				
			||||||
	0x08, 0x52, 0x10, 0x4e, 0x65, 0x78, 0x74, 0x4b, 0x65, 0x79, 0x43, 0x63, 0x70, 0x6b, 0x65, 0x79,
 | 
						0x74, 0x4b, 0x65, 0x79, 0x45, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x4e,
 | 
				
			||||||
	0x41, 0x63, 0x6b, 0x1a, 0x4e, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04,
 | 
						0x65, 0x78, 0x74, 0x4c, 0x6b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4e,
 | 
				
			||||||
	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
 | 
						0x65, 0x78, 0x74, 0x4c, 0x6b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x4c,
 | 
				
			||||||
	0x12, 0x31, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
 | 
						0x6b, 0x65, 0x79, 0x41, 0x63, 0x6b, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x4e, 0x65,
 | 
				
			||||||
	0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x4d, 0x69, 0x6e, 0x69,
 | 
						0x78, 0x74, 0x4c, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x6b, 0x1a, 0x4e, 0x0a, 0x05, 0x47, 0x72, 0x6f,
 | 
				
			||||||
	0x6d, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62,
 | 
						0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
 | 
				
			||||||
	0x65, 0x72, 0x73, 0x42, 0x21, 0x5a, 0x1f, 0x66, 0x6f, 0x72, 0x67, 0x65, 0x2e, 0x72, 0x65, 0x64,
 | 
						0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72,
 | 
				
			||||||
	0x72, 0x6f, 0x6f, 0x6d, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x2f, 0x79, 0x76, 0x65, 0x73, 0x2f, 0x6d,
 | 
						0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69,
 | 
				
			||||||
	0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 | 
						0x62, 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74,
 | 
				
			||||||
 | 
						0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x42, 0x21, 0x5a, 0x1f, 0x66, 0x6f, 0x72,
 | 
				
			||||||
 | 
						0x67, 0x65, 0x2e, 0x72, 0x65, 0x64, 0x72, 0x6f, 0x6f, 0x6d, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x2f,
 | 
				
			||||||
 | 
						0x79, 0x76, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x62, 0x06, 0x70, 0x72,
 | 
				
			||||||
 | 
						0x6f, 0x74, 0x6f, 0x33,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +0,0 @@
 | 
				
			|||||||
package meowlib
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Network interface {
 | 
					 | 
				
			||||||
	Send(request []byte) ([]byte, error)
 | 
					 | 
				
			||||||
	Start(callback *func() []InternalMessage)
 | 
					 | 
				
			||||||
	Stop()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -2,12 +2,14 @@ syntax = "proto3";
 | 
				
			|||||||
package meowlib;
 | 
					package meowlib;
 | 
				
			||||||
option go_package = "forge.redroom.link/yves/meowlib";
 | 
					option go_package = "forge.redroom.link/yves/meowlib";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// structure for sending a message intended for server use in protobuf format
 | 
				
			||||||
message PackedServerMessage {
 | 
					message PackedServerMessage {
 | 
				
			||||||
	string From = 1;
 | 
						string From = 1;
 | 
				
			||||||
	bytes Payload = 2;
 | 
						bytes Payload = 2;
 | 
				
			||||||
	string Signature = 3;
 | 
						bytes Signature = 3;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// structure for sending a message to be forwarded to another user in protobuf format
 | 
				
			||||||
message PackedUserMessage {
 | 
					message PackedUserMessage {
 | 
				
			||||||
	string From = 1; 
 | 
						string From = 1; 
 | 
				
			||||||
	string Destination=2; 
 | 
						string Destination=2; 
 | 
				
			||||||
@@ -15,6 +17,7 @@ message PackedUserMessage {
 | 
				
			|||||||
	bytes Signature=4;
 | 
						bytes Signature=4;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// structure defining a message to be forwarded encrypted, then sent in a "packedmessage"
 | 
				
			||||||
message ServerMessage {
 | 
					message ServerMessage {
 | 
				
			||||||
	string Type = 1; 
 | 
						string Type = 1; 
 | 
				
			||||||
	string ServerPubKey = 2 ; 
 | 
						string ServerPubKey = 2 ; 
 | 
				
			||||||
@@ -72,10 +75,12 @@ message UserMessage {
 | 
				
			|||||||
        uint64 Sent = 3 ; 
 | 
					        uint64 Sent = 3 ; 
 | 
				
			||||||
        uint64 Received = 4; 
 | 
					        uint64 Received = 4; 
 | 
				
			||||||
        uint64 Processed = 5; 
 | 
					        uint64 Processed = 5; 
 | 
				
			||||||
        string NextCcid = 6;
 | 
					        string NextCkey = 6;        // contact key
 | 
				
			||||||
        bool NextCcidAck = 7; // false when proposing a new id, true for accepting it
 | 
					        bool NextCkeyAck = 7; // false when proposing a new id, true for accepting it
 | 
				
			||||||
        string NextCcpkey = 8;
 | 
					        string NextEkey = 8;           // encryption key
 | 
				
			||||||
        bool NextKeyCcpkeyAck = 9; // false when proposing a new key, true for accpeting it
 | 
					        bool NextKeyEkeyAck = 9; // false when proposing a new key, true for accpeting it
 | 
				
			||||||
 | 
					        string NextLkey = 10;       // lookup key
 | 
				
			||||||
 | 
					        bool NextLkeyAck = 11; // false when proposing a new id, true for accepting it
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    ConversationStatus Status = 5;
 | 
					    ConversationStatus Status = 5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								pb/protogen.bat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								pb/protogen.bat
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					protoc -I=. --go_out=.. messages.proto
 | 
				
			||||||
 | 
					move ..\forge.redroom.link\yves\meowlib\messages.pb.go ..\
 | 
				
			||||||
 | 
					rmdir ..\forge.redroom.link /S /Q
 | 
				
			||||||
							
								
								
									
										70
									
								
								peer.go
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								peer.go
									
									
									
									
									
								
							@@ -9,7 +9,6 @@ import (
 | 
				
			|||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"math"
 | 
						"math"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/makiuchi-d/gozxing"
 | 
						"github.com/makiuchi-d/gozxing"
 | 
				
			||||||
@@ -25,28 +24,29 @@ type ContactCard struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Peer struct {
 | 
					type Peer struct {
 | 
				
			||||||
	Name                string            `json:"name,omitempty"`
 | 
						Name string `json:"name,omitempty"`
 | 
				
			||||||
	Me                  KeyPair           `json:"me,omitempty"`
 | 
						//	Conversation        []InternalMessage `json:"conversation,omitempty"`
 | 
				
			||||||
	Contact             ContactCard       `json:"contact,omitempty"`
 | 
						// My own keys for that peer
 | 
				
			||||||
	Visible             bool              `json:"visible,omitempty"`
 | 
						Me           KeyPair `json:"me,omitempty"`
 | 
				
			||||||
	VisiblePassword     string            `json:"visible_password,omitempty"`
 | 
						EncryptionKp KeyPair `json:"conversation_kp,omitempty"`
 | 
				
			||||||
	PasswordType        string            `json:"password_type,omitempty"`
 | 
						LookupKp     KeyPair `json:"lookup_kp,omitempty"`
 | 
				
			||||||
	Blocked             bool              `json:"blocked,omitempty"`
 | 
						// Peer keys and infos
 | 
				
			||||||
	MessageNotification string            `json:"message_notification,omitempty"`
 | 
						Contact ContactCard `json:"contact,omitempty"`
 | 
				
			||||||
	OnionMode           bool              `json:"onion_mode,omitempty"`
 | 
						// Internal management attributes
 | 
				
			||||||
	Conversation        []InternalMessage `json:"convdersation,omitempty"`
 | 
						Visible             bool      `json:"visible,omitempty"`
 | 
				
			||||||
	LastMessage         time.Time         `json:"last_message,omitempty"`
 | 
						VisiblePassword     string    `json:"visible_password,omitempty"`
 | 
				
			||||||
	EncryptionKp        KeyPair           `json:"conversation_kp,omitempty"`
 | 
						PasswordType        string    `json:"password_type,omitempty"`
 | 
				
			||||||
	LookupKp            KeyPair           `json:"lookup_kp,omitempty"`
 | 
						Blocked             bool      `json:"blocked,omitempty"`
 | 
				
			||||||
	CommUrl             string            `json:"comm_url,omitempty"`
 | 
						MessageNotification string    `json:"message_notification,omitempty"`
 | 
				
			||||||
	net                 Network
 | 
						OnionMode           bool      `json:"onion_mode,omitempty"`
 | 
				
			||||||
 | 
						LastMessage         time.Time `json:"last_message,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type PeerList []Peer
 | 
					type PeerList []Peer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Group struct {
 | 
					type Group struct {
 | 
				
			||||||
	Name    string        `json:"name,omitempty"`
 | 
						Name    string `json:"name,omitempty"`
 | 
				
			||||||
	Members []ContactCard `json:"members,omitempty"`
 | 
						Members []Peer `json:"members,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (pl *PeerList) GetFromPublicKey(publickey string) *Peer {
 | 
					func (pl *PeerList) GetFromPublicKey(publickey string) *Peer {
 | 
				
			||||||
@@ -67,20 +67,6 @@ func (pl *PeerList) GetFromName(name string) *Peer {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (peer *Peer) SetCommInterface(url string) {
 | 
					 | 
				
			||||||
	if strings.HasPrefix(url, "http://") {
 | 
					 | 
				
			||||||
		var https *Https
 | 
					 | 
				
			||||||
		https.url = url
 | 
					 | 
				
			||||||
		peer.net = Network(https)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	peer.net = nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (peer *Peer) SendText(text string) {
 | 
					 | 
				
			||||||
	im := CreateText(*peer, text)
 | 
					 | 
				
			||||||
	fmt.Println(im.MessageData.Destination)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (contact *ContactCard) WritePng(filename string) {
 | 
					func (contact *ContactCard) WritePng(filename string) {
 | 
				
			||||||
	jsonContact, _ := json.Marshal(contact)
 | 
						jsonContact, _ := json.Marshal(contact)
 | 
				
			||||||
	//imgdata := base64.StdEncoding.EncodeToString(jsonContact)
 | 
						//imgdata := base64.StdEncoding.EncodeToString(jsonContact)
 | 
				
			||||||
@@ -152,3 +138,23 @@ func ReadQr(fielname string) ContactCard {
 | 
				
			|||||||
	fmt.Println(result)
 | 
						fmt.Println(result)
 | 
				
			||||||
	return contact
 | 
						return contact
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *Peer) CreateMessage(Message []byte) (lookupK string, EncryptedMsg []byte, Signature []byte, Servers []Server, err error) {
 | 
				
			||||||
 | 
						// prepares a message to send to a specific peer contact
 | 
				
			||||||
 | 
						EncryptedMsg, Signature, err = EncryptAndSign(p.Contact.EncryptionPublicKey, p.Me.Private, Message)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println(err.Error())
 | 
				
			||||||
 | 
							return "", nil, nil, nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return p.LookupKp.Public, EncryptedMsg, Signature, p.Contact.PullServers, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *Peer) ReadMessage(Message []byte, Signature []byte) (DecryptedMsg []byte, err error) {
 | 
				
			||||||
 | 
						// reads a message from a specific peer contact
 | 
				
			||||||
 | 
						DecryptedMsg, err = DecryptAndCheck(p.Me.Private, p.Contact.ContactPublicKey, Message, Signature)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println(err.Error())
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return DecryptedMsg, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										51
									
								
								test.id
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								test.id
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					-----BEGIN PGP MESSAGE-----
 | 
				
			||||||
 | 
					Version: GopenPGP 2.2.4
 | 
				
			||||||
 | 
					Comment: https://gopenpgp.org
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					wy4ECQMIq/FVyXOunqjgpVfIDGm4a6fhv/7yD+pLACzu0XLrEEd6V9/Vr4+5UGhL
 | 
				
			||||||
 | 
					0usB6ZVNKHYMxlUSaFHLZagtQNjoU+bIGaxIToWnKcQ8thW4Z71n15TWyUMikMkv
 | 
				
			||||||
 | 
					6S87LsY7h97TrLSR2NAwZgTqMqe4rzLRKwvEgGmDGbShJO4GOiO/SKLJSkZ9j7yf
 | 
				
			||||||
 | 
					iKsy4l3E7L0wTpnwOMXlDfr0d9NADIgRyj7Bd5GCWVDkFx+wr1MyKNuwYKSqhhz4
 | 
				
			||||||
 | 
					nchTk9J7KE7n9EOmqCxjWY6xPNC/RlpasshSMck3tYZ0vM19kfTnX5rTT2MDW3r8
 | 
				
			||||||
 | 
					WaPAukIi08O67rc/8h7YIcLpzg7vvVqx5FEvrm1xLw2qNGFmvG1y8u1CtWuHQ7ky
 | 
				
			||||||
 | 
					mggzS7ZVb9/jdoog4ExHMvV5+csgWN0n5Mnz+l9fdVrirnkz16BNQ+kfFJaxZ9eh
 | 
				
			||||||
 | 
					flZUirnu2qx0IFck2cJYLpk/mPKYh0V4soNwd/GfZfZWLSyyCroorwfaJSAAeqf7
 | 
				
			||||||
 | 
					yIh446vzlurqvD2/tza8gLatJDFYN5g5LdKTxOHhbRWyDUeB9tw68bOfLHpCm8ed
 | 
				
			||||||
 | 
					XLobbsGWG+BgJwIlrsSKNE5joL+hBnFAtZUHMpiLP6ngJfDEWtG5hS+lMVTinkez
 | 
				
			||||||
 | 
					B1RY01rX1lWRAmy2SNoQdF47kap1cS7tnnDX1QR2IMzxNd1zCpsfvoQy0os7ueU9
 | 
				
			||||||
 | 
					Pn07CxwDJXQy/Tb7NC62dKcZO7zcI4wXYMNqXXYj05pseYRYbExmiHln1/uWhAud
 | 
				
			||||||
 | 
					F86Fr22qPoj0fRZralVn170KUhwgOY3tAogGuaU5vGa4/1oXfFky0lLGlhvKteGA
 | 
				
			||||||
 | 
					lQ9FFRgeBl762nl/c8gpwxsMwCE+kcbHEzl2wWozHRVh9bzWSz91NIDdYhxbXvnR
 | 
				
			||||||
 | 
					tVWRaL52A/5/9Veu8ohHBA2qhmLOzOHoO3v2lSWlCl+7mkNja8ABoo/neytfMUzO
 | 
				
			||||||
 | 
					AFgRu/Qhch0WuZOSmd9xjcJ5iGzgRhpTPHraWTPvueroapgHg8tFEHq+VmtkoD88
 | 
				
			||||||
 | 
					8jlJX8Fl+VBndsZotLpIwy1CyJyKnyc6Nr09A4vEoShDM2DLGNM7+IFDzhVo/3ir
 | 
				
			||||||
 | 
					nTbnN0dBzRwqrG6M4hc17n4PuUEqhYL9p9wdm4hvyb4mrV6i0+nxqQswC6tDHB1c
 | 
				
			||||||
 | 
					x99xiTl0CyAyaF9o+ArNf1aw3pb7a6e66H7lQJ6TB812NCN4jthtsLpa0eJo69BG
 | 
				
			||||||
 | 
					y+GamI1uwkM2n7qf3RMncwFVnG6ux52HAoa81NXgfsaLbuQEn8UhW42uciFS7g5i
 | 
				
			||||||
 | 
					jmBsDQvzLRowIjUKYyHigY+w82seDGErk9ZOEjtCI99c+Xz1RxAquJb1HKWBwmME
 | 
				
			||||||
 | 
					st8PjPwTosqi0OqxvKaHTxK80ywcKJ/nRTxfq5xKHdV2BGZVWLOOVrhqm008zFZ+
 | 
				
			||||||
 | 
					ocw4VrqtdY2YrB+bs8IpvueYTaQabLFfXEG7EXrDU3W7fqhAeIhhAVlAFrkGNFy1
 | 
				
			||||||
 | 
					Y2drmPprDuyZB61SjTgHG10eBkizBbw/VOvpfG08mFlx28/w2BXTkhJdlzqVUn1r
 | 
				
			||||||
 | 
					6Xy2Tjkbc4yakoyZeE09sF1fsNRQ3mI8Q8vORNz/2o2Llk3uwJn0VLdpZDFT6/Mg
 | 
				
			||||||
 | 
					3+xhUY1YYbSyC+ezE4KzumgT4lTo+j0uV8O8poGlhEPdcrhHds338n8nwByCf89U
 | 
				
			||||||
 | 
					weClXd3T49v3q22UpHc4nTEibCy2TMM/NH4R41LJX3fHui0cYZOtMc5ng2Kv8BjH
 | 
				
			||||||
 | 
					oFjUm76BtqEQReKjWm0QkUMRI+xZtIpMvv+nJOQYZQHDfLeVQpWsCg86dotP6DYN
 | 
				
			||||||
 | 
					p61f0/hkgH+Jw0R0DmyAkiW+JnNL1eLrPdnJVgYgsQVH2eJBawOV3sRxvJ4jJ0RW
 | 
				
			||||||
 | 
					92bC6ViZDLXlKULYBZ6rmxi/0W9jYm2E2ooFRmYyteVctKt2aeZpRUaT9mmjwpqz
 | 
				
			||||||
 | 
					Ld2HL2ZqTMtjkTBXR+4CivHI1Wv+V03xIF/gRMkWXQULr0mNr+Y4DF8RVI2DCtgc
 | 
				
			||||||
 | 
					GHXxOw+YfBECr+NxP6Kuj1sTg7an16gkIhQUt4ttWr1ebWXnQUcFby9kduho99dV
 | 
				
			||||||
 | 
					DHZzdhaPlgSUP5TFamBukRedgOD0ar1TqpWKO6Z9pe6m2ZmEdN8c+fCCqm3fyeM2
 | 
				
			||||||
 | 
					nroJspl4cDIlW/QUeHTygT6FkLDE6onj0d6/xUg992NKRhdeuKFW9K1bkitXdiEN
 | 
				
			||||||
 | 
					/g7wjq3h4ziL/K8hUilIEiC2SatHPIb9tlpOwsHzXKLr4IVHdYuiKqyc9kH0wmb6
 | 
				
			||||||
 | 
					/auMNMAWhTCS9V901xDOIGYVRVqCnpR8+aduDm+v+pL3ZoyFerZCfWe49bSzhRPZ
 | 
				
			||||||
 | 
					fL1uneJcnp8VZTXY2W3xPINx8Yez49FzrGVoYTibUpgJRsfbGMgW7LPBWvgpAXQt
 | 
				
			||||||
 | 
					bwIAsUQqdB+68eblP9RcYfO6znJtt/R4rf9d5yf6an3U64Nuq8Ef+AMS5HVvqrdR
 | 
				
			||||||
 | 
					oBCYfY5o/tTHw3bDdzq9fLK2LMYK2PP9yaUWyyvNjzErR1ssiS3YnHDMYnLR+d5t
 | 
				
			||||||
 | 
					9J/bm5XSKFXTkyqaQUuHR7JXJn+gCeDWAsqrSgipMPMntibjgC/OeiKLqTSg+dQn
 | 
				
			||||||
 | 
					F54X4OYSr3SNbnY9IsdM4gvCB65uHR+UtB2/1bPvvkS06aMFy9oyjiSMH9i+6XEJ
 | 
				
			||||||
 | 
					/tmoVSsvHicLIZfrtfCKZ1+F9g+rcL+V7ugbGJshWJkfyh0VX4TPOZmc5gwI9thP
 | 
				
			||||||
 | 
					KA9bzCRoOd+UJzz+0lJcA11gINhbzDGMdsqbFEx8Gv07mBYNFUtkpPaCmQ86R+sW
 | 
				
			||||||
 | 
					LwzE6VqgyrH/CY1BbKigOxIXJkoh99Xq0DkQO19zUNy5AyymqBMV/iWa2Ew4aUur
 | 
				
			||||||
 | 
					4ZZBBR05Y2JigGDjhQTxGBkawCxzsjRjNTd/QrnxEQ==
 | 
				
			||||||
 | 
					=dF9e
 | 
				
			||||||
 | 
					-----END PGP MESSAGE-----
 | 
				
			||||||
@@ -1,60 +0,0 @@
 | 
				
			|||||||
package meowlib
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/google/uuid"
 | 
					 | 
				
			||||||
	"github.com/rs/zerolog/log"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type InternalMessage struct {
 | 
					 | 
				
			||||||
	With         Peer        `json:"with,omitempty"`
 | 
					 | 
				
			||||||
	SentByMe     bool        `json:"sent_by_me,omitempty"`
 | 
					 | 
				
			||||||
	MessageData  UserMessage `json:"message_data,omitempty"`
 | 
					 | 
				
			||||||
	ServerUuid   string      `json:"server_uuid,omitempty"`
 | 
					 | 
				
			||||||
	Received     time.Time   `json:"received,omitempty"`
 | 
					 | 
				
			||||||
	Processed    time.Time   `json:"processed,omitempty"`
 | 
					 | 
				
			||||||
	TransferPath []Server    `json:"transfer_path,omitempty"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func CreateText(Destination Peer, text string) *InternalMessage {
 | 
					 | 
				
			||||||
	var msg InternalMessage
 | 
					 | 
				
			||||||
	msg.With = Destination
 | 
					 | 
				
			||||||
	msg.SentByMe = true
 | 
					 | 
				
			||||||
	msg.MessageData.From = Destination.Me.Public
 | 
					 | 
				
			||||||
	msg.MessageData.Destination = Destination.Contact.ContactPublicKey
 | 
					 | 
				
			||||||
	msg.MessageData.Status.Sent = uint64(time.Now().Unix())
 | 
					 | 
				
			||||||
	msg.MessageData.Status.LocalUuid = strings.Replace(uuid.New().String(), "-", "", -1)
 | 
					 | 
				
			||||||
	msg.MessageData.Type = "t"
 | 
					 | 
				
			||||||
	msg.MessageData.Data = []byte(text)
 | 
					 | 
				
			||||||
	return &msg
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (msg *UserMessage) Pack() *PackedUserMessage {
 | 
					 | 
				
			||||||
	var pck PackedUserMessage
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	jsonMsg, _ := json.Marshal(msg)
 | 
					 | 
				
			||||||
	armor, err := Encrypt(msg.Destination, jsonMsg)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Error().Msg("Message encryption failed")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	pck.Destination = msg.Destination
 | 
					 | 
				
			||||||
	pck.Payload = []byte(armor)
 | 
					 | 
				
			||||||
	return &pck
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (pck *PackedUserMessage) Unpack(privateKey string) *UserMessage {
 | 
					 | 
				
			||||||
	var msg *UserMessage
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	decrypted, err := Decrypt(privateKey, pck.Payload)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Error().Msg("Message decryption failed")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	err = json.Unmarshal(decrypted, &msg)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Error().Msg("Message encryption failed")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return msg
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,37 +0,0 @@
 | 
				
			|||||||
package meowlib
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"log"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestCreateText(t *testing.T) {
 | 
					 | 
				
			||||||
	kp := NewKeyPair()
 | 
					 | 
				
			||||||
	fmt.Println(kp.Public)
 | 
					 | 
				
			||||||
	fmt.Println(kp.Private)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestPack(t *testing.T) {
 | 
					 | 
				
			||||||
	kp := NewKeyPair()
 | 
					 | 
				
			||||||
	//	fmt.Println(kp.Public)
 | 
					 | 
				
			||||||
	//	fmt.Println(kp.Private)
 | 
					 | 
				
			||||||
	key := kp.GetCryptoKeyObject()
 | 
					 | 
				
			||||||
	//	fmt.Println(key.Armor())
 | 
					 | 
				
			||||||
	pubkey, _ := key.GetArmoredPublicKey()
 | 
					 | 
				
			||||||
	if kp.Public != pubkey {
 | 
					 | 
				
			||||||
		log.Fatal("error in public key")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestUnPack(t *testing.T) {
 | 
					 | 
				
			||||||
	kp := NewKeyPair()
 | 
					 | 
				
			||||||
	//	fmt.Println(kp.Public)
 | 
					 | 
				
			||||||
	//	fmt.Println(kp.Private)
 | 
					 | 
				
			||||||
	key := kp.GetCryptoKeyObject()
 | 
					 | 
				
			||||||
	//	fmt.Println(key.Armor())
 | 
					 | 
				
			||||||
	pubkey, _ := key.GetArmoredPublicKey()
 | 
					 | 
				
			||||||
	if kp.Public != pubkey {
 | 
					 | 
				
			||||||
		log.Fatal("error in public key")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user