summaryrefslogtreecommitdiffstats
path: root/vendor/go.mau.fi/libsignal/groups/GroupSessionBuilder.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.mau.fi/libsignal/groups/GroupSessionBuilder.go')
-rw-r--r--vendor/go.mau.fi/libsignal/groups/GroupSessionBuilder.go84
1 files changed, 84 insertions, 0 deletions
diff --git a/vendor/go.mau.fi/libsignal/groups/GroupSessionBuilder.go b/vendor/go.mau.fi/libsignal/groups/GroupSessionBuilder.go
new file mode 100644
index 00000000..2a5569b7
--- /dev/null
+++ b/vendor/go.mau.fi/libsignal/groups/GroupSessionBuilder.go
@@ -0,0 +1,84 @@
+// Package groups is responsible for setting up group SenderKey encrypted sessions.
+// Once a session has been established, GroupCipher can be used to encrypt/decrypt
+// messages in that session.
+//
+// The built sessions are unidirectional: they can be used either for sending or
+// for receiving, but not both. Sessions are constructed per (groupId + senderId +
+// deviceId) tuple. Remote logical users are identified by their senderId, and each
+// logical recipientId can have multiple physical devices.
+package groups
+
+import (
+ "go.mau.fi/libsignal/groups/state/record"
+ "go.mau.fi/libsignal/groups/state/store"
+ "go.mau.fi/libsignal/protocol"
+ "go.mau.fi/libsignal/serialize"
+ "go.mau.fi/libsignal/util/keyhelper"
+)
+
+// NewGroupSessionBuilder will return a new group session builder.
+func NewGroupSessionBuilder(senderKeyStore store.SenderKey,
+ serializer *serialize.Serializer) *SessionBuilder {
+
+ return &SessionBuilder{
+ senderKeyStore: senderKeyStore,
+ serializer: serializer,
+ }
+}
+
+// SessionBuilder is a structure for building group sessions.
+type SessionBuilder struct {
+ senderKeyStore store.SenderKey
+ serializer *serialize.Serializer
+}
+
+// Process will process an incoming group message and set up the corresponding
+// session for it.
+func (b *SessionBuilder) Process(senderKeyName *protocol.SenderKeyName,
+ msg *protocol.SenderKeyDistributionMessage) {
+
+ senderKeyRecord := b.senderKeyStore.LoadSenderKey(senderKeyName)
+ if senderKeyRecord == nil {
+ senderKeyRecord = record.NewSenderKey(b.serializer.SenderKeyRecord, b.serializer.SenderKeyState)
+ }
+ senderKeyRecord.AddSenderKeyState(msg.ID(), msg.Iteration(), msg.ChainKey(), msg.SignatureKey())
+ b.senderKeyStore.StoreSenderKey(senderKeyName, senderKeyRecord)
+}
+
+// Create will create a new group session for the given name.
+func (b *SessionBuilder) Create(senderKeyName *protocol.SenderKeyName) (*protocol.SenderKeyDistributionMessage, error) {
+ // Load the senderkey by name
+ senderKeyRecord := b.senderKeyStore.LoadSenderKey(senderKeyName)
+
+ // If the record is empty, generate new keys.
+ if senderKeyRecord == nil || senderKeyRecord.IsEmpty() {
+ senderKeyRecord = record.NewSenderKey(b.serializer.SenderKeyRecord, b.serializer.SenderKeyState)
+ signingKey, err := keyhelper.GenerateSenderSigningKey()
+ if err != nil {
+ return nil, err
+ }
+ senderKeyRecord.SetSenderKeyState(
+ keyhelper.GenerateSenderKeyID(), 0,
+ keyhelper.GenerateSenderKey(),
+ signingKey,
+ )
+ b.senderKeyStore.StoreSenderKey(senderKeyName, senderKeyRecord)
+ }
+
+ // Get the senderkey state.
+ state, err := senderKeyRecord.SenderKeyState()
+ if err != nil {
+ return nil, err
+ }
+
+ // Create the group message to return.
+ senderKeyDistributionMessage := protocol.NewSenderKeyDistributionMessage(
+ state.KeyID(),
+ state.SenderChainKey().Iteration(),
+ state.SenderChainKey().Seed(),
+ state.SigningKey().PublicKey(),
+ b.serializer.SenderKeyDistributionMessage,
+ )
+
+ return senderKeyDistributionMessage, nil
+}