mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-06-27 15:49:23 +00:00
Add dependencies/vendor (whatsapp)
This commit is contained in:
141
vendor/go.mau.fi/libsignal/groups/GroupCipher.go
vendored
Normal file
141
vendor/go.mau.fi/libsignal/groups/GroupCipher.go
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
package groups
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"go.mau.fi/libsignal/cipher"
|
||||
"go.mau.fi/libsignal/ecc"
|
||||
"go.mau.fi/libsignal/groups/ratchet"
|
||||
"go.mau.fi/libsignal/groups/state/record"
|
||||
"go.mau.fi/libsignal/groups/state/store"
|
||||
"go.mau.fi/libsignal/protocol"
|
||||
"go.mau.fi/libsignal/signalerror"
|
||||
)
|
||||
|
||||
// NewGroupCipher will return a new group message cipher that can be used for
|
||||
// encrypt/decrypt operations.
|
||||
func NewGroupCipher(builder *SessionBuilder, senderKeyID *protocol.SenderKeyName,
|
||||
senderKeyStore store.SenderKey) *GroupCipher {
|
||||
|
||||
return &GroupCipher{
|
||||
senderKeyID: senderKeyID,
|
||||
senderKeyStore: senderKeyStore,
|
||||
sessionBuilder: builder,
|
||||
}
|
||||
}
|
||||
|
||||
// GroupCipher is the main entry point for group encrypt/decrypt operations.
|
||||
// Once a session has been established, this can be used for
|
||||
// all encrypt/decrypt operations within that session.
|
||||
type GroupCipher struct {
|
||||
senderKeyID *protocol.SenderKeyName
|
||||
senderKeyStore store.SenderKey
|
||||
sessionBuilder *SessionBuilder
|
||||
}
|
||||
|
||||
// Encrypt will take the given message in bytes and return encrypted bytes.
|
||||
func (c *GroupCipher) Encrypt(plaintext []byte) (protocol.GroupCiphertextMessage, error) {
|
||||
// Load the sender key based on id from our store.
|
||||
keyRecord := c.senderKeyStore.LoadSenderKey(c.senderKeyID)
|
||||
senderKeyState, err := keyRecord.SenderKeyState()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get the message key from the senderkey state.
|
||||
senderKey, err := senderKeyState.SenderChainKey().SenderMessageKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Encrypt the plaintext.
|
||||
ciphertext, err := cipher.EncryptCbc(senderKey.Iv(), senderKey.CipherKey(), plaintext)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
senderKeyMessage := protocol.NewSenderKeyMessage(
|
||||
senderKeyState.KeyID(),
|
||||
senderKey.Iteration(),
|
||||
ciphertext,
|
||||
senderKeyState.SigningKey().PrivateKey(),
|
||||
c.sessionBuilder.serializer.SenderKeyMessage,
|
||||
)
|
||||
|
||||
senderKeyState.SetSenderChainKey(senderKeyState.SenderChainKey().Next())
|
||||
c.senderKeyStore.StoreSenderKey(c.senderKeyID, keyRecord)
|
||||
|
||||
return senderKeyMessage, nil
|
||||
}
|
||||
|
||||
// Decrypt decrypts the given message using an existing session that
|
||||
// is stored in the senderKey store.
|
||||
func (c *GroupCipher) Decrypt(senderKeyMessage *protocol.SenderKeyMessage) ([]byte, error) {
|
||||
keyRecord := c.senderKeyStore.LoadSenderKey(c.senderKeyID)
|
||||
|
||||
if keyRecord.IsEmpty() {
|
||||
return nil, fmt.Errorf("%w for %s in %s", signalerror.ErrNoSenderKeyForUser, c.senderKeyID.Sender().String(), c.senderKeyID.GroupID())
|
||||
}
|
||||
|
||||
// Get the senderkey state by id.
|
||||
senderKeyState, err := keyRecord.GetSenderKeyStateByID(senderKeyMessage.KeyID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Verify the signature of the senderkey message.
|
||||
verified := c.verifySignature(senderKeyState.SigningKey().PublicKey(), senderKeyMessage)
|
||||
if !verified {
|
||||
return nil, signalerror.ErrSenderKeyStateVerificationFailed
|
||||
}
|
||||
|
||||
senderKey, err := c.getSenderKey(senderKeyState, senderKeyMessage.Iteration())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Decrypt the message ciphertext.
|
||||
plaintext, err := cipher.DecryptCbc(senderKey.Iv(), senderKey.CipherKey(), senderKeyMessage.Ciphertext())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Store the sender key by id.
|
||||
c.senderKeyStore.StoreSenderKey(c.senderKeyID, keyRecord)
|
||||
|
||||
return plaintext, nil
|
||||
}
|
||||
|
||||
// verifySignature will verify the signature of the senderkey message with
|
||||
// the given public key.
|
||||
func (c *GroupCipher) verifySignature(signingPubKey ecc.ECPublicKeyable,
|
||||
senderKeyMessage *protocol.SenderKeyMessage) bool {
|
||||
|
||||
return ecc.VerifySignature(signingPubKey, senderKeyMessage.Serialize(), senderKeyMessage.Signature())
|
||||
}
|
||||
|
||||
func (c *GroupCipher) getSenderKey(senderKeyState *record.SenderKeyState, iteration uint32) (*ratchet.SenderMessageKey, error) {
|
||||
senderChainKey := senderKeyState.SenderChainKey()
|
||||
if senderChainKey.Iteration() > iteration {
|
||||
if senderKeyState.HasSenderMessageKey(iteration) {
|
||||
return senderKeyState.RemoveSenderMessageKey(iteration), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w (current: %d, received: %d)", signalerror.ErrOldCounter, senderChainKey.Iteration(), iteration)
|
||||
}
|
||||
|
||||
if iteration-senderChainKey.Iteration() > 2000 {
|
||||
return nil, signalerror.ErrTooFarIntoFuture
|
||||
}
|
||||
|
||||
for senderChainKey.Iteration() < iteration {
|
||||
senderMessageKey, err := senderChainKey.SenderMessageKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
senderKeyState.AddSenderMessageKey(senderMessageKey)
|
||||
senderChainKey = senderChainKey.Next()
|
||||
}
|
||||
|
||||
senderKeyState.SetSenderChainKey(senderChainKey.Next())
|
||||
return senderChainKey.SenderMessageKey()
|
||||
}
|
84
vendor/go.mau.fi/libsignal/groups/GroupSessionBuilder.go
vendored
Normal file
84
vendor/go.mau.fi/libsignal/groups/GroupSessionBuilder.go
vendored
Normal file
@ -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
|
||||
}
|
3
vendor/go.mau.fi/libsignal/groups/ratchet/Doc.go
vendored
Normal file
3
vendor/go.mau.fi/libsignal/groups/ratchet/Doc.go
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
// Package ratchet provides the methods necessary to establish a ratchet
|
||||
// session for group messaging.
|
||||
package ratchet
|
68
vendor/go.mau.fi/libsignal/groups/ratchet/SenderChainKey.go
vendored
Normal file
68
vendor/go.mau.fi/libsignal/groups/ratchet/SenderChainKey.go
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
package ratchet
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
)
|
||||
|
||||
var messageKeySeed = []byte{0x01}
|
||||
var chainKeySeed = []byte{0x02}
|
||||
|
||||
// NewSenderChainKey will return a new SenderChainKey.
|
||||
func NewSenderChainKey(iteration uint32, chainKey []byte) *SenderChainKey {
|
||||
return &SenderChainKey{
|
||||
iteration: iteration,
|
||||
chainKey: chainKey,
|
||||
}
|
||||
}
|
||||
|
||||
// NewSenderChainKeyFromStruct will return a new chain key object from the
|
||||
// given serializeable structure.
|
||||
func NewSenderChainKeyFromStruct(structure *SenderChainKeyStructure) *SenderChainKey {
|
||||
return &SenderChainKey{
|
||||
iteration: structure.Iteration,
|
||||
chainKey: structure.ChainKey,
|
||||
}
|
||||
}
|
||||
|
||||
// NewStructFromSenderChainKeys returns a serializeable structure of chain keys.
|
||||
func NewStructFromSenderChainKey(key *SenderChainKey) *SenderChainKeyStructure {
|
||||
return &SenderChainKeyStructure{
|
||||
Iteration: key.iteration,
|
||||
ChainKey: key.chainKey,
|
||||
}
|
||||
}
|
||||
|
||||
// SenderChainKeyStructure is a serializeable structure of SenderChainKeys.
|
||||
type SenderChainKeyStructure struct {
|
||||
Iteration uint32
|
||||
ChainKey []byte
|
||||
}
|
||||
|
||||
type SenderChainKey struct {
|
||||
iteration uint32
|
||||
chainKey []byte
|
||||
}
|
||||
|
||||
func (k *SenderChainKey) Iteration() uint32 {
|
||||
return k.iteration
|
||||
}
|
||||
|
||||
func (k *SenderChainKey) SenderMessageKey() (*SenderMessageKey, error) {
|
||||
return NewSenderMessageKey(k.iteration, k.getDerivative(messageKeySeed, k.chainKey))
|
||||
}
|
||||
|
||||
func (k *SenderChainKey) Next() *SenderChainKey {
|
||||
return NewSenderChainKey(k.iteration+1, k.getDerivative(chainKeySeed, k.chainKey))
|
||||
}
|
||||
|
||||
func (k *SenderChainKey) Seed() []byte {
|
||||
return k.chainKey
|
||||
}
|
||||
|
||||
func (k *SenderChainKey) getDerivative(seed []byte, key []byte) []byte {
|
||||
mac := hmac.New(sha256.New, key[:])
|
||||
mac.Write(seed)
|
||||
|
||||
return mac.Sum(nil)
|
||||
}
|
89
vendor/go.mau.fi/libsignal/groups/ratchet/SenderMessageKey.go
vendored
Normal file
89
vendor/go.mau.fi/libsignal/groups/ratchet/SenderMessageKey.go
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
package ratchet
|
||||
|
||||
import (
|
||||
"go.mau.fi/libsignal/kdf"
|
||||
"go.mau.fi/libsignal/util/bytehelper"
|
||||
)
|
||||
|
||||
// KdfInfo is optional bytes to include in deriving secrets with KDF.
|
||||
const KdfInfo string = "WhisperGroup"
|
||||
|
||||
// NewSenderMessageKey will return a new sender message key using the given
|
||||
// iteration and seed.
|
||||
func NewSenderMessageKey(iteration uint32, seed []byte) (*SenderMessageKey, error) {
|
||||
derivative, err := kdf.DeriveSecrets(seed, nil, []byte(KdfInfo), 48)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Split our derived secrets into 2 parts
|
||||
parts := bytehelper.Split(derivative, 16, 32)
|
||||
|
||||
// Build the message key.
|
||||
senderKeyMessage := &SenderMessageKey{
|
||||
iteration: iteration,
|
||||
seed: seed,
|
||||
iv: parts[0],
|
||||
cipherKey: parts[1],
|
||||
}
|
||||
|
||||
return senderKeyMessage, nil
|
||||
}
|
||||
|
||||
// NewSenderMessageKeyFromStruct will return a new message key object from the
|
||||
// given serializeable structure.
|
||||
func NewSenderMessageKeyFromStruct(structure *SenderMessageKeyStructure) *SenderMessageKey {
|
||||
return &SenderMessageKey{
|
||||
iteration: structure.Iteration,
|
||||
iv: structure.IV,
|
||||
cipherKey: structure.CipherKey,
|
||||
seed: structure.Seed,
|
||||
}
|
||||
}
|
||||
|
||||
// NewStructFromSenderMessageKey returns a serializeable structure of message keys.
|
||||
func NewStructFromSenderMessageKey(key *SenderMessageKey) *SenderMessageKeyStructure {
|
||||
return &SenderMessageKeyStructure{
|
||||
CipherKey: key.cipherKey,
|
||||
Iteration: key.iteration,
|
||||
IV: key.iv,
|
||||
Seed: key.seed,
|
||||
}
|
||||
}
|
||||
|
||||
// SenderMessageKeyStructure is a serializeable structure of SenderMessageKeys.
|
||||
type SenderMessageKeyStructure struct {
|
||||
Iteration uint32
|
||||
IV []byte
|
||||
CipherKey []byte
|
||||
Seed []byte
|
||||
}
|
||||
|
||||
// SenderMessageKey is a structure for sender message keys used in group
|
||||
// messaging.
|
||||
type SenderMessageKey struct {
|
||||
iteration uint32
|
||||
iv []byte
|
||||
cipherKey []byte
|
||||
seed []byte
|
||||
}
|
||||
|
||||
// Iteration will return the sender message key's iteration.
|
||||
func (k *SenderMessageKey) Iteration() uint32 {
|
||||
return k.iteration
|
||||
}
|
||||
|
||||
// Iv will return the sender message key's initialization vector.
|
||||
func (k *SenderMessageKey) Iv() []byte {
|
||||
return k.iv
|
||||
}
|
||||
|
||||
// CipherKey will return the key in bytes.
|
||||
func (k *SenderMessageKey) CipherKey() []byte {
|
||||
return k.cipherKey
|
||||
}
|
||||
|
||||
// Seed will return the sender message key's seed.
|
||||
func (k *SenderMessageKey) Seed() []byte {
|
||||
return k.seed
|
||||
}
|
2
vendor/go.mau.fi/libsignal/groups/state/record/Doc.go
vendored
Normal file
2
vendor/go.mau.fi/libsignal/groups/state/record/Doc.go
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
// Package record provides the state and record of a group session.
|
||||
package record
|
149
vendor/go.mau.fi/libsignal/groups/state/record/SenderKeyRecord.go
vendored
Normal file
149
vendor/go.mau.fi/libsignal/groups/state/record/SenderKeyRecord.go
vendored
Normal file
@ -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,
|
||||
}
|
||||
}
|
186
vendor/go.mau.fi/libsignal/groups/state/record/SenderKeyState.go
vendored
Normal file
186
vendor/go.mau.fi/libsignal/groups/state/record/SenderKeyState.go
vendored
Normal file
@ -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
|
||||
}
|
3
vendor/go.mau.fi/libsignal/groups/state/store/Doc.go
vendored
Normal file
3
vendor/go.mau.fi/libsignal/groups/state/store/Doc.go
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
// Package store provides the storage interfaces for storing group sender
|
||||
// key records.
|
||||
package store
|
11
vendor/go.mau.fi/libsignal/groups/state/store/SenderKeyStore.go
vendored
Normal file
11
vendor/go.mau.fi/libsignal/groups/state/store/SenderKeyStore.go
vendored
Normal file
@ -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
|
||||
}
|
Reference in New Issue
Block a user