This commit is contained in:
ycc
2022-09-06 09:30:45 +02:00
parent 86f222a7df
commit 37fadc5bb3
16 changed files with 944 additions and 619 deletions

80
client/identity.go Normal file
View File

@ -0,0 +1,80 @@
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 {
Nickname string `json:"nickname,omitempty"`
PublicKey string `json:"public_key,omitempty"`
PrivateKey string `json:"private_key,omitempty"`
Status string `json:"status,omitempty"`
Peers PeerList `json:"peers,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 := meowlib.NewKeyPair()
id.PublicKey = kp.Public
id.PrivateKey = kp.Private
return &id
}
func (id *Identity) InvitePeer(myName string, contactName string, messageServerIdxs []int) (*Peer, *meowlib.ContactCard) {
var peer Peer
var myContactCard meowlib.ContactCard
peer.Me = meowlib.NewKeyPair()
peer.EncryptionKp = meowlib.NewKeyPair()
peer.LookupKp = meowlib.NewKeyPair()
peer.Name = contactName
for _, i := range messageServerIdxs {
srv := id.MessageServers.Servers[i].ServerData
myContactCard.PullServers = append(myContactCard.PullServers, &srv)
}
myContactCard.Name = myName
myContactCard.ContactPublicKey = peer.Me.Public
myContactCard.EncryptionPublicKey = peer.EncryptionKp.Public
myContactCard.LookupPublicKey = peer.LookupKp.Public
id.Peers = append(id.Peers, peer)
return &id.Peers[len(id.Peers)-1], &myContactCard
}
func (*Identity) FinalizeInvitation(peer *Peer, receivedContact *meowlib.ContactCard) {
peer.Contact = *receivedContact
}
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
}

21
client/identity_test.go Normal file
View File

@ -0,0 +1,21 @@
package client
import (
"log"
"testing"
"github.com/stretchr/testify/assert"
)
func TestCreate(t *testing.T) {
id := CreateIdentity("myname")
id.Save("test.id")
}
func TestLoad(t *testing.T) {
id, err := LoadIdentity("test.id")
if err != nil {
log.Println(err.Error())
}
assert.Equal(t, id.Nickname, "myname", "The two words should be the same.")
}

83
client/peer.go Normal file
View 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
}

10
client/peer_test.go Normal file
View File

@ -0,0 +1,10 @@
package client
import (
"testing"
)
func TestGetFromPublicKey(t *testing.T) {
id := CreateIdentity("test")
id.Save("test.id")
}

55
client/server.go Normal file
View 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
}