Reorg
This commit is contained in:
parent
86f222a7df
commit
37fadc5bb3
@ -1,9 +1,10 @@
|
||||
package meowlib
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
|
||||
"forge.redroom.link/yves/meowlib"
|
||||
"github.com/ProtonMail/gopenpgp/v2/helper"
|
||||
)
|
||||
|
||||
@ -15,28 +16,29 @@ type Identity struct {
|
||||
PrivateKey string `json:"private_key,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Peers PeerList `json:"peers,omitempty"`
|
||||
KnownServers ServerList `json:"known_servers,omitempty"`
|
||||
MessageServers ServerList `json:"message_servers,omitempty"`
|
||||
KnownServers InternalServerList `json:"known_servers,omitempty"`
|
||||
MessageServers InternalServerList `json:"message_servers,omitempty"`
|
||||
}
|
||||
|
||||
func CreateIdentity(nickname string) *Identity {
|
||||
var id Identity
|
||||
id.Nickname = nickname
|
||||
kp := NewKeyPair()
|
||||
kp := meowlib.NewKeyPair()
|
||||
id.PublicKey = kp.Public
|
||||
id.PrivateKey = kp.Private
|
||||
return &id
|
||||
}
|
||||
|
||||
func (id *Identity) InvitePeer(myName string, contactName string, messageServerIdxs []int) (*Peer, *ContactCard) {
|
||||
func (id *Identity) InvitePeer(myName string, contactName string, messageServerIdxs []int) (*Peer, *meowlib.ContactCard) {
|
||||
var peer Peer
|
||||
var myContactCard ContactCard
|
||||
peer.Me = NewKeyPair()
|
||||
peer.EncryptionKp = NewKeyPair()
|
||||
peer.LookupKp = NewKeyPair()
|
||||
var myContactCard meowlib.ContactCard
|
||||
peer.Me = meowlib.NewKeyPair()
|
||||
peer.EncryptionKp = meowlib.NewKeyPair()
|
||||
peer.LookupKp = meowlib.NewKeyPair()
|
||||
peer.Name = contactName
|
||||
for _, i := range messageServerIdxs {
|
||||
myContactCard.PullServers = append(myContactCard.PullServers, id.MessageServers.Servers[i].ServerData)
|
||||
srv := id.MessageServers.Servers[i].ServerData
|
||||
myContactCard.PullServers = append(myContactCard.PullServers, &srv)
|
||||
}
|
||||
myContactCard.Name = myName
|
||||
myContactCard.ContactPublicKey = peer.Me.Public
|
||||
@ -48,7 +50,7 @@ func (id *Identity) InvitePeer(myName string, contactName string, messageServerI
|
||||
return &id.Peers[len(id.Peers)-1], &myContactCard
|
||||
}
|
||||
|
||||
func (*Identity) FinalizeInvitation(peer *Peer, receivedContact *ContactCard) {
|
||||
func (*Identity) FinalizeInvitation(peer *Peer, receivedContact *meowlib.ContactCard) {
|
||||
peer.Contact = *receivedContact
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package meowlib
|
||||
package client
|
||||
|
||||
import (
|
||||
"log"
|
83
client/peer.go
Normal file
83
client/peer.go
Normal file
@ -0,0 +1,83 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"forge.redroom.link/yves/meowlib"
|
||||
)
|
||||
|
||||
/*
|
||||
type ContactCard struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
ContactPublicKey string `json:"contact_public_key,omitempty"`
|
||||
EncryptionPublicKey string `json:"encryption_public_key,omitempty"`
|
||||
LookupPublicKey string `json:"lookup_public_key,omitempty"`
|
||||
PullServers []meowlib.Server `json:"pull_servers,omitempty"`
|
||||
}
|
||||
*/
|
||||
|
||||
type Peer struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
// Conversation []InternalMessage `json:"conversation,omitempty"`
|
||||
// My own keys for that peer
|
||||
Me meowlib.KeyPair `json:"me,omitempty"`
|
||||
EncryptionKp meowlib.KeyPair `json:"conversation_kp,omitempty"`
|
||||
LookupKp meowlib.KeyPair `json:"lookup_kp,omitempty"`
|
||||
// Peer keys and infos
|
||||
Contact meowlib.ContactCard `json:"contact,omitempty"`
|
||||
// Internal management attributes
|
||||
Visible bool `json:"visible,omitempty"`
|
||||
VisiblePassword string `json:"visible_password,omitempty"`
|
||||
PasswordType string `json:"password_type,omitempty"`
|
||||
Blocked bool `json:"blocked,omitempty"`
|
||||
MessageNotification string `json:"message_notification,omitempty"`
|
||||
OnionMode bool `json:"onion_mode,omitempty"`
|
||||
LastMessage time.Time `json:"last_message,omitempty"`
|
||||
}
|
||||
|
||||
type PeerList []Peer
|
||||
|
||||
type Group struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Members []Peer `json:"members,omitempty"`
|
||||
}
|
||||
|
||||
func (pl *PeerList) GetFromPublicKey(publickey string) *Peer {
|
||||
for _, peer := range *pl {
|
||||
if peer.Contact.ContactPublicKey == publickey {
|
||||
return &peer
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pl *PeerList) GetFromName(name string) *Peer {
|
||||
for _, peer := range *pl {
|
||||
if peer.Contact.Name == name {
|
||||
return &peer
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Peer) AsymEncryptMessage(Message []byte) (lookupK string, EncryptedMsg []byte, Signature []byte, Servers []*meowlib.Server, err error) {
|
||||
// prepares a message to send to a specific peer contact
|
||||
EncryptedMsg, Signature, err = meowlib.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) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMsg []byte, err error) {
|
||||
// reads a message from a specific peer contact
|
||||
DecryptedMsg, err = meowlib.DecryptAndCheck(p.Me.Private, p.Contact.ContactPublicKey, Message, Signature)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
return DecryptedMsg, err
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package meowlib
|
||||
package client
|
||||
|
||||
import (
|
||||
"testing"
|
55
client/server.go
Normal file
55
client/server.go
Normal file
@ -0,0 +1,55 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"forge.redroom.link/yves/meowlib"
|
||||
)
|
||||
|
||||
type InternalServer struct {
|
||||
ServerData meowlib.Server `json:"server_data,omitempty"`
|
||||
Presence bool `json:"presence,omitempty"`
|
||||
LastCheck time.Time `json:"last_check,omitempty"`
|
||||
Uptime time.Duration `json:"uptime,omitempty"`
|
||||
Login string `json:"login,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Me meowlib.KeyPair `json:"me,omitempty"`
|
||||
}
|
||||
|
||||
type InternalServerList struct {
|
||||
Name string
|
||||
Servers []InternalServer
|
||||
}
|
||||
|
||||
func InternalServerFromUrl(url string) *InternalServer {
|
||||
var is InternalServer
|
||||
is.ServerData.Url = url
|
||||
return &is
|
||||
}
|
||||
|
||||
func (sl *InternalServerList) AddUrls(urls []string) {
|
||||
for _, url := range urls {
|
||||
sl.Servers = append(sl.Servers, *InternalServerFromUrl(url))
|
||||
}
|
||||
}
|
||||
|
||||
func (ints *InternalServer) AsymEncryptMessage(Message []byte) (EncryptedMsg []byte, Signature []byte, err error) {
|
||||
// prepares a message to send to a specific internal server
|
||||
EncryptedMsg, Signature, err = meowlib.EncryptAndSign(ints.ServerData.PublicKey, ints.Me.Private, Message)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return nil, nil, err
|
||||
}
|
||||
return EncryptedMsg, Signature, err
|
||||
}
|
||||
|
||||
func (ints *InternalServer) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMsg []byte, err error) {
|
||||
// reads a message from a specific internal server
|
||||
DecryptedMsg, err = meowlib.DecryptAndCheck(ints.Me.Private, ints.ServerData.PublicKey, Message, Signature)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
return DecryptedMsg, err
|
||||
}
|
99
contactcard.go
Normal file
99
contactcard.go
Normal file
@ -0,0 +1,99 @@
|
||||
package meowlib
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
|
||||
"github.com/makiuchi-d/gozxing"
|
||||
"github.com/makiuchi-d/gozxing/qrcode"
|
||||
)
|
||||
|
||||
func ServerFromUrl(url string) *Server {
|
||||
var s Server
|
||||
s.Url = url
|
||||
return &s
|
||||
}
|
||||
|
||||
func (contact *ContactCard) AddUrls(urls []string) {
|
||||
for _, url := range urls {
|
||||
contact.PullServers = append(contact.PullServers, ServerFromUrl(url))
|
||||
}
|
||||
}
|
||||
|
||||
func (contact *ContactCard) 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 *ContactCard) 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) ContactCard {
|
||||
var contact ContactCard
|
||||
// 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
|
||||
}
|
@ -1,10 +1,13 @@
|
||||
package meowlib
|
||||
package meowlib_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"forge.redroom.link/yves/meowlib"
|
||||
"forge.redroom.link/yves/meowlib/client"
|
||||
)
|
||||
|
||||
func TestEndToEnd(t *testing.T) {
|
||||
@ -12,10 +15,10 @@ func TestEndToEnd(t *testing.T) {
|
||||
// Create my own identity
|
||||
//
|
||||
fmt.Println("Trying to load identity from file.")
|
||||
me, err := LoadIdentity("id.enc")
|
||||
me, err := client.LoadIdentity("id.enc")
|
||||
if err != nil {
|
||||
fmt.Println("Failed : creating New identity...")
|
||||
me = CreateIdentity("myname")
|
||||
me = client.CreateIdentity("myname")
|
||||
|
||||
//
|
||||
// define my preferences (servers)
|
||||
@ -35,24 +38,19 @@ func TestEndToEnd(t *testing.T) {
|
||||
//
|
||||
// Simulate peer invitation response : generate the friend's keypair
|
||||
fmt.Println("Simulating first friend answer...")
|
||||
var receivedContact ContactCard
|
||||
var receivedContact meowlib.ContactCard
|
||||
|
||||
// Friend simulated invitation
|
||||
firstFriendContactKp := NewKeyPair()
|
||||
firstFriendEncryptionKp := NewKeyPair()
|
||||
firstFriendLookupKp := NewKeyPair()
|
||||
firstFriendContactKp := meowlib.NewKeyPair()
|
||||
firstFriendEncryptionKp := meowlib.NewKeyPair()
|
||||
firstFriendLookupKp := meowlib.NewKeyPair()
|
||||
receivedContact.Name = "I'm the friend"
|
||||
receivedContact.ContactPublicKey = firstFriendContactKp.Public
|
||||
receivedContact.EncryptionPublicKey = firstFriendEncryptionKp.Public
|
||||
receivedContact.LookupPublicKey = firstFriendLookupKp.Public
|
||||
var friendsMessageServers ServerList
|
||||
friendsMessageServers.AddUrls([]string{"http://myfriend.org/meow/"})
|
||||
receivedContact.AddUrls([]string{"http://myfriend.org/meow/"})
|
||||
// end Friend simulated invitation
|
||||
|
||||
for _, srv := range friendsMessageServers.Servers {
|
||||
receivedContact.PullServers = append(receivedContact.PullServers, srv.ServerData)
|
||||
}
|
||||
|
||||
// End simulating contact invitation response
|
||||
//
|
||||
|
||||
@ -83,7 +81,7 @@ func TestEndToEnd(t *testing.T) {
|
||||
// simulates if peer can decrypt my message
|
||||
//Message := "toto"
|
||||
//Signature := "test"
|
||||
decMess, err2 := DecryptAndCheck(myFirstFriend.EncryptionKp.Private, myFirstFriend.Contact.EncryptionPublicKey, []byte(EncMsg), MsgSignature)
|
||||
decMess, err2 := meowlib.DecryptAndCheck(myFirstFriend.EncryptionKp.Private, myFirstFriend.Contact.EncryptionPublicKey, []byte(EncMsg), MsgSignature)
|
||||
if err2 != nil {
|
||||
fmt.Println(err2.Error())
|
||||
}
|
||||
|
3
go.mod
3
go.mod
@ -4,9 +4,6 @@ go 1.16
|
||||
|
||||
require (
|
||||
github.com/ProtonMail/gopenpgp/v2 v2.2.4
|
||||
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/makiuchi-d/gozxing v0.1.1
|
||||
github.com/rs/zerolog v1.25.0
|
||||
github.com/stretchr/testify v1.4.0
|
||||
|
10
go.sum
10
go.sum
@ -9,16 +9,10 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4=
|
||||
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/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/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
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=
|
||||
@ -56,7 +50,6 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -84,9 +77,6 @@ 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/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/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
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.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=
|
||||
|
844
messages.pb.go
844
messages.pb.go
File diff suppressed because it is too large
Load Diff
@ -72,6 +72,15 @@ message Server {
|
||||
int32 ConfidenceLevel = 5;
|
||||
}
|
||||
|
||||
message ContactCard {
|
||||
string name=1;
|
||||
string contactPublicKey =2;
|
||||
string encryptionPublicKey= 3;
|
||||
string lookupPublicKey =4;
|
||||
repeated Server PullServers =5;
|
||||
}
|
||||
|
||||
|
||||
message MinimalContact {
|
||||
string name=1;
|
||||
string publicKey=2;
|
||||
|
160
peer.go
160
peer.go
@ -1,160 +0,0 @@
|
||||
package meowlib
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/makiuchi-d/gozxing"
|
||||
"github.com/makiuchi-d/gozxing/qrcode"
|
||||
)
|
||||
|
||||
type ContactCard struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
ContactPublicKey string `json:"contact_public_key,omitempty"`
|
||||
EncryptionPublicKey string `json:"encryption_public_key,omitempty"`
|
||||
LookupPublicKey string `json:"lookup_public_key,omitempty"`
|
||||
PullServers []Server `json:"pull_servers,omitempty"`
|
||||
}
|
||||
|
||||
type Peer struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
// Conversation []InternalMessage `json:"conversation,omitempty"`
|
||||
// My own keys for that peer
|
||||
Me KeyPair `json:"me,omitempty"`
|
||||
EncryptionKp KeyPair `json:"conversation_kp,omitempty"`
|
||||
LookupKp KeyPair `json:"lookup_kp,omitempty"`
|
||||
// Peer keys and infos
|
||||
Contact ContactCard `json:"contact,omitempty"`
|
||||
// Internal management attributes
|
||||
Visible bool `json:"visible,omitempty"`
|
||||
VisiblePassword string `json:"visible_password,omitempty"`
|
||||
PasswordType string `json:"password_type,omitempty"`
|
||||
Blocked bool `json:"blocked,omitempty"`
|
||||
MessageNotification string `json:"message_notification,omitempty"`
|
||||
OnionMode bool `json:"onion_mode,omitempty"`
|
||||
LastMessage time.Time `json:"last_message,omitempty"`
|
||||
}
|
||||
|
||||
type PeerList []Peer
|
||||
|
||||
type Group struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Members []Peer `json:"members,omitempty"`
|
||||
}
|
||||
|
||||
func (pl *PeerList) GetFromPublicKey(publickey string) *Peer {
|
||||
for _, peer := range *pl {
|
||||
if peer.Contact.ContactPublicKey == publickey {
|
||||
return &peer
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pl *PeerList) GetFromName(name string) *Peer {
|
||||
for _, peer := range *pl {
|
||||
if peer.Contact.Name == name {
|
||||
return &peer
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (contact *ContactCard) 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 *ContactCard) 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) ContactCard {
|
||||
var contact ContactCard
|
||||
// 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
|
||||
}
|
||||
|
||||
func (p *Peer) AsymEncryptMessage(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) AsymDecryptMessage(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
|
||||
}
|
@ -1,19 +1,20 @@
|
||||
package meowlib
|
||||
package meowlib_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"forge.redroom.link/yves/meowlib"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func TestServerMessageSerialization(t *testing.T) {
|
||||
var msg PackedServerMessage
|
||||
var msg meowlib.PackedServerMessage
|
||||
msg.From = "toto"
|
||||
msg.Payload = []byte("mon texte")
|
||||
msg.Signature = "moi"
|
||||
msg.Signature = []byte("moi")
|
||||
out, err := proto.Marshal(&msg)
|
||||
if err != nil {
|
||||
log.Fatalln("Failed to encode address book:", err)
|
||||
@ -25,7 +26,7 @@ func TestServerMessageSerialization(t *testing.T) {
|
||||
if err != nil {
|
||||
log.Fatalln("Error reading file:", err)
|
||||
}
|
||||
rmsg := &PackedServerMessage{}
|
||||
rmsg := &meowlib.PackedServerMessage{}
|
||||
if err := proto.Unmarshal(in, rmsg); err != nil {
|
||||
log.Fatalln("Failed to parse address book:", err)
|
||||
}
|
||||
|
53
server.go
53
server.go
@ -1,53 +0,0 @@
|
||||
package meowlib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type InternalServer struct {
|
||||
ServerData Server `json:"server_data,omitempty"`
|
||||
Presence bool `json:"presence,omitempty"`
|
||||
LastCheck time.Time `json:"last_check,omitempty"`
|
||||
Uptime time.Duration `json:"uptime,omitempty"`
|
||||
Login string `json:"login,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Me KeyPair `json:"me,omitempty"`
|
||||
}
|
||||
|
||||
type ServerList struct {
|
||||
Name string
|
||||
Servers []InternalServer
|
||||
}
|
||||
|
||||
func ServerFromUrl(url string) *InternalServer {
|
||||
var is InternalServer
|
||||
is.ServerData.Url = url
|
||||
return &is
|
||||
}
|
||||
|
||||
func (sl *ServerList) AddUrls(urls []string) {
|
||||
for _, url := range urls {
|
||||
sl.Servers = append(sl.Servers, *ServerFromUrl(url))
|
||||
}
|
||||
}
|
||||
|
||||
func (ints *InternalServer) AsymEncryptMessage(Message []byte) (EncryptedMsg []byte, Signature []byte, err error) {
|
||||
// prepares a message to send to a specific internal server
|
||||
EncryptedMsg, Signature, err = EncryptAndSign(ints.ServerData.PublicKey, ints.Me.Private, Message)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return nil, nil, err
|
||||
}
|
||||
return EncryptedMsg, Signature, err
|
||||
}
|
||||
|
||||
func (ints *InternalServer) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMsg []byte, err error) {
|
||||
// reads a message from a specific internal server
|
||||
DecryptedMsg, err = DecryptAndCheck(ints.Me.Private, ints.ServerData.PublicKey, Message, Signature)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
return DecryptedMsg, err
|
||||
}
|
54
server/identity.go
Normal file
54
server/identity.go
Normal file
@ -0,0 +1,54 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
|
||||
"forge.redroom.link/yves/meowlib"
|
||||
"github.com/ProtonMail/gopenpgp/v2/helper"
|
||||
)
|
||||
|
||||
const key = "3pw0c8#6ZG8{75b5;3?fe80$2"
|
||||
|
||||
type Identity struct {
|
||||
ServerName string `json:"servername,omitempty"`
|
||||
ServerDesc string `json:"servername,omitempty"`
|
||||
PublicKey string `json:"public_key,omitempty"`
|
||||
PrivateKey string `json:"private_key,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
// KnownServers ServerList `json:"known_servers,omitempty"`
|
||||
}
|
||||
|
||||
func CreateIdentity(servername string, serverdesc string) *Identity {
|
||||
var id Identity
|
||||
id.ServerName = servername
|
||||
id.ServerDesc = serverdesc
|
||||
kp := meowlib.NewKeyPair()
|
||||
id.PublicKey = kp.Public
|
||||
id.PrivateKey = kp.Private
|
||||
return &id
|
||||
}
|
||||
|
||||
func LoadIdentity(file string) (*Identity, error) {
|
||||
var id Identity
|
||||
indata, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pass, err := helper.DecryptMessageWithPassword([]byte(key), string(indata))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = json.Unmarshal([]byte(pass), &id)
|
||||
return &id, err
|
||||
}
|
||||
|
||||
func (id *Identity) Save(file string) error {
|
||||
b, _ := json.Marshal(id)
|
||||
armor, err := helper.EncryptMessageWithPassword([]byte(key), string(b))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(file, []byte(armor), 0644)
|
||||
return err
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package meowlib
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
const MessagesType = 1
|
||||
const PollRequestType = 1
|
||||
const PollResponseType = 1
|
||||
const MtrkType = 1
|
||||
|
||||
func (msg *ServerMessage) Pack() *PackedServerMessage {
|
||||
var pck PackedServerMessage
|
||||
|
||||
jsonMsg, _ := json.Marshal(msg)
|
||||
armor, err := Encrypt(msg.ServerPubKey, jsonMsg)
|
||||
if err != nil {
|
||||
log.Error().Msg("Message encryption failed")
|
||||
}
|
||||
pck.Payload = []byte(armor)
|
||||
return &pck
|
||||
}
|
||||
|
||||
func (pck *PackedServerMessage) Unpack(privateKey string) *ServerMessage {
|
||||
var msg *ServerMessage
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func CreateMtrkChainServerMessage([]Server, []PackedUserMessage) *PackedServerMessage {
|
||||
var msg PackedServerMessage
|
||||
return &msg
|
||||
}
|
||||
|
||||
func (msg *ServerMessage) Parse() {
|
||||
var pck PackedServerMessage
|
||||
|
||||
jsonMsg, _ := json.Marshal(msg)
|
||||
armor, err := Encrypt(msg.ServerPubKey, jsonMsg)
|
||||
if err != nil {
|
||||
log.Error().Msg("Message encryption failed")
|
||||
}
|
||||
pck.Payload = []byte(armor)
|
||||
}
|
Loading…
Reference in New Issue
Block a user