summaryrefslogtreecommitdiffstats
path: root/vendor/go.mau.fi/libsignal/groups/state
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.mau.fi/libsignal/groups/state')
-rw-r--r--vendor/go.mau.fi/libsignal/groups/state/record/Doc.go2
-rw-r--r--vendor/go.mau.fi/libsignal/groups/state/record/SenderKeyRecord.go149
-rw-r--r--vendor/go.mau.fi/libsignal/groups/state/record/SenderKeyState.go186
-rw-r--r--vendor/go.mau.fi/libsignal/groups/state/store/Doc.go3
-rw-r--r--vendor/go.mau.fi/libsignal/groups/state/store/SenderKeyStore.go11
5 files changed, 351 insertions, 0 deletions
diff --git a/vendor/go.mau.fi/libsignal/groups/state/record/Doc.go b/vendor/go.mau.fi/libsignal/groups/state/record/Doc.go
new file mode 100644
index 00000000..5a7d7307
--- /dev/null
+++ b/vendor/go.mau.fi/libsignal/groups/state/record/Doc.go
@@ -0,0 +1,2 @@
+// Package record provides the state and record of a group session.
+package record
diff --git a/vendor/go.mau.fi/libsignal/groups/state/record/SenderKeyRecord.go b/vendor/go.mau.fi/libsignal/groups/state/record/SenderKeyRecord.go
new file mode 100644
index 00000000..64d59068
--- /dev/null
+++ b/vendor/go.mau.fi/libsignal/groups/state/record/SenderKeyRecord.go
@@ -0,0 +1,149 @@
+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,
+ }
+}
diff --git a/vendor/go.mau.fi/libsignal/groups/state/record/SenderKeyState.go b/vendor/go.mau.fi/libsignal/groups/state/record/SenderKeyState.go
new file mode 100644
index 00000000..e3187c30
--- /dev/null
+++ b/vendor/go.mau.fi/libsignal/groups/state/record/SenderKeyState.go
@@ -0,0 +1,186 @@
+package record
+
+import (
+ "go.mau.fi/libsignal/ecc"
+ "go.mau.fi/libsignal/groups/ratchet"
+ "go.mau.fi/libsignal/util/bytehelper"
+)
+
+const maxMessageKeys = 2000
+
+// SenderKeyStateSerializer is an interface for serializing and deserializing
+// a Signal State into bytes. An implementation of this interface should be
+// used to encode/decode the object into JSON, Protobuffers, etc.
+type SenderKeyStateSerializer interface {
+ Serialize(state *SenderKeyStateStructure) []byte
+ Deserialize(serialized []byte) (*SenderKeyStateStructure, error)
+}
+
+// NewSenderKeyStateFromBytes will return a Signal State from the given
+// bytes using the given serializer.
+func NewSenderKeyStateFromBytes(serialized []byte, serializer SenderKeyStateSerializer) (*SenderKeyState, error) {
+ // Use the given serializer to decode the signal message.
+ stateStructure, err := serializer.Deserialize(serialized)
+ if err != nil {
+ return nil, err
+ }
+
+ return NewSenderKeyStateFromStructure(stateStructure, serializer)
+}
+
+// NewSenderKeyState returns a new SenderKeyState.
+func NewSenderKeyState(keyID uint32, iteration uint32, chainKey []byte,
+ signatureKey *ecc.ECKeyPair, serializer SenderKeyStateSerializer) *SenderKeyState {
+
+ return &SenderKeyState{
+ keys: make([]*ratchet.SenderMessageKey, 0, maxMessageKeys/2),
+ keyID: keyID,
+ senderChainKey: ratchet.NewSenderChainKey(iteration, chainKey),
+ signingKeyPair: signatureKey,
+ serializer: serializer,
+ }
+}
+
+// NewSenderKeyStateFromPublicKey returns a new SenderKeyState with the given publicKey.
+func NewSenderKeyStateFromPublicKey(keyID uint32, iteration uint32, chainKey []byte,
+ signatureKey ecc.ECPublicKeyable, serializer SenderKeyStateSerializer) *SenderKeyState {
+
+ keyPair := ecc.NewECKeyPair(signatureKey, nil)
+
+ return &SenderKeyState{
+ keys: make([]*ratchet.SenderMessageKey, 0, maxMessageKeys/2),
+ keyID: keyID,
+ senderChainKey: ratchet.NewSenderChainKey(iteration, chainKey),
+ signingKeyPair: keyPair,
+ serializer: serializer,
+ }
+}
+
+// NewSenderKeyStateFromStructure will return a new session state with the
+// given state structure. This structure is given back from an
+// implementation of the sender key state serializer.
+func NewSenderKeyStateFromStructure(structure *SenderKeyStateStructure,
+ serializer SenderKeyStateSerializer) (*SenderKeyState, error) {
+
+ // Convert our ecc keys from bytes into object form.
+ signingKeyPublic, err := ecc.DecodePoint(structure.SigningKeyPublic, 0)
+ if err != nil {
+ return nil, err
+ }
+ signingKeyPrivate := ecc.NewDjbECPrivateKey(bytehelper.SliceToArray(structure.SigningKeyPrivate))
+
+ // Build our sender message keys from structure
+ senderMessageKeys := make([]*ratchet.SenderMessageKey, len(structure.Keys))
+ for i := range structure.Keys {
+ senderMessageKeys[i] = ratchet.NewSenderMessageKeyFromStruct(structure.Keys[i])
+ }
+
+ // Build our state object.
+ state := &SenderKeyState{
+ keys: senderMessageKeys,
+ keyID: structure.KeyID,
+ senderChainKey: ratchet.NewSenderChainKeyFromStruct(structure.SenderChainKey),
+ signingKeyPair: ecc.NewECKeyPair(signingKeyPublic, signingKeyPrivate),
+ serializer: serializer,
+ }
+
+ return state, nil
+}
+
+// SenderKeyStateStructure is a serializeable structure of SenderKeyState.
+type SenderKeyStateStructure struct {
+ Keys []*ratchet.SenderMessageKeyStructure
+ KeyID uint32
+ SenderChainKey *ratchet.SenderChainKeyStructure
+ SigningKeyPrivate []byte
+ SigningKeyPublic []byte
+}
+
+// SenderKeyState is a structure for maintaining a senderkey session state.
+type SenderKeyState struct {
+ keys []*ratchet.SenderMessageKey
+ keyID uint32
+ senderChainKey *ratchet.SenderChainKey
+ signingKeyPair *ecc.ECKeyPair
+ serializer SenderKeyStateSerializer
+}
+
+// SigningKey returns the signing key pair of the sender key state.
+func (k *SenderKeyState) SigningKey() *ecc.ECKeyPair {
+ return k.signingKeyPair
+}
+
+// SenderChainKey returns the sender chain key of the state.
+func (k *SenderKeyState) SenderChainKey() *ratchet.SenderChainKey {
+ return k.senderChainKey
+}
+
+// KeyID returns the state's key id.
+func (k *SenderKeyState) KeyID() uint32 {
+ return k.keyID
+}
+
+// HasSenderMessageKey will return true if the state has a key with the
+// given iteration.
+func (k *SenderKeyState) HasSenderMessageKey(iteration uint32) bool {
+ for i := 0; i < len(k.keys); i++ {
+ if k.keys[i].Iteration() == iteration {
+ return true
+ }
+ }
+ return false
+}
+
+// AddSenderMessageKey will add the given sender message key to the state.
+func (k *SenderKeyState) AddSenderMessageKey(senderMsgKey *ratchet.SenderMessageKey) {
+ k.keys = append(k.keys, senderMsgKey)
+
+ if len(k.keys) > maxMessageKeys {
+ k.keys = k.keys[1:]
+ }
+}
+
+// SetSenderChainKey will set the state's sender chain key with the given key.
+func (k *SenderKeyState) SetSenderChainKey(senderChainKey *ratchet.SenderChainKey) {
+ k.senderChainKey = senderChainKey
+}
+
+// RemoveSenderMessageKey will remove the key in this state with the given iteration number.
+func (k *SenderKeyState) RemoveSenderMessageKey(iteration uint32) *ratchet.SenderMessageKey {
+ for i := 0; i < len(k.keys); i++ {
+ if k.keys[i].Iteration() == iteration {
+ removed := k.keys[i]
+ k.keys = append(k.keys[0:i], k.keys[i+1:]...)
+ return removed
+ }
+ }
+
+ return nil
+}
+
+// Serialize will return the state as bytes using the given serializer.
+func (k *SenderKeyState) Serialize() []byte {
+ return k.serializer.Serialize(k.structure())
+}
+
+// structure will return a serializable structure of the
+// the given state so it can be persistently stored.
+func (k *SenderKeyState) structure() *SenderKeyStateStructure {
+ // Convert our sender message keys into a serializeable structure
+ keys := make([]*ratchet.SenderMessageKeyStructure, len(k.keys))
+ for i := range k.keys {
+ keys[i] = ratchet.NewStructFromSenderMessageKey(k.keys[i])
+ }
+
+ // Build and return our state structure.
+ s := &SenderKeyStateStructure{
+ Keys: keys,
+ KeyID: k.keyID,
+ SenderChainKey: ratchet.NewStructFromSenderChainKey(k.senderChainKey),
+ SigningKeyPublic: k.signingKeyPair.PublicKey().Serialize(),
+ }
+ if k.signingKeyPair.PrivateKey() != nil {
+ s.SigningKeyPrivate = bytehelper.ArrayToSlice(k.signingKeyPair.PrivateKey().Serialize())
+ }
+ return s
+}
diff --git a/vendor/go.mau.fi/libsignal/groups/state/store/Doc.go b/vendor/go.mau.fi/libsignal/groups/state/store/Doc.go
new file mode 100644
index 00000000..8a23b446
--- /dev/null
+++ b/vendor/go.mau.fi/libsignal/groups/state/store/Doc.go
@@ -0,0 +1,3 @@
+// Package store provides the storage interfaces for storing group sender
+// key records.
+package store
diff --git a/vendor/go.mau.fi/libsignal/groups/state/store/SenderKeyStore.go b/vendor/go.mau.fi/libsignal/groups/state/store/SenderKeyStore.go
new file mode 100644
index 00000000..a068df7c
--- /dev/null
+++ b/vendor/go.mau.fi/libsignal/groups/state/store/SenderKeyStore.go
@@ -0,0 +1,11 @@
+package store
+
+import (
+ "go.mau.fi/libsignal/groups/state/record"
+ "go.mau.fi/libsignal/protocol"
+)
+
+type SenderKey interface {
+ StoreSenderKey(senderKeyName *protocol.SenderKeyName, keyRecord *record.SenderKey)
+ LoadSenderKey(senderKeyName *protocol.SenderKeyName) *record.SenderKey
+}