161 lines
4.2 KiB
Go
161 lines
4.2 KiB
Go
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
|
|
}
|