You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
matterbridge/vendor/go.mau.fi/libsignal/groups/state/record/SenderKeyRecord.go

150 lines
4.8 KiB
Go

package record
import (
"fmt"
"go.mau.fi/libsignal/ecc"
"go.mau.fi/libsignal/signalerror"
)
const maxStates = 5
// SenderKeySerializer is an interface for serializing and deserializing
// SenderKey objects into bytes. An implementation of this interface should be
// used to encode/decode the object into JSON, Protobuffers, etc.
type SenderKeySerializer interface {
Serialize(preKey *SenderKeyStructure) []byte
Deserialize(serialized []byte) (*SenderKeyStructure, error)
}
// NewSenderKeyFromBytes will return a prekey record from the given bytes using the given serializer.
func NewSenderKeyFromBytes(serialized []byte, serializer SenderKeySerializer,
stateSerializer SenderKeyStateSerializer) (*SenderKey, error) {
// Use the given serializer to decode the senderkey record
senderKeyStructure, err := serializer.Deserialize(serialized)
if err != nil {
return nil, err
}
return NewSenderKeyFromStruct(senderKeyStructure, serializer, stateSerializer)
}
// NewSenderKeyFromStruct returns a SenderKey record using the given serializable structure.
func NewSenderKeyFromStruct(structure *SenderKeyStructure, serializer SenderKeySerializer,
stateSerializer SenderKeyStateSerializer) (*SenderKey, error) {
// Build our sender key states from structure.
senderKeyStates := make([]*SenderKeyState, len(structure.SenderKeyStates))
for i := range structure.SenderKeyStates {
var err error
senderKeyStates[i], err = NewSenderKeyStateFromStructure(structure.SenderKeyStates[i], stateSerializer)
if err != nil {
return nil, err
}
}
// Build and return our session.
senderKey := &SenderKey{
senderKeyStates: senderKeyStates,
serializer: serializer,
}
return senderKey, nil
}
// NewSenderKey record returns a new sender key record that can
// be stored in a SenderKeyStore.
func NewSenderKey(serializer SenderKeySerializer,
stateSerializer SenderKeyStateSerializer) *SenderKey {
return &SenderKey{
senderKeyStates: []*SenderKeyState{},
serializer: serializer,
stateSerializer: stateSerializer,
}
}
// SenderKeyStructure is a structure for serializing SenderKey records.
type SenderKeyStructure struct {
SenderKeyStates []*SenderKeyStateStructure
}
// SenderKey record is a structure for storing pre keys inside
// a SenderKeyStore.
type SenderKey struct {
senderKeyStates []*SenderKeyState
serializer SenderKeySerializer
stateSerializer SenderKeyStateSerializer
}
// SenderKeyState will return the first sender key state in the record's
// list of sender key states.
func (k *SenderKey) SenderKeyState() (*SenderKeyState, error) {
if len(k.senderKeyStates) > 0 {
return k.senderKeyStates[0], nil
}
return nil, signalerror.ErrNoSenderKeyStatesInRecord
}
// GetSenderKeyStateByID will return the sender key state with the given
// key id.
func (k *SenderKey) GetSenderKeyStateByID(keyID uint32) (*SenderKeyState, error) {
for i := 0; i < len(k.senderKeyStates); i++ {
if k.senderKeyStates[i].KeyID() == keyID {
return k.senderKeyStates[i], nil
}
}
return nil, fmt.Errorf("%w %d", signalerror.ErrNoSenderKeyStateForID, keyID)
}
// IsEmpty will return false if there is more than one state in this
// senderkey record.
func (k *SenderKey) IsEmpty() bool {
return len(k.senderKeyStates) == 0
}
// AddSenderKeyState will add a new state to this senderkey record with the given
// id, iteration, chainkey, and signature key.
func (k *SenderKey) AddSenderKeyState(id uint32, iteration uint32,
chainKey []byte, signatureKey ecc.ECPublicKeyable) {
newState := NewSenderKeyStateFromPublicKey(id, iteration, chainKey, signatureKey, k.stateSerializer)
k.senderKeyStates = append([]*SenderKeyState{newState}, k.senderKeyStates...)
if len(k.senderKeyStates) > maxStates {
k.senderKeyStates = k.senderKeyStates[:len(k.senderKeyStates)-1]
}
}
// SetSenderKeyState will replace the current senderkey states with the given
// senderkey state.
func (k *SenderKey) SetSenderKeyState(id uint32, iteration uint32,
chainKey []byte, signatureKey *ecc.ECKeyPair) {
newState := NewSenderKeyState(id, iteration, chainKey, signatureKey, k.stateSerializer)
k.senderKeyStates = make([]*SenderKeyState, 0, maxStates/2)
k.senderKeyStates = append(k.senderKeyStates, newState)
}
// Serialize will return the record as serialized bytes so it can be
// persistently stored.
func (k *SenderKey) Serialize() []byte {
return k.serializer.Serialize(k.Structure())
}
// Structure will return a simple serializable record structure.
// This is used for serialization to persistently
// store a session record.
func (k *SenderKey) Structure() *SenderKeyStructure {
senderKeyStates := make([]*SenderKeyStateStructure, len(k.senderKeyStates))
for i := range k.senderKeyStates {
senderKeyStates[i] = k.senderKeyStates[i].structure()
}
return &SenderKeyStructure{
SenderKeyStates: senderKeyStates,
}
}