164 lines
4.5 KiB
Go
164 lines
4.5 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
|
|
"forge.redroom.link/yves/meowlib"
|
|
"github.com/ProtonMail/gopenpgp/v2/helper"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
const key = "3pw0c8#6ZG8{75b5;3?fe80$2"
|
|
|
|
type Identity struct {
|
|
ServerName string `json:"servername,omitempty"`
|
|
ServerDesc string `json:"serverdesc,omitempty"`
|
|
ServerKp meowlib.KeyPair `json:"server_kp,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
|
|
id.ServerKp = meowlib.NewKeyPair()
|
|
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
|
|
}
|
|
|
|
//
|
|
// Inbound processing chain
|
|
//
|
|
|
|
// Unpack a protobuf received packed message
|
|
func (id *Identity) UnpackReceived(message []byte) (fromPublicKey string, encryptedMessage []byte, signature []byte, err error) {
|
|
pmsg := &meowlib.PackedServerMessage{}
|
|
if err := proto.Unmarshal(message, pmsg); err != nil {
|
|
return "", nil, nil, err
|
|
}
|
|
return pmsg.From, pmsg.Payload, pmsg.Signature, nil
|
|
}
|
|
|
|
// AsymDecryptMessage reads a message from a specific client contact
|
|
func (id *Identity) AsymDecryptMessage(ClientPublicKey string, Message []byte, Signature []byte) (DecryptedMsg []byte, err error) {
|
|
DecryptedMsg, err = meowlib.AsymDecryptAndCheck(id.ServerKp.Private, ClientPublicKey, Message, Signature)
|
|
if err != nil {
|
|
fmt.Println(err.Error())
|
|
return nil, err
|
|
}
|
|
return DecryptedMsg, err
|
|
}
|
|
|
|
// Decode decrypted ToServerMessage
|
|
func (id *Identity) DeserializeToServerMessage(toServerMessage []byte) (*meowlib.ToServerMessage, error) {
|
|
tsmsg := &meowlib.ToServerMessage{}
|
|
if err := proto.Unmarshal(toServerMessage, tsmsg); err != nil {
|
|
return nil, err
|
|
}
|
|
return tsmsg, nil
|
|
}
|
|
|
|
// Inbound helper function
|
|
func (id *Identity) ProcessInbound(message []byte) (*meowlib.ToServerMessage, error) {
|
|
// Unpack
|
|
srv_from, srv_encmsg, srv_signature, err := id.UnpackReceived(message)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Decrypt
|
|
srv_clear, err := id.AsymDecryptMessage(srv_from, srv_encmsg, srv_signature)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Decode msg
|
|
srv_msg, err := id.DeserializeToServerMessage(srv_clear)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return srv_msg, nil
|
|
}
|
|
|
|
//
|
|
// Outbound processing chain
|
|
//
|
|
|
|
func (id *Identity) BuildSimpleAckResponseMessage(uuidToAck string) (fromServerMessage *meowlib.FromServerMessage, err error) {
|
|
var msg meowlib.FromServerMessage
|
|
msg.ServerPublicKey = id.ServerKp.Public
|
|
msg.UuidAck = uuidToAck
|
|
return &msg, nil
|
|
}
|
|
|
|
func (id *Identity) SerializeFromServerMessage(msg *meowlib.FromServerMessage) (encodedFromServerMessage []byte, err error) {
|
|
out, err := proto.Marshal(msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
// AsymEncryptMessage prepares a message to send to a specific peer contact
|
|
func (id *Identity) AsymEncryptMessage(peerPublicKey string, Message []byte) (EncryptedMsg []byte, Signature []byte, err error) {
|
|
EncryptedMsg, Signature, err = meowlib.AsymEncryptAndSign(peerPublicKey, id.ServerKp.Private, Message)
|
|
if err != nil {
|
|
fmt.Println(err.Error())
|
|
return nil, nil, err
|
|
}
|
|
return EncryptedMsg, Signature, err
|
|
}
|
|
|
|
func (id *Identity) PackForSending(encryptedMessage []byte, signature []byte) (fromServerMessage []byte, err error) {
|
|
var pmsg meowlib.PackedServerMessage
|
|
pmsg.Payload = encryptedMessage
|
|
pmsg.Signature = signature
|
|
pmsg.From = id.ServerKp.Public
|
|
out, err := proto.Marshal(&pmsg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
// Outbound helper function
|
|
func (id *Identity) ProcessOutbound(peerPublicKey string, msg *meowlib.FromServerMessage) (fromServerMessage []byte, err error) {
|
|
encoded_srv_fromServerMessage, err := id.SerializeFromServerMessage(msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
srv_resp, srv_respsig, err := id.AsymEncryptMessage(peerPublicKey, encoded_srv_fromServerMessage)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
resp, err := id.PackForSending(srv_resp, srv_respsig)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|