Curve25519
This commit is contained in:
parent
c07cdff3de
commit
dee68043d1
@ -19,7 +19,7 @@ type KeysArray []KeyPair
|
||||
|
||||
func NewKeyPair() KeyPair {
|
||||
var kp KeyPair
|
||||
keys, err := crypto.GenerateKey("name", "mail", "rsa", 4096)
|
||||
keys, err := crypto.GenerateKey("name", "mail", "x25519", 0)
|
||||
if err != nil {
|
||||
log.Error().Msg("Key generation failed")
|
||||
}
|
||||
|
@ -4,16 +4,25 @@
|
||||
\title{
|
||||
\textffm{Meow} messaging protocol}
|
||||
\author{Author
|
||||
\texttt{author@address.net}}
|
||||
\texttt{meow@redroom.link}}
|
||||
\date{\today}
|
||||
|
||||
\maketitle
|
||||
|
||||
\begin{abstract}
|
||||
The \textffm{Meow} protocol is a privacy driven instant messaging protocol.
|
||||
|
||||
|
||||
The \textffm{Meow} protocol is a privacy driven instant messaging protocol.
|
||||
That protocol might be used for creating secure and distributed chat services or allowing machine to machine communication.
|
||||
This document describes the services provided by the protocol, the messaging structures and the transport protocols that might be used.
|
||||
\begin{quote}
|
||||
|
||||
\centering
|
||||
\emph{"Nous ne vivrons pas d'utopie collective, nous arrivons trop tard, le grand marché est déjà là.
|
||||
Nous devons élaborer des stratégies de survie et de contamination, par la prolifération d'utopies privées, cryptées, qui se substitueront à l'ancien ordre social.
|
||||
Tout ce que je sais, c'est que nous vivons dans un monde dont on ne s'évade pas"}\\
|
||||
\footnotesize{Maurice G. Dantec for NOII (1997)}
|
||||
\end{quote}
|
||||
\end{abstract}
|
||||
|
||||
|
||||
@ -60,23 +69,21 @@ In return your contact will provide the exact same data, encrypted with your pub
|
||||
|
||||
\subsection{Contacts forwarding}
|
||||
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 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 thna you would be discarded.
|
||||
|
||||
|
||||
\subsection{Group conversation}
|
||||
A very basic group messaging service is available. It allows to exchange group information between users. After that, a message to a group will send a copy of the message to each member.
|
||||
|
||||
|
||||
|
||||
\subsection{Emergency broadcast}
|
||||
The
|
||||
A local (server based) emergency broadcast service will be provided. It will provide the ability to send/receive broadcast messages to all users connected to the current server.
|
||||
|
||||
|
||||
\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,...)
|
||||
|
||||
|
||||
|
||||
|
||||
\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.
|
||||
@ -98,6 +105,8 @@ Let's call that one the User Key Pair (Ukp)
|
||||
|
||||
\subsection{Contact identity}
|
||||
Each of your contacts will know you as 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.
|
||||
As other people myth have seen your key
|
||||
This means that :
|
||||
\begin{itemize}
|
||||
\item none of your contacts will be able to forward your id to another person without your consent
|
||||
@ -176,7 +185,10 @@ TODO
|
||||
|
||||
\section{Server Features}
|
||||
\subsection{Server catalog}
|
||||
Each server will cache a list of all the servers that it is aware of.
|
||||
|
||||
\subsection{Antispam}
|
||||
|
||||
\subsection{Self defense}
|
||||
|
||||
|
||||
@ -188,6 +200,10 @@ TODO
|
||||
\section{Very secure devices}
|
||||
You don't trust your phone ?
|
||||
|
||||
\section{Roadmap}
|
||||
\subsection{Nations}
|
||||
Beyond the scope of user directories, we plan to implement the concept of virtual Nations.
|
||||
Today still, most people don't really choose the nation they live in.
|
||||
|
||||
|
||||
\end{document}
|
@ -31,7 +31,7 @@ func TestEndToEnd(t *testing.T) {
|
||||
a, _ := json.Marshal(invitation)
|
||||
fmt.Println(string(a))
|
||||
// TODO : Convert invitation to QR Code
|
||||
|
||||
invitation.WritePng("invitation.png")
|
||||
//
|
||||
// Simulate peer invitation response : generate the friend's keypair
|
||||
fmt.Println("Simulating first friend answer...")
|
||||
@ -64,6 +64,8 @@ func TestEndToEnd(t *testing.T) {
|
||||
ioutil.WriteFile("id.json", a, 0644)
|
||||
fmt.Println(string(a))
|
||||
}
|
||||
// go me.CheckMessages()
|
||||
|
||||
//myFirstFriend.SetComMethod()
|
||||
//msg := myFirstFriend.SendText()
|
||||
|
||||
|
2
go.mod
2
go.mod
@ -6,8 +6,8 @@ require (
|
||||
github.com/ProtonMail/gopenpgp/v2 v2.2.4
|
||||
github.com/go-resty/resty/v2 v2.6.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/makiuchi-d/gozxing v0.1.1
|
||||
github.com/rs/zerolog v1.25.0
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/tidwall/gjson v1.10.2
|
||||
google.golang.org/protobuf v1.27.1
|
||||
)
|
||||
|
11
go.sum
11
go.sum
@ -19,6 +19,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/makiuchi-d/gozxing v0.1.1 h1:xxqijhoedi+/lZlhINteGbywIrewVdVv2wl9r5O9S1I=
|
||||
github.com/makiuchi-d/gozxing v0.1.1/go.mod h1:eRIHbOjX7QWxLIDJoQuMLhuXg9LAuw6znsUtRkNw9DU=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@ -33,12 +35,6 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo=
|
||||
github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@ -72,8 +68,9 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
|
37
https.go
37
https.go
@ -2,48 +2,35 @@ package meowlib
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
var Address string
|
||||
|
||||
func Configure(url string) {
|
||||
Address = url
|
||||
type Https struct {
|
||||
url string
|
||||
}
|
||||
|
||||
func Send(msg []byte) (string, error) {
|
||||
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(Address + "/message/add/")
|
||||
Post(https.url + "/message/add/")
|
||||
if err != nil {
|
||||
log.Error().Msg(err.Error())
|
||||
}
|
||||
serverUuid := gjson.Get(resp.String(), "serveruuid").String()
|
||||
return serverUuid, err
|
||||
return resp.Body(), err
|
||||
}
|
||||
|
||||
func Receive(key string) []byte {
|
||||
client := resty.New().SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
|
||||
|
||||
resp, err := client.R().
|
||||
SetHeader("Content-Type", "application/json").
|
||||
Get(Address + "/message/" + key)
|
||||
fmt.Println(" StatusCode :", resp.StatusCode())
|
||||
fmt.Println(" Cookies :", resp.Cookies())
|
||||
fmt.Println(" Error :", err)
|
||||
msg := resp.Body()
|
||||
return msg
|
||||
}
|
||||
|
||||
func Start(callback *func() []InternalMessage) {
|
||||
func (https *Https) Start(callback *func() []InternalMessage) {
|
||||
for {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (https *Https) Stop() {
|
||||
for {
|
||||
|
||||
}
|
||||
|
1
invitation.json
Normal file
1
invitation.json
Normal file
File diff suppressed because one or more lines are too long
BIN
invitation.png
Normal file
BIN
invitation.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 530 B |
@ -1,9 +1,7 @@
|
||||
package meowlib
|
||||
|
||||
type Network interface {
|
||||
Configure(url string)
|
||||
Send(msg []byte)
|
||||
Receive(request []byte) []byte
|
||||
Start()
|
||||
Send(request []byte) ([]byte, error)
|
||||
Start(callback *func() []InternalMessage)
|
||||
Stop()
|
||||
}
|
||||
|
94
peer.go
94
peer.go
@ -1,8 +1,19 @@
|
||||
package meowlib
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/makiuchi-d/gozxing"
|
||||
"github.com/makiuchi-d/gozxing/qrcode"
|
||||
)
|
||||
|
||||
type Contact struct {
|
||||
@ -27,6 +38,8 @@ type Peer struct {
|
||||
LastMessage time.Time `json:"last_message,omitempty"`
|
||||
EncryptionKp KeyPair `json:"conversation_kp,omitempty"`
|
||||
LookupKp KeyPair `json:"lookup_kp,omitempty"`
|
||||
CommUrl string `json:"comm_url,omitempty"`
|
||||
net Network
|
||||
}
|
||||
|
||||
type PeerList []Peer
|
||||
@ -54,7 +67,88 @@ func (pl *PeerList) GetFromName(name string) *Peer {
|
||||
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 *Contact) WritePng(filename string) {
|
||||
jsonContact, _ := json.Marshal(contact)
|
||||
//imgdata := base64.StdEncoding.EncodeToString(jsonContact)
|
||||
size := int(math.Sqrt(float64(len(jsonContact))/3)) + 1
|
||||
println(size)
|
||||
|
||||
// Create a colored i mage of the given width and height.
|
||||
img := image.NewNRGBA(image.Rect(0, 0, size, size))
|
||||
|
||||
for y := 0; y < size; y++ {
|
||||
for x := 0; x < size*3; x = x + 3 {
|
||||
p1 := uint8(jsonContact[x+y])
|
||||
p2 := uint8(jsonContact[x+y+1])
|
||||
p3 := uint8(jsonContact[x+y+2])
|
||||
img.Set(x/3, y, color.NRGBA{
|
||||
R: p1,
|
||||
G: p2,
|
||||
B: p3,
|
||||
A: 255,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := png.Encode(f, img); err != nil {
|
||||
f.Close()
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := f.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (contact *Contact) WriteQr(filename string) {
|
||||
jsonContact, _ := json.Marshal(contact)
|
||||
qwriter := qrcode.NewQRCodeWriter()
|
||||
code, err := qwriter.Encode(string(jsonContact), gozxing.BarcodeFormat_QR_CODE, 512, 512, nil)
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
}
|
||||
file, _ := os.Create("barcode.png")
|
||||
defer file.Close()
|
||||
|
||||
// *BitMatrix implements the image.Image interface,
|
||||
// so it is able to be passed to png.Encode directly.
|
||||
_ = png.Encode(file, code)
|
||||
|
||||
}
|
||||
|
||||
func ReadQr(fielname string) Contact {
|
||||
var contact Contact
|
||||
// open and decode image file
|
||||
file, _ := os.Open("qrcode.jpg")
|
||||
img, _, _ := image.Decode(file)
|
||||
|
||||
// prepare BinaryBitmap
|
||||
bmp, _ := gozxing.NewBinaryBitmapFromImage(img)
|
||||
|
||||
// decode image
|
||||
qrReader := qrcode.NewQRCodeReader()
|
||||
result, _ := qrReader.Decode(bmp, nil)
|
||||
|
||||
fmt.Println(result)
|
||||
return contact
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user