Support chat validation

This commit is contained in:
Tnze
2023-01-01 18:43:21 +08:00
parent fa83b762bf
commit bb98d90db3
9 changed files with 239 additions and 152 deletions

View File

@ -1,6 +1,8 @@
package sign
import (
"crypto/sha256"
"encoding/binary"
"io"
"github.com/google/uuid"
@ -11,40 +13,81 @@ import (
)
type Message struct {
Link struct {
Index int
Sender uuid.UUID
Session uuid.UUID
}
Signature []byte
PackedMessageBody
Prev Prev
Signature *Signature
*MessageBody
Unsigned *chat.Message
FilterMask
}
type Prev struct {
Index int
Sender uuid.UUID
Session uuid.UUID
}
type Session struct {
sessionID uuid.UUID
publicKey user.PublicKey
SessionID uuid.UUID
PublicKey user.PublicKey
valid bool
lastMsg *Message
}
func (s Session) WriteTo(w io.Writer) (n int64, err error) {
n1, err := pk.UUID(s.sessionID).WriteTo(w)
n1, err := pk.UUID(s.SessionID).WriteTo(w)
if err != nil {
return n1, err
}
n2, err := s.publicKey.WriteTo(w)
n2, err := s.PublicKey.WriteTo(w)
return n1 + n2, err
}
func (s *Session) ReadFrom(r io.Reader) (n int64, err error) {
n1, err := ((*pk.UUID)(&s.sessionID)).ReadFrom(r)
n1, err := ((*pk.UUID)(&s.SessionID)).ReadFrom(r)
if err != nil {
return n1, err
}
n2, err := s.publicKey.ReadFrom(r)
n2, err := s.PublicKey.ReadFrom(r)
return n1 + n2, err
}
func (s *Session) Update(msg Message) bool {
panic("todo")
func (s *Session) InitValidate() {
s.valid = true
s.lastMsg = nil
}
func (s *Session) VerifyAndUpdate(msg *Message) bool {
s.valid = s.valid && s.verifyHash(msg) && s.verifyChain(msg)
if s.valid {
s.lastMsg = msg
return true
}
return false
}
func (s *Session) verifyHash(msg *Message) bool {
h := sha256.New()
// 1
_ = binary.Write(h, binary.BigEndian, int32(1))
// Prev
_, _ = h.Write(msg.Prev.Sender[:])
_, _ = h.Write(msg.Prev.Session[:])
_ = binary.Write(h, binary.BigEndian, msg.Prev.Index)
// Body
_ = binary.Write(h, binary.BigEndian, msg.Salt)
_ = binary.Write(h, binary.BigEndian, msg.Timestamp.Unix())
content := []byte(msg.PlainMsg)
_ = binary.Write(h, binary.BigEndian, int32(len(content)))
_, _ = h.Write(content)
// Body.LastSeen
_ = binary.Write(h, binary.BigEndian, int32(len(msg.LastSeen)))
for _, v := range msg.LastSeen {
_, _ = h.Write((*v)[:])
}
return s.PublicKey.VerifyMessage(h.Sum(nil), msg.Signature[:]) == nil
}
func (s *Session) verifyChain(msg *Message) bool {
return s.lastMsg != nil && (msg.Prev.Index < s.lastMsg.Prev.Index || msg.Prev.Sender != s.lastMsg.Prev.Sender || msg.Prev.Session != s.lastMsg.Prev.Session)
}