Files
go-mc/chat/sign/session.go
patyhank 185020e31c
Some checks failed
CodeQL / Analyze (go) (push) Has been cancelled
Go / Test (1.22) (push) Has been cancelled
Go / Test (^1.22) (push) Has been cancelled
Squashed below commits
nbt chat message

fixes some bug

chunk temp

relocate module

items id
2025-08-27 20:29:40 +08:00

94 lines
2.1 KiB
Go

package sign
import (
"crypto/sha256"
"encoding/binary"
"io"
"github.com/google/uuid"
"git.konjactw.dev/falloutBot/go-mc/chat"
pk "git.konjactw.dev/falloutBot/go-mc/net/packet"
"git.konjactw.dev/falloutBot/go-mc/yggdrasil/user"
)
type Message struct {
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
valid bool
lastMsg *Message
}
func (s Session) WriteTo(w io.Writer) (n int64, err error) {
n1, err := pk.UUID(s.SessionID).WriteTo(w)
if err != nil {
return n1, err
}
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)
if err != nil {
return n1, err
}
n2, err := s.PublicKey.ReadFrom(r)
return n1 + n2, err
}
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)
}