review3 renames

This commit is contained in:
N 2022-09-06 17:07:35 +02:00
parent 37fadc5bb3
commit 8778ae0aef
10 changed files with 586 additions and 553 deletions

View File

@ -37,8 +37,8 @@ func NewKeyPair() KeyPair {
return kp return kp
} }
func (keyPair *KeyPair) GetCryptoKeyObject() *crypto.Key { func (Kp *KeyPair) GetCryptoKeyObject() *crypto.Key {
priv, err := base64.StdEncoding.DecodeString(keyPair.Private) priv, err := base64.StdEncoding.DecodeString(Kp.Private)
if err != nil { if err != nil {
log.Error().Msg("Create key from armoured b64 failed") log.Error().Msg("Create key from armoured b64 failed")
} }
@ -49,8 +49,8 @@ func (keyPair *KeyPair) GetCryptoKeyObject() *crypto.Key {
return key return key
} }
func Encrypt(publicKey string, data []byte) ([]byte, error) { func Encrypt(PublicKey string, data []byte) ([]byte, error) {
pub, err := base64.StdEncoding.DecodeString(publicKey) pub, err := base64.StdEncoding.DecodeString(PublicKey)
if err != nil { if err != nil {
log.Error().Msg("Message encryption b64 failed") log.Error().Msg("Message encryption b64 failed")
} }
@ -61,8 +61,8 @@ func Encrypt(publicKey string, data []byte) ([]byte, error) {
return []byte(armor), err return []byte(armor), err
} }
func Decrypt(privateKey string, data []byte) ([]byte, error) { func Decrypt(PrivateKey string, data []byte) ([]byte, error) {
priv, err := base64.StdEncoding.DecodeString(privateKey) priv, err := base64.StdEncoding.DecodeString(PrivateKey)
if err != nil { if err != nil {
log.Error().Msg("Message decryption b64 failed") log.Error().Msg("Message decryption b64 failed")
} }
@ -73,12 +73,12 @@ func Decrypt(privateKey string, data []byte) ([]byte, error) {
return []byte(decrypted), err return []byte(decrypted), err
} }
func EncryptAndSign(publicEncKey string, privateSignKey string, data []byte) ([]byte, []byte, error) { func EncryptAndSign(PublicEncryptionKey string, PrivateSignatureKey string, data []byte) ([]byte, []byte, error) {
pub, err := base64.StdEncoding.DecodeString(publicEncKey) pub, err := base64.StdEncoding.DecodeString(PublicEncryptionKey)
if err != nil { if err != nil {
log.Error().Msg("Message encryption and sign b64 failed") log.Error().Msg("Message encryption and sign b64 failed")
} }
priv, err := base64.StdEncoding.DecodeString(privateSignKey) priv, err := base64.StdEncoding.DecodeString(PrivateSignatureKey)
if err != nil { if err != nil {
log.Error().Msg("Message encryption and sign b64 failed") log.Error().Msg("Message encryption and sign b64 failed")
} }
@ -89,16 +89,16 @@ func EncryptAndSign(publicEncKey string, privateSignKey string, data []byte) ([]
return []byte(encrypted), []byte(signature), err return []byte(encrypted), []byte(signature), err
} }
func DecryptAndCheck(MyPrivateEncryptionKey string, peerContactPublicKey string, data []byte, signature []byte) (DecryptedMessage []byte, err error) { func DecryptAndCheck(MyPrivateEncryptionKey string, MyContactPublicKey string, data []byte, Signature []byte) (DecryptedMessage []byte, err error) {
pub, err := base64.StdEncoding.DecodeString(MyPrivateEncryptionKey) pub, err := base64.StdEncoding.DecodeString(MyPrivateEncryptionKey)
if err != nil { if err != nil {
log.Error().Msg("Message decryption and sign b64 failed") log.Error().Msg("Message decryption and sign b64 failed")
} }
priv, err := base64.StdEncoding.DecodeString(peerContactPublicKey) priv, err := base64.StdEncoding.DecodeString(MyContactPublicKey)
if err != nil { if err != nil {
log.Error().Msg("Message decryption and sign b64 failed") log.Error().Msg("Message decryption and sign b64 failed")
} }
DecryptedMessage, err = helper.DecryptVerifyBinaryDetached(string(pub), string(priv), nil, data, string(signature)) DecryptedMessage, err = helper.DecryptVerifyBinaryDetached(string(pub), string(priv), nil, data, string(Signature))
if err != nil { if err != nil {
log.Error().Msg("Message decryption and sign failed") log.Error().Msg("Message decryption and sign failed")
} }

View File

@ -12,8 +12,7 @@ const key = "3pw0c8#6ZG8{75b5;3?fe80$2"
type Identity struct { type Identity struct {
Nickname string `json:"nickname,omitempty"` Nickname string `json:"nickname,omitempty"`
PublicKey string `json:"public_key,omitempty"` RootKp meowlib.KeyPair `json:"id_kp,omitempty"`
PrivateKey string `json:"private_key,omitempty"`
Status string `json:"status,omitempty"` Status string `json:"status,omitempty"`
Peers PeerList `json:"peers,omitempty"` Peers PeerList `json:"peers,omitempty"`
KnownServers InternalServerList `json:"known_servers,omitempty"` KnownServers InternalServerList `json:"known_servers,omitempty"`
@ -23,24 +22,22 @@ type Identity struct {
func CreateIdentity(nickname string) *Identity { func CreateIdentity(nickname string) *Identity {
var id Identity var id Identity
id.Nickname = nickname id.Nickname = nickname
kp := meowlib.NewKeyPair() id.RootKp = meowlib.NewKeyPair()
id.PublicKey = kp.Public
id.PrivateKey = kp.Private
return &id return &id
} }
func (id *Identity) InvitePeer(myName string, contactName string, messageServerIdxs []int) (*Peer, *meowlib.ContactCard) { func (id *Identity) InvitePeer(MyName string, ContactName string, MessageServerIdxs []int) (*Peer, *meowlib.ContactCard) {
var peer Peer var peer Peer
var myContactCard meowlib.ContactCard var myContactCard meowlib.ContactCard
peer.Me = meowlib.NewKeyPair() peer.Me = meowlib.NewKeyPair()
peer.EncryptionKp = meowlib.NewKeyPair() peer.EncryptionKp = meowlib.NewKeyPair()
peer.LookupKp = meowlib.NewKeyPair() peer.LookupKp = meowlib.NewKeyPair()
peer.Name = contactName peer.Name = ContactName
for _, i := range messageServerIdxs { for _, i := range MessageServerIdxs {
srv := id.MessageServers.Servers[i].ServerData srv := id.MessageServers.Servers[i].ServerData
myContactCard.PullServers = append(myContactCard.PullServers, &srv) myContactCard.PullServers = append(myContactCard.PullServers, &srv)
} }
myContactCard.Name = myName myContactCard.Name = MyName
myContactCard.ContactPublicKey = peer.Me.Public myContactCard.ContactPublicKey = peer.Me.Public
myContactCard.EncryptionPublicKey = peer.EncryptionKp.Public myContactCard.EncryptionPublicKey = peer.EncryptionKp.Public
myContactCard.LookupPublicKey = peer.LookupKp.Public myContactCard.LookupPublicKey = peer.LookupKp.Public
@ -50,8 +47,8 @@ func (id *Identity) InvitePeer(myName string, contactName string, messageServerI
return &id.Peers[len(id.Peers)-1], &myContactCard return &id.Peers[len(id.Peers)-1], &myContactCard
} }
func (*Identity) FinalizeInvitation(peer *Peer, receivedContact *meowlib.ContactCard) { func (*Identity) FinalizeInvitation(peer *Peer, ReceivedContact *meowlib.ContactCard) {
peer.Contact = *receivedContact peer.Contact = *ReceivedContact
} }

View File

@ -7,16 +7,6 @@ import (
"forge.redroom.link/yves/meowlib" "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 { type Peer struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
// Conversation []InternalMessage `json:"conversation,omitempty"` // Conversation []InternalMessage `json:"conversation,omitempty"`
@ -61,23 +51,23 @@ func (pl *PeerList) GetFromName(name string) *Peer {
return nil return nil
} }
func (p *Peer) AsymEncryptMessage(Message []byte) (lookupK string, EncryptedMsg []byte, Signature []byte, Servers []*meowlib.Server, err error) { // AsymEncryptMessage prepares a message to send to a specific peer contact
// prepares a message to send to a specific peer contact func (p *Peer) AsymEncryptMessage(Message []byte) (LookupPublicKey string, EncryptedMessage []byte, Signature []byte, Servers []*meowlib.Server, err error) {
EncryptedMsg, Signature, err = meowlib.EncryptAndSign(p.Contact.EncryptionPublicKey, p.Me.Private, Message) EncryptedMessage, Signature, err = meowlib.EncryptAndSign(p.Contact.EncryptionPublicKey, p.Me.Private, Message)
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
return "", nil, nil, nil, err return "", nil, nil, nil, err
} }
return p.LookupKp.Public, EncryptedMsg, Signature, p.Contact.PullServers, err return p.LookupKp.Public, EncryptedMessage, Signature, p.Contact.PullServers, err
} }
func (p *Peer) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMsg []byte, err error) { // AsymDecryptMessage reads a message from a specific peer contact
// reads a message from a specific peer contact func (p *Peer) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMessage []byte, err error) {
DecryptedMsg, err = meowlib.DecryptAndCheck(p.Me.Private, p.Contact.ContactPublicKey, Message, Signature) DecryptedMessage, err = meowlib.DecryptAndCheck(p.Me.Private, p.Contact.ContactPublicKey, Message, Signature)
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
return nil, err return nil, err
} }
return DecryptedMsg, err return DecryptedMessage, err
} }

View File

@ -34,22 +34,22 @@ func (sl *InternalServerList) AddUrls(urls []string) {
} }
} }
func (ints *InternalServer) AsymEncryptMessage(Message []byte) (EncryptedMsg []byte, Signature []byte, err error) { // AsymEncryptMessage prepares a message to send to a specific internal server
// prepares a message to send to a specific internal server func (ints *InternalServer) AsymEncryptMessage(Message []byte) (EncryptedMessage []byte, Signature []byte, err error) {
EncryptedMsg, Signature, err = meowlib.EncryptAndSign(ints.ServerData.PublicKey, ints.Me.Private, Message) EncryptedMessage, Signature, err = meowlib.EncryptAndSign(ints.ServerData.PublicKey, ints.Me.Private, Message)
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
return nil, nil, err return nil, nil, err
} }
return EncryptedMsg, Signature, err return EncryptedMessage, Signature, err
} }
func (ints *InternalServer) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMsg []byte, err error) { // AsymDecryptMessage reads a message from a specific internal server
// reads a message from a specific internal server func (ints *InternalServer) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMessage []byte, err error) {
DecryptedMsg, err = meowlib.DecryptAndCheck(ints.Me.Private, ints.ServerData.PublicKey, Message, Signature) DecryptedMessage, err = meowlib.DecryptAndCheck(ints.Me.Private, ints.ServerData.PublicKey, Message, Signature)
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
return nil, err return nil, err
} }
return DecryptedMsg, err return DecryptedMessage, err
} }

View File

@ -20,14 +20,14 @@ func ServerFromUrl(url string) *Server {
return &s return &s
} }
func (contact *ContactCard) AddUrls(urls []string) { func (Contact *ContactCard) AddUrls(urls []string) {
for _, url := range urls { for _, url := range urls {
contact.PullServers = append(contact.PullServers, ServerFromUrl(url)) Contact.PullServers = append(Contact.PullServers, ServerFromUrl(url))
} }
} }
func (contact *ContactCard) WritePng(filename string) { func (Contact *ContactCard) WritePng(filename string) {
jsonContact, _ := json.Marshal(contact) jsonContact, _ := json.Marshal(Contact)
//imgdata := base64.StdEncoding.EncodeToString(jsonContact) //imgdata := base64.StdEncoding.EncodeToString(jsonContact)
size := int(math.Sqrt(float64(len(jsonContact))/3)) + 1 size := int(math.Sqrt(float64(len(jsonContact))/3)) + 1
println(size) println(size)
@ -65,8 +65,8 @@ func (contact *ContactCard) WritePng(filename string) {
} }
func (contact *ContactCard) WriteQr(filename string) { func (Contact *ContactCard) WriteQr(FileName string) {
jsonContact, _ := json.Marshal(contact) jsonContact, _ := json.Marshal(Contact)
qwriter := qrcode.NewQRCodeWriter() qwriter := qrcode.NewQRCodeWriter()
code, err := qwriter.Encode(string(jsonContact), gozxing.BarcodeFormat_QR_CODE, 512, 512, nil) code, err := qwriter.Encode(string(jsonContact), gozxing.BarcodeFormat_QR_CODE, 512, 512, nil)
if err != nil { if err != nil {
@ -81,8 +81,8 @@ func (contact *ContactCard) WriteQr(filename string) {
} }
func ReadQr(fielname string) ContactCard { func ReadQr(FileName string) ContactCard {
var contact ContactCard var Contact ContactCard
// open and decode image file // open and decode image file
file, _ := os.Open("qrcode.jpg") file, _ := os.Open("qrcode.jpg")
img, _, _ := image.Decode(file) img, _, _ := image.Decode(file)
@ -95,5 +95,5 @@ func ReadQr(fielname string) ContactCard {
result, _ := qrReader.Decode(bmp, nil) result, _ := qrReader.Decode(bmp, nil)
fmt.Println(result) fmt.Println(result)
return contact return Contact
} }

View File

@ -15,21 +15,21 @@ func TestEndToEnd(t *testing.T) {
// Create my own identity // Create my own identity
// //
fmt.Println("Trying to load identity from file.") fmt.Println("Trying to load identity from file.")
me, err := client.LoadIdentity("id.enc") Me, err := client.LoadIdentity("id.enc")
if err != nil { if err != nil {
fmt.Println("Failed : creating New identity...") fmt.Println("Failed : creating New identity...")
me = client.CreateIdentity("myname") Me = client.CreateIdentity("myname")
// //
// define my preferences (servers) // define my preferences (servers)
// //
me.MessageServers.Name = "Message Servers" Me.MessageServers.Name = "Message Servers"
me.MessageServers.AddUrls([]string{"http://127.0.0.1/meow/", "mqtt://127.0.0.1", "meow://127.0.0.1"}) Me.MessageServers.AddUrls([]string{"http://127.0.0.1/meow/", "mqtt://127.0.0.1", "meow://127.0.0.1"})
// //
// create an invitation for a friend, I want him/her to know me as Bender // create an invitation for a friend, I want him/her to know me as Bender
// //
fmt.Println("Creating an invitation for the first friend...") fmt.Println("Creating an invitation for the first friend...")
myFirstFriend, invitation := me.InvitePeer("Bender", "myfirstfriend", []int{1, 2}) MyFirstFriend, invitation := Me.InvitePeer("Bender", "myfirstfriend", []int{1, 2})
// print my invitation // print my invitation
a, _ := json.Marshal(invitation) a, _ := json.Marshal(invitation)
fmt.Println(string(a)) fmt.Println(string(a))
@ -38,17 +38,17 @@ func TestEndToEnd(t *testing.T) {
// //
// Simulate peer invitation response : generate the friend's keypair // Simulate peer invitation response : generate the friend's keypair
fmt.Println("Simulating first friend answer...") fmt.Println("Simulating first friend answer...")
var receivedContact meowlib.ContactCard var ReceivedContact meowlib.ContactCard
// Friend simulated invitation // Friend simulated invitation
firstFriendContactKp := meowlib.NewKeyPair() FirstFriendContactKp := meowlib.NewKeyPair()
firstFriendEncryptionKp := meowlib.NewKeyPair() FirstFriendEncryptionKp := meowlib.NewKeyPair()
firstFriendLookupKp := meowlib.NewKeyPair() FirstFriendLookupKp := meowlib.NewKeyPair()
receivedContact.Name = "I'm the friend" ReceivedContact.Name = "I'm the friend"
receivedContact.ContactPublicKey = firstFriendContactKp.Public ReceivedContact.ContactPublicKey = FirstFriendContactKp.Public
receivedContact.EncryptionPublicKey = firstFriendEncryptionKp.Public ReceivedContact.EncryptionPublicKey = FirstFriendEncryptionKp.Public
receivedContact.LookupPublicKey = firstFriendLookupKp.Public ReceivedContact.LookupPublicKey = FirstFriendLookupKp.Public
receivedContact.AddUrls([]string{"http://myfriend.org/meow/"}) ReceivedContact.AddUrls([]string{"http://myfriend.org/meow/"})
// end Friend simulated invitation // end Friend simulated invitation
// End simulating contact invitation response // End simulating contact invitation response
@ -57,19 +57,19 @@ func TestEndToEnd(t *testing.T) {
// //
// Finalize the contact with the invitation response // Finalize the contact with the invitation response
// //
me.FinalizeInvitation(myFirstFriend, &receivedContact) Me.FinalizeInvitation(MyFirstFriend, &ReceivedContact)
err = me.Save("id.enc") err = Me.Save("id.enc")
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
} }
a, _ = json.Marshal(me) a, _ = json.Marshal(Me)
ioutil.WriteFile("id.json", a, 0644) ioutil.WriteFile("id.json", a, 0644)
fmt.Println(string(a)) fmt.Println(string(a))
// create message to simulated friend // create message to simulated friend
sentmessage := "Hello friend!" sentmessage := "Hello friend!"
lookupK, EncMsg, MsgSignature, Servers, err := myFirstFriend.CreateMessage([]byte(sentmessage)) lookupK, EncMsg, Signature, Servers, err := MyFirstFriend.AsymEncryptMessage([]byte(sentmessage))
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
} }
@ -81,12 +81,33 @@ func TestEndToEnd(t *testing.T) {
// simulates if peer can decrypt my message // simulates if peer can decrypt my message
//Message := "toto" //Message := "toto"
//Signature := "test" //Signature := "test"
decMess, err2 := meowlib.DecryptAndCheck(myFirstFriend.EncryptionKp.Private, myFirstFriend.Contact.EncryptionPublicKey, []byte(EncMsg), MsgSignature) decMess, err2 := MyFirstFriend.AsymDecryptMessage([]byte(EncMsg), Signature)
if err2 != nil { if err2 != nil {
fmt.Println(err2.Error()) fmt.Println(err2.Error())
} }
fmt.Println(decMess) fmt.Println("--- myFriend.decryptedMess = ", string(decMess))
//
// simulates a new server to send a message to
var intS1 client.InternalServer
intS1.ServerData.Name = "IntS1"
intS1.ServerData.Description = "Internal Serveur 1"
intS1.Me = meowlib.NewKeyPair()
intS1.ServerData.Url = "http://myfriend.org/meow/"
KP := meowlib.NewKeyPair()
intS1.ServerData.PublicKey = KP.Public
// sends a message to server 1
SrvEncrypted, SrvSign, err3 := intS1.AsymEncryptMessage([]byte(sentmessage))
if err3 != nil {
fmt.Println(err3.Error())
}
// tests simulated server decrypted message
SrvDecrypted, err4 := intS1.AsymDecryptMessage(SrvEncrypted, SrvSign)
if err4 != nil {
fmt.Println(err4.Error())
}
fmt.Println("--- SrvDecryptedMess = ", string(SrvDecrypted))
} }
} }

478
id.enc
View File

@ -1,243 +1,243 @@
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
Comment: https://gopenpgp.org
Version: GopenPGP 2.2.4 Version: GopenPGP 2.2.4
Comment: https://gopenpgp.org
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
=zCs9 =ibSW
-----END PGP MESSAGE----- -----END PGP MESSAGE-----

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.26.0 // protoc-gen-go v1.28.1
// protoc v3.6.1 // protoc v3.21.5
// source: messages.proto // source: messages.proto
package meowlib package meowlib
@ -26,9 +26,9 @@ type PackedServerMessage struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
From string `protobuf:"bytes,1,opt,name=From,proto3" json:"From,omitempty"` From string `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"`
Payload []byte `protobuf:"bytes,2,opt,name=Payload,proto3" json:"Payload,omitempty"` Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"`
Signature []byte `protobuf:"bytes,3,opt,name=Signature,proto3" json:"Signature,omitempty"` Signature []byte `protobuf:"bytes,3,opt,name=signature,proto3" json:"signature,omitempty"`
} }
func (x *PackedServerMessage) Reset() { func (x *PackedServerMessage) Reset() {
@ -162,13 +162,13 @@ type ToServerMessage struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Type string `protobuf:"bytes,1,opt,name=Type,proto3" json:"Type,omitempty"` // Type Type string `protobuf:"bytes,1,opt,name=Type,proto3" json:"Type,omitempty"` // Type
ServerPubKey string `protobuf:"bytes,2,opt,name=ServerPubKey,proto3" json:"ServerPubKey,omitempty"` // My pub key for the server to send me an encrypter answer ServerPublicKey string `protobuf:"bytes,2,opt,name=ServerPublicKey,proto3" json:"ServerPublicKey,omitempty"` // My pub key for the server to send me an encrypter answer
Payload []byte `protobuf:"bytes,3,opt,name=Payload,proto3" json:"Payload,omitempty"` // optional payload for server Payload []byte `protobuf:"bytes,3,opt,name=Payload,proto3" json:"Payload,omitempty"` // optional payload for server
PullRequest []*ToServerMessage_ConversationRequest `protobuf:"bytes,7,rep,name=PullRequest,proto3" json:"PullRequest,omitempty"` PullRequest []*ToServerMessage_ConversationRequest `protobuf:"bytes,7,rep,name=PullRequest,proto3" json:"PullRequest,omitempty"`
Messages []*ToServerMessage_PostedMessage `protobuf:"bytes,9,rep,name=Messages,proto3" json:"Messages,omitempty"` Messages []*ToServerMessage_PostedMessage `protobuf:"bytes,9,rep,name=Messages,proto3" json:"Messages,omitempty"`
NextServerKey string `protobuf:"bytes,10,opt,name=NextServerKey,proto3" json:"NextServerKey,omitempty"` NextServerKey string `protobuf:"bytes,10,opt,name=NextServerKey,proto3" json:"NextServerKey,omitempty"`
Url string `protobuf:"bytes,11,opt,name=Url,proto3" json:"Url,omitempty"` Url string `protobuf:"bytes,11,opt,name=Url,proto3" json:"Url,omitempty"`
} }
func (x *ToServerMessage) Reset() { func (x *ToServerMessage) Reset() {
@ -210,9 +210,9 @@ func (x *ToServerMessage) GetType() string {
return "" return ""
} }
func (x *ToServerMessage) GetServerPubKey() string { func (x *ToServerMessage) GetServerPublicKey() string {
if x != nil { if x != nil {
return x.ServerPubKey return x.ServerPublicKey
} }
return "" return ""
} }
@ -448,10 +448,10 @@ type ContactCard struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
ContactPublicKey string `protobuf:"bytes,2,opt,name=contactPublicKey,proto3" json:"contactPublicKey,omitempty"` ContactPublicKey string `protobuf:"bytes,2,opt,name=ContactPublicKey,proto3" json:"ContactPublicKey,omitempty"`
EncryptionPublicKey string `protobuf:"bytes,3,opt,name=encryptionPublicKey,proto3" json:"encryptionPublicKey,omitempty"` EncryptionPublicKey string `protobuf:"bytes,3,opt,name=EncryptionPublicKey,proto3" json:"EncryptionPublicKey,omitempty"`
LookupPublicKey string `protobuf:"bytes,4,opt,name=lookupPublicKey,proto3" json:"lookupPublicKey,omitempty"` LookupPublicKey string `protobuf:"bytes,4,opt,name=LookupPublicKey,proto3" json:"LookupPublicKey,omitempty"`
PullServers []*Server `protobuf:"bytes,5,rep,name=PullServers,proto3" json:"PullServers,omitempty"` PullServers []*Server `protobuf:"bytes,5,rep,name=PullServers,proto3" json:"PullServers,omitempty"`
} }
@ -527,8 +527,8 @@ type MinimalContact struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
PublicKey string `protobuf:"bytes,2,opt,name=publicKey,proto3" json:"publicKey,omitempty"` PublicKey string `protobuf:"bytes,2,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"`
TrustedServers []*Server `protobuf:"bytes,3,rep,name=TrustedServers,proto3" json:"TrustedServers,omitempty"` TrustedServers []*Server `protobuf:"bytes,3,rep,name=TrustedServers,proto3" json:"TrustedServers,omitempty"`
} }
@ -590,13 +590,13 @@ type UserMessage struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Destination string `protobuf:"bytes,1,opt,name=Destination,proto3" json:"Destination,omitempty"` Destination string `protobuf:"bytes,1,opt,name=Destination,proto3" json:"Destination,omitempty"`
From string `protobuf:"bytes,2,opt,name=From,proto3" json:"From,omitempty"` From string `protobuf:"bytes,2,opt,name=From,proto3" json:"From,omitempty"`
Type string `protobuf:"bytes,3,opt,name=Type,proto3" json:"Type,omitempty"` Type string `protobuf:"bytes,3,opt,name=Type,proto3" json:"Type,omitempty"`
Data []byte `protobuf:"bytes,4,opt,name=Data,proto3" json:"Data,omitempty"` Data []byte `protobuf:"bytes,4,opt,name=Data,proto3" json:"Data,omitempty"`
Status *UserMessage_ConversationStatus `protobuf:"bytes,5,opt,name=Status,proto3" json:"Status,omitempty"` Status *UserMessage_ConversationStatus `protobuf:"bytes,5,opt,name=Status,proto3" json:"Status,omitempty"`
Contact *MinimalContact `protobuf:"bytes,6,opt,name=contact,proto3" json:"contact,omitempty"` Contact *MinimalContact `protobuf:"bytes,6,opt,name=Contact,proto3" json:"Contact,omitempty"`
Group *UserMessage_Group `protobuf:"bytes,7,opt,name=group,proto3" json:"group,omitempty"` DestinationGroup *UserMessage_Group `protobuf:"bytes,7,opt,name=DestinationGroup,proto3" json:"DestinationGroup,omitempty"`
} }
func (x *UserMessage) Reset() { func (x *UserMessage) Reset() {
@ -673,9 +673,9 @@ func (x *UserMessage) GetContact() *MinimalContact {
return nil return nil
} }
func (x *UserMessage) GetGroup() *UserMessage_Group { func (x *UserMessage) GetDestinationGroup() *UserMessage_Group {
if x != nil { if x != nil {
return x.Group return x.DestinationGroup
} }
return nil return nil
} }
@ -685,10 +685,10 @@ type ToServerMessage_ConversationRequest struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
LookupKey string `protobuf:"bytes,1,opt,name=lookupKey,proto3" json:"lookupKey,omitempty"` // lookup key for a conversation LookupKey string `protobuf:"bytes,1,opt,name=LookupKey,proto3" json:"LookupKey,omitempty"` // lookup key for a conversation
LastServerUuidOK string `protobuf:"bytes,2,opt,name=LastServerUuidOK,proto3" json:"LastServerUuidOK,omitempty"` // Last Server message UUID received (send me all after that one) LastServerUuidOK string `protobuf:"bytes,2,opt,name=LastServerUuidOK,proto3" json:"LastServerUuidOK,omitempty"` // Last Server message UUID received (send me all after that one)
PublishOnline bool `protobuf:"varint,3,opt,name=PublishOnline,proto3" json:"PublishOnline,omitempty"` // ?? Publish my online status for that contact ? PublishOnline bool `protobuf:"varint,3,opt,name=PublishOnline,proto3" json:"PublishOnline,omitempty"` // ?? Publish my online status for that contact ?
LookupSignature string `protobuf:"bytes,4,opt,name=lookupSignature,proto3" json:"lookupSignature,omitempty"` // prove that I own the private key by signing that block LookupSignature string `protobuf:"bytes,4,opt,name=LookupSignature,proto3" json:"LookupSignature,omitempty"` // prove that I own the private key by signing that block
} }
func (x *ToServerMessage_ConversationRequest) Reset() { func (x *ToServerMessage_ConversationRequest) Reset() {
@ -756,7 +756,7 @@ type ToServerMessage_PostedMessage struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
LookupKey string `protobuf:"bytes,1,opt,name=lookupKey,proto3" json:"lookupKey,omitempty"` LookupKey string `protobuf:"bytes,1,opt,name=LookupKey,proto3" json:"LookupKey,omitempty"`
Messages []*PackedUserMessage `protobuf:"bytes,2,rep,name=Messages,proto3" json:"Messages,omitempty"` Messages []*PackedUserMessage `protobuf:"bytes,2,rep,name=Messages,proto3" json:"Messages,omitempty"`
} }
@ -858,7 +858,7 @@ type FromServerMessage_PostedMessage struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
LookupKey string `protobuf:"bytes,1,opt,name=lookupKey,proto3" json:"lookupKey,omitempty"` LookupKey string `protobuf:"bytes,1,opt,name=LookupKey,proto3" json:"LookupKey,omitempty"`
Messages []*PackedUserMessage `protobuf:"bytes,2,rep,name=Messages,proto3" json:"Messages,omitempty"` Messages []*PackedUserMessage `protobuf:"bytes,2,rep,name=Messages,proto3" json:"Messages,omitempty"`
} }
@ -913,17 +913,17 @@ type UserMessage_ConversationStatus struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
LocalUuid string `protobuf:"bytes,1,opt,name=LocalUuid,proto3" json:"LocalUuid,omitempty"` LocalUuid string `protobuf:"bytes,1,opt,name=LocalUuid,proto3" json:"LocalUuid,omitempty"`
LocalSequence uint64 `protobuf:"varint,2,opt,name=LocalSequence,proto3" json:"LocalSequence,omitempty"` LocalSequence uint64 `protobuf:"varint,2,opt,name=LocalSequence,proto3" json:"LocalSequence,omitempty"`
Sent uint64 `protobuf:"varint,3,opt,name=Sent,proto3" json:"Sent,omitempty"` Sent uint64 `protobuf:"varint,3,opt,name=Sent,proto3" json:"Sent,omitempty"`
Received uint64 `protobuf:"varint,4,opt,name=Received,proto3" json:"Received,omitempty"` Received uint64 `protobuf:"varint,4,opt,name=Received,proto3" json:"Received,omitempty"`
Processed uint64 `protobuf:"varint,5,opt,name=Processed,proto3" json:"Processed,omitempty"` Processed uint64 `protobuf:"varint,5,opt,name=Processed,proto3" json:"Processed,omitempty"`
NextCkey string `protobuf:"bytes,6,opt,name=NextCkey,proto3" json:"NextCkey,omitempty"` // contact key NextContactKey string `protobuf:"bytes,6,opt,name=NextContactKey,proto3" json:"NextContactKey,omitempty"` // contact key
NextCkeyAck bool `protobuf:"varint,7,opt,name=NextCkeyAck,proto3" json:"NextCkeyAck,omitempty"` // false when proposing a new id, true for accepting it NextCcontactKeyAck bool `protobuf:"varint,7,opt,name=NextCcontactKeyAck,proto3" json:"NextCcontactKeyAck,omitempty"` // false when proposing a new id, true for accepting it
NextEkey string `protobuf:"bytes,8,opt,name=NextEkey,proto3" json:"NextEkey,omitempty"` // encryption key NextEncryptionKey string `protobuf:"bytes,8,opt,name=NextEncryptionKey,proto3" json:"NextEncryptionKey,omitempty"` // encryption key
NextKeyEkeyAck bool `protobuf:"varint,9,opt,name=NextKeyEkeyAck,proto3" json:"NextKeyEkeyAck,omitempty"` // false when proposing a new key, true for accpeting it NextKeyEncryptionKeyAck bool `protobuf:"varint,9,opt,name=NextKeyEncryptionKeyAck,proto3" json:"NextKeyEncryptionKeyAck,omitempty"` // false when proposing a new key, true for accpeting it
NextLkey string `protobuf:"bytes,10,opt,name=NextLkey,proto3" json:"NextLkey,omitempty"` // lookup key NextLookupKey string `protobuf:"bytes,10,opt,name=NextLookupKey,proto3" json:"NextLookupKey,omitempty"` // lookup key
NextLkeyAck bool `protobuf:"varint,11,opt,name=NextLkeyAck,proto3" json:"NextLkeyAck,omitempty"` // false when proposing a new id, true for accepting it NextLookupKeyAck bool `protobuf:"varint,11,opt,name=NextLookupKeyAck,proto3" json:"NextLookupKeyAck,omitempty"` // false when proposing a new id, true for accepting it
} }
func (x *UserMessage_ConversationStatus) Reset() { func (x *UserMessage_ConversationStatus) Reset() {
@ -993,44 +993,44 @@ func (x *UserMessage_ConversationStatus) GetProcessed() uint64 {
return 0 return 0
} }
func (x *UserMessage_ConversationStatus) GetNextCkey() string { func (x *UserMessage_ConversationStatus) GetNextContactKey() string {
if x != nil { if x != nil {
return x.NextCkey return x.NextContactKey
} }
return "" return ""
} }
func (x *UserMessage_ConversationStatus) GetNextCkeyAck() bool { func (x *UserMessage_ConversationStatus) GetNextCcontactKeyAck() bool {
if x != nil { if x != nil {
return x.NextCkeyAck return x.NextCcontactKeyAck
} }
return false return false
} }
func (x *UserMessage_ConversationStatus) GetNextEkey() string { func (x *UserMessage_ConversationStatus) GetNextEncryptionKey() string {
if x != nil { if x != nil {
return x.NextEkey return x.NextEncryptionKey
} }
return "" return ""
} }
func (x *UserMessage_ConversationStatus) GetNextKeyEkeyAck() bool { func (x *UserMessage_ConversationStatus) GetNextKeyEncryptionKeyAck() bool {
if x != nil { if x != nil {
return x.NextKeyEkeyAck return x.NextKeyEncryptionKeyAck
} }
return false return false
} }
func (x *UserMessage_ConversationStatus) GetNextLkey() string { func (x *UserMessage_ConversationStatus) GetNextLookupKey() string {
if x != nil { if x != nil {
return x.NextLkey return x.NextLookupKey
} }
return "" return ""
} }
func (x *UserMessage_ConversationStatus) GetNextLkeyAck() bool { func (x *UserMessage_ConversationStatus) GetNextLookupKeyAck() bool {
if x != nil { if x != nil {
return x.NextLkeyAck return x.NextLookupKeyAck
} }
return false return false
} }
@ -1040,8 +1040,8 @@ type UserMessage_Group struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
Members []*MinimalContact `protobuf:"bytes,2,rep,name=members,proto3" json:"members,omitempty"` Members []*MinimalContact `protobuf:"bytes,2,rep,name=Members,proto3" json:"Members,omitempty"`
} }
func (x *UserMessage_Group) Reset() { func (x *UserMessage_Group) Reset() {
@ -1096,11 +1096,11 @@ var file_messages_proto_rawDesc = []byte{
0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x07, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x22, 0x61, 0x0a, 0x13, 0x50, 0x61, 0x63, 0x12, 0x07, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x22, 0x61, 0x0a, 0x13, 0x50, 0x61, 0x63,
0x6b, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x6b, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x12, 0x12, 0x0a, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x46, 0x72, 0x6f, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1c, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1c,
0x0a, 0x09, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x09, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x81, 0x01, 0x0a, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x81, 0x01, 0x0a,
0x11, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x11, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x52, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e,
@ -1109,163 +1109,170 @@ var file_messages_proto_rawDesc = []byte{
0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f,
0x61, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18,
0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
0x22, 0xc8, 0x04, 0x0a, 0x0f, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x22, 0xce, 0x04, 0x0a, 0x0f, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76,
0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x09, 0x52, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b,
0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20,
0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x4e, 0x0a, 0x0b, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x4e, 0x0a, 0x0b,
0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6d, 0x65, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x07, 0x20, 0x03, 0x28,
0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x0b, 0x32, 0x2c, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x54, 0x6f, 0x53, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76,
0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0b, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x0b, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x08,
0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26,
0x69, 0x62, 0x2e, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x54, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x65,
0x67, 0x65, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x4d,
0x52, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x4e, 0x65,
0x78, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0d, 0x4e, 0x65, 0x78, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79,
0x12, 0x10, 0x0a, 0x03, 0x55, 0x72, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x55,
0x72, 0x6c, 0x1a, 0xaf, 0x01, 0x0a, 0x13, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f,
0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c,
0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x10, 0x4c, 0x61, 0x73, 0x74,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75, 0x69, 0x64, 0x4f, 0x4b, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x10, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75,
0x69, 0x64, 0x4f, 0x4b, 0x12, 0x24, 0x0a, 0x0d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f,
0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x50, 0x75, 0x62,
0x6c, 0x69, 0x73, 0x68, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x6c, 0x6f,
0x6f, 0x6b, 0x75, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x61,
0x74, 0x75, 0x72, 0x65, 0x1a, 0x65, 0x0a, 0x0d, 0x50, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b,
0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70,
0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18,
0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e,
0x50, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x52, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x92, 0x05, 0x0a, 0x11,
0x46, 0x72, 0x6f, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50,
0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x53, 0x65, 0x72,
0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x79,
0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x50, 0x61, 0x79, 0x6c,
0x6f, 0x61, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x63,
0x65, 0x69, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x53, 0x65, 0x72,
0x76, 0x65, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x53,
0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75, 0x69, 0x64, 0x12, 0x50, 0x0a, 0x0c, 0x50,
0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x08, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x2c, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x46, 0x72, 0x6f, 0x6d,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x75,
0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
0x0c, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a,
0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x28, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x46, 0x72, 0x6f, 0x6d, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x6f, 0x73, 0x74,
0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x4e, 0x65, 0x78, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65,
0x72, 0x4b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4e, 0x65, 0x78, 0x74,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x72, 0x6c,
0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x55, 0x72, 0x6c, 0x1a, 0x3a, 0x0a, 0x14, 0x43,
0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x75,
0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x55, 0x75, 0x69, 0x64, 0x73, 0x1a, 0x70, 0x0a, 0x11, 0x50, 0x75, 0x6c, 0x6c, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x45,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e,
0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x46, 0x72, 0x6f, 0x6d, 0x53, 0x65, 0x72, 0x76,
0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72,
0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x65, 0x0a, 0x0d, 0x50, 0x6f, 0x73,
0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f,
0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c,
0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x08, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6f,
0x77, 0x6c, 0x69, 0x62, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73,
0x22, 0x98, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x12, 0x24, 0x0a, 0x0d, 0x4e, 0x65, 0x78, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65,
0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4e, 0x65, 0x78, 0x74, 0x53, 0x65, 0x72,
0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x72, 0x6c, 0x18, 0x0b, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x55, 0x72, 0x6c, 0x1a, 0xaf, 0x01, 0x0a, 0x13, 0x43, 0x6f, 0x6e,
0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x1c, 0x0a, 0x09, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x09, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x2a,
0x0a, 0x10, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75, 0x69, 0x64,
0x4f, 0x4b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x55, 0x75, 0x69, 0x64, 0x4f, 0x4b, 0x12, 0x24, 0x0a, 0x0d, 0x50, 0x75,
0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
0x08, 0x52, 0x0d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65,
0x12, 0x28, 0x0a, 0x0f, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x4c, 0x6f, 0x6f, 0x6b, 0x75,
0x70, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x65, 0x0a, 0x0d, 0x50, 0x6f,
0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x4c,
0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x08, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65,
0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x73, 0x22, 0x92, 0x05, 0x0a, 0x11, 0x46, 0x72, 0x6f, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x53,
0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12,
0x18, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x07, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x53, 0x65, 0x72,
0x76, 0x65, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28,
0x04, 0x52, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65,
0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75, 0x69, 0x64, 0x18,
0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x75, 0x69,
0x64, 0x12, 0x50, 0x0a, 0x0c, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69,
0x62, 0x2e, 0x46, 0x72, 0x6f, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18,
0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e,
0x46, 0x72, 0x6f, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52,
0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x4e, 0x65, 0x78,
0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0d, 0x4e, 0x65, 0x78, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12,
0x10, 0x0a, 0x03, 0x55, 0x72, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x55, 0x72,
0x6c, 0x1a, 0x3a, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x55, 0x75, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52,
0x0c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x75, 0x69, 0x64, 0x73, 0x1a, 0x70, 0x0a,
0x11, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x03, 0x6b, 0x65, 0x79, 0x12, 0x45, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x46, 0x72,
0x6f, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a,
0x65, 0x0a, 0x0d, 0x50, 0x6f, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x12, 0x1c, 0x0a, 0x09, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x09, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x36,
0x0a, 0x08, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65,
0x64, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x98, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65,
0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63,
0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69,
0x63, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x75, 0x62, 0x6c,
0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03, 0x55, 0x72, 0x6c, 0x12, 0x28, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x64, 0x65, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05,
0x52, 0x0f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65,
0x6c, 0x22, 0xdc, 0x01, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x43, 0x61, 0x72,
0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74,
0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x10, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65,
0x79, 0x12, 0x30, 0x0a, 0x13, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50,
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13,
0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63,
0x4b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x50, 0x75, 0x62,
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x4c, 0x6f,
0x6f, 0x6b, 0x75, 0x70, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x31, 0x0a,
0x0b, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x53, 0x65, 0x72,
0x76, 0x65, 0x72, 0x52, 0x0b, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73,
0x22, 0x7b, 0x0a, 0x0e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x61,
0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63,
0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69,
0x63, 0x4b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x0e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x53,
0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6d,
0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0e, 0x54,
0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0xb2, 0x06,
0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a,
0x0b, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x12, 0x0a, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x46,
0x72, 0x6f, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18,
0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x06, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6d, 0x65,
0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74,
0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x31, 0x0a, 0x07,
0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x43,
0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x52, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12,
0x46, 0x0a, 0x10, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x72,
0x6f, 0x75, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6f, 0x77,
0x6c, 0x69, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x10, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x1a, 0xb8, 0x03, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x76,
0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c,
0x0a, 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x55, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x55, 0x75, 0x69, 0x64, 0x12, 0x24, 0x0a, 0x0d,
0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x04, 0x52, 0x0d, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e,
0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04,
0x52, 0x04, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76,
0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76,
0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18,
0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64,
0x12, 0x26, 0x0a, 0x0e, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x4b,
0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x63, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x12, 0x4e, 0x65, 0x78, 0x74,
0x43, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x6b, 0x18, 0x07,
0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x63, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x6b, 0x12, 0x2c, 0x0a, 0x11, 0x4e, 0x65, 0x78, 0x74,
0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x18, 0x08, 0x20,
0x01, 0x28, 0x09, 0x52, 0x11, 0x4e, 0x65, 0x78, 0x74, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x38, 0x0a, 0x17, 0x4e, 0x65, 0x78, 0x74, 0x4b, 0x65,
0x79, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63,
0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x4e, 0x65, 0x78, 0x74, 0x4b, 0x65, 0x79,
0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x6b,
0x12, 0x24, 0x0a, 0x0d, 0x4e, 0x65, 0x78, 0x74, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65,
0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4e, 0x65, 0x78, 0x74, 0x4c, 0x6f, 0x6f,
0x6b, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x10, 0x4e, 0x65, 0x78, 0x74, 0x4c, 0x6f,
0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x6b, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08,
0x52, 0x10, 0x4e, 0x65, 0x78, 0x74, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x41,
0x63, 0x6b, 0x1a, 0x4e, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x4e,
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12,
0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x31, 0x0a, 0x07, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6d,
0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x52, 0x07, 0x4d, 0x65, 0x6d, 0x62, 0x65,
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x72, 0x73, 0x42, 0x21, 0x5a, 0x1f, 0x66, 0x6f, 0x72, 0x67, 0x65, 0x2e, 0x72, 0x65, 0x64, 0x72,
0x10, 0x0a, 0x03, 0x55, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x55, 0x72, 0x6f, 0x6f, 0x6d, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x2f, 0x79, 0x76, 0x65, 0x73, 0x2f, 0x6d, 0x65,
0x6c, 0x12, 0x28, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x4c, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x76, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0xdc, 0x01, 0x0a, 0x0b,
0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x43, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63,
0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x63, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x13, 0x65,
0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b,
0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x28, 0x0a,
0x0f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79,
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x50, 0x75,
0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x0b, 0x50, 0x75, 0x6c, 0x6c, 0x53,
0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6d,
0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0b, 0x50,
0x75, 0x6c, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0x7b, 0x0a, 0x0e, 0x4d, 0x69,
0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x37,
0x0a, 0x0e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73,
0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62,
0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0xca, 0x05, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x74, 0x69,
0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65,
0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x46, 0x72, 0x6f,
0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x12, 0x0a,
0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70,
0x65, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x3f, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18,
0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e,
0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76,
0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x31, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63,
0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69,
0x62, 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74,
0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x30, 0x0a, 0x05, 0x67, 0x72, 0x6f,
0x75, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c,
0x69, 0x62, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x47,
0x72, 0x6f, 0x75, 0x70, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x1a, 0xe6, 0x02, 0x0a, 0x12,
0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74,
0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x55, 0x75, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x55, 0x75, 0x69, 0x64,
0x12, 0x24, 0x0a, 0x0d, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x65,
0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x74, 0x18, 0x03,
0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x65,
0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x52, 0x65,
0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73,
0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x50, 0x72, 0x6f, 0x63, 0x65,
0x73, 0x73, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x6b, 0x65, 0x79,
0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x6b, 0x65, 0x79,
0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x6b, 0x18,
0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x43, 0x6b, 0x65, 0x79, 0x41,
0x63, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x4e, 0x65, 0x78, 0x74, 0x45, 0x6b, 0x65, 0x79, 0x18, 0x08,
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4e, 0x65, 0x78, 0x74, 0x45, 0x6b, 0x65, 0x79, 0x12, 0x26,
0x0a, 0x0e, 0x4e, 0x65, 0x78, 0x74, 0x4b, 0x65, 0x79, 0x45, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x6b,
0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x4e, 0x65, 0x78, 0x74, 0x4b, 0x65, 0x79, 0x45,
0x6b, 0x65, 0x79, 0x41, 0x63, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x4e, 0x65, 0x78, 0x74, 0x4c, 0x6b,
0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4e, 0x65, 0x78, 0x74, 0x4c, 0x6b,
0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x4c, 0x6b, 0x65, 0x79, 0x41, 0x63,
0x6b, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x4e, 0x65, 0x78, 0x74, 0x4c, 0x6b, 0x65,
0x79, 0x41, 0x63, 0x6b, 0x1a, 0x4e, 0x0a, 0x05, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a,
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x12, 0x31, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x2e, 0x4d, 0x69, 0x6e,
0x69, 0x6d, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x52, 0x07, 0x6d, 0x65, 0x6d,
0x62, 0x65, 0x72, 0x73, 0x42, 0x21, 0x5a, 0x1f, 0x66, 0x6f, 0x72, 0x67, 0x65, 0x2e, 0x72, 0x65,
0x64, 0x72, 0x6f, 0x6f, 0x6d, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x2f, 0x79, 0x76, 0x65, 0x73, 0x2f,
0x6d, 0x65, 0x6f, 0x77, 0x6c, 0x69, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -1306,12 +1313,12 @@ var file_messages_proto_depIdxs = []int32{
4, // 4: meowlib.ContactCard.PullServers:type_name -> meowlib.Server 4, // 4: meowlib.ContactCard.PullServers:type_name -> meowlib.Server
4, // 5: meowlib.MinimalContact.TrustedServers:type_name -> meowlib.Server 4, // 5: meowlib.MinimalContact.TrustedServers:type_name -> meowlib.Server
13, // 6: meowlib.UserMessage.Status:type_name -> meowlib.UserMessage.ConversationStatus 13, // 6: meowlib.UserMessage.Status:type_name -> meowlib.UserMessage.ConversationStatus
6, // 7: meowlib.UserMessage.contact:type_name -> meowlib.MinimalContact 6, // 7: meowlib.UserMessage.Contact:type_name -> meowlib.MinimalContact
14, // 8: meowlib.UserMessage.group:type_name -> meowlib.UserMessage.Group 14, // 8: meowlib.UserMessage.DestinationGroup:type_name -> meowlib.UserMessage.Group
1, // 9: meowlib.ToServerMessage.PostedMessage.Messages:type_name -> meowlib.PackedUserMessage 1, // 9: meowlib.ToServerMessage.PostedMessage.Messages:type_name -> meowlib.PackedUserMessage
10, // 10: meowlib.FromServerMessage.PullResponseEntry.value:type_name -> meowlib.FromServerMessage.ConversationResponse 10, // 10: meowlib.FromServerMessage.PullResponseEntry.value:type_name -> meowlib.FromServerMessage.ConversationResponse
1, // 11: meowlib.FromServerMessage.PostedMessage.Messages:type_name -> meowlib.PackedUserMessage 1, // 11: meowlib.FromServerMessage.PostedMessage.Messages:type_name -> meowlib.PackedUserMessage
6, // 12: meowlib.UserMessage.Group.members:type_name -> meowlib.MinimalContact 6, // 12: meowlib.UserMessage.Group.Members:type_name -> meowlib.MinimalContact
13, // [13:13] is the sub-list for method output_type 13, // [13:13] is the sub-list for method output_type
13, // [13:13] is the sub-list for method input_type 13, // [13:13] is the sub-list for method input_type
13, // [13:13] is the sub-list for extension type_name 13, // [13:13] is the sub-list for extension type_name

View File

@ -1,7 +1,8 @@
package client package server
import ( import (
"encoding/json" "encoding/json"
"fmt"
"io/ioutil" "io/ioutil"
"forge.redroom.link/yves/meowlib" "forge.redroom.link/yves/meowlib"
@ -11,27 +12,24 @@ import (
const key = "3pw0c8#6ZG8{75b5;3?fe80$2" const key = "3pw0c8#6ZG8{75b5;3?fe80$2"
type Identity struct { type Identity struct {
ServerName string `json:"servername,omitempty"` ServerName string `json:"servername,omitempty"`
ServerDesc string `json:"servername,omitempty"` ServerDesc string `json:"serverdesc,omitempty"`
PublicKey string `json:"public_key,omitempty"` ServerKp meowlib.KeyPair `json:"server_kp,omitempty"`
PrivateKey string `json:"private_key,omitempty"` Status string `json:"status,omitempty"`
Status string `json:"status,omitempty"`
// KnownServers ServerList `json:"known_servers,omitempty"` // KnownServers ServerList `json:"known_servers,omitempty"`
} }
func CreateIdentity(servername string, serverdesc string) *Identity { func CreateIdentity(ServerName string, ServerDesc string) *Identity {
var id Identity var id Identity
id.ServerName = servername id.ServerName = ServerName
id.ServerDesc = serverdesc id.ServerDesc = ServerDesc
kp := meowlib.NewKeyPair() id.ServerKp = meowlib.NewKeyPair()
id.PublicKey = kp.Public
id.PrivateKey = kp.Private
return &id return &id
} }
func LoadIdentity(file string) (*Identity, error) { func LoadIdentity(File string) (*Identity, error) {
var id Identity var id Identity
indata, err := ioutil.ReadFile(file) indata, err := ioutil.ReadFile(File)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -52,3 +50,23 @@ func (id *Identity) Save(file string) error {
err = ioutil.WriteFile(file, []byte(armor), 0644) err = ioutil.WriteFile(file, []byte(armor), 0644)
return err return err
} }
// AsymEncryptMessage prepares a message to send to a specific client contact
func (id *Identity) AsymEncryptMessage(ClientPublicKey string, Message []byte) (EncryptedMsg []byte, Signature []byte, err error) {
EncryptedMsg, Signature, err = meowlib.EncryptAndSign(ClientPublicKey, id.ServerKp.Private, Message)
if err != nil {
fmt.Println(err.Error())
return nil, nil, err
}
return EncryptedMsg, Signature, err
}
// 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.DecryptAndCheck(id.ServerKp.Private, ClientPublicKey, Message, Signature)
if err != nil {
fmt.Println(err.Error())
return nil, err
}
return DecryptedMsg, err
}