mirror of
https://github.com/cwinfo/matterbridge.git
synced 2024-12-27 21:25:39 +00:00
153 lines
5.0 KiB
Go
153 lines
5.0 KiB
Go
package protocol
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"go.mau.fi/libsignal/ecc"
|
|
"go.mau.fi/libsignal/keys/identity"
|
|
"go.mau.fi/libsignal/signalerror"
|
|
"go.mau.fi/libsignal/util/optional"
|
|
)
|
|
|
|
// PreKeySignalMessageSerializer is an interface for serializing and deserializing
|
|
// PreKeySignalMessages into bytes. An implementation of this interface should be
|
|
// used to encode/decode the object into JSON, Protobuffers, etc.
|
|
type PreKeySignalMessageSerializer interface {
|
|
Serialize(signalMessage *PreKeySignalMessageStructure) []byte
|
|
Deserialize(serialized []byte) (*PreKeySignalMessageStructure, error)
|
|
}
|
|
|
|
// NewPreKeySignalMessageFromBytes will return a Signal Ciphertext message from the given
|
|
// bytes using the given serializer.
|
|
func NewPreKeySignalMessageFromBytes(serialized []byte, serializer PreKeySignalMessageSerializer,
|
|
msgSerializer SignalMessageSerializer) (*PreKeySignalMessage, error) {
|
|
// Use the given serializer to decode the signal message.
|
|
signalMessageStructure, err := serializer.Deserialize(serialized)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return NewPreKeySignalMessageFromStruct(signalMessageStructure, serializer, msgSerializer)
|
|
}
|
|
|
|
// NewPreKeySignalMessageFromStruct will return a new PreKeySignalMessage from the given
|
|
// PreKeySignalMessageStructure.
|
|
func NewPreKeySignalMessageFromStruct(structure *PreKeySignalMessageStructure,
|
|
serializer PreKeySignalMessageSerializer, msgSerializer SignalMessageSerializer) (*PreKeySignalMessage, error) {
|
|
|
|
// Throw an error if the given message structure is an unsupported version.
|
|
if structure.Version <= UnsupportedVersion {
|
|
return nil, fmt.Errorf("%w %d (prekey message)", signalerror.ErrOldMessageVersion, structure.Version)
|
|
}
|
|
|
|
// Throw an error if the given message structure is a future version.
|
|
if structure.Version > CurrentVersion {
|
|
return nil, fmt.Errorf("%w %d (prekey message)", signalerror.ErrUnknownMessageVersion, structure.Version)
|
|
}
|
|
|
|
// Throw an error if the structure is missing critical fields.
|
|
if structure.BaseKey == nil || structure.IdentityKey == nil || structure.Message == nil {
|
|
return nil, fmt.Errorf("%w (prekey message)", signalerror.ErrIncompleteMessage)
|
|
}
|
|
|
|
// Create the signal message object from the structure.
|
|
preKeyWhisperMessage := &PreKeySignalMessage{structure: *structure, serializer: serializer}
|
|
|
|
// Generate the base ECC key from bytes.
|
|
var err error
|
|
preKeyWhisperMessage.baseKey, err = ecc.DecodePoint(structure.BaseKey, 0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Generate the identity key from bytes
|
|
var identityKey ecc.ECPublicKeyable
|
|
identityKey, err = ecc.DecodePoint(structure.IdentityKey, 0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
preKeyWhisperMessage.identityKey = identity.NewKey(identityKey)
|
|
|
|
// Generate the SignalMessage object from bytes.
|
|
preKeyWhisperMessage.message, err = NewSignalMessageFromBytes(structure.Message, msgSerializer)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return preKeyWhisperMessage, nil
|
|
}
|
|
|
|
// NewPreKeySignalMessage will return a new PreKeySignalMessage object.
|
|
func NewPreKeySignalMessage(version int, registrationID uint32, preKeyID *optional.Uint32, signedPreKeyID uint32,
|
|
baseKey ecc.ECPublicKeyable, identityKey *identity.Key, message *SignalMessage, serializer PreKeySignalMessageSerializer,
|
|
msgSerializer SignalMessageSerializer) (*PreKeySignalMessage, error) {
|
|
structure := &PreKeySignalMessageStructure{
|
|
Version: version,
|
|
RegistrationID: registrationID,
|
|
PreKeyID: preKeyID,
|
|
SignedPreKeyID: signedPreKeyID,
|
|
BaseKey: baseKey.Serialize(),
|
|
IdentityKey: identityKey.PublicKey().Serialize(),
|
|
Message: message.Serialize(),
|
|
}
|
|
return NewPreKeySignalMessageFromStruct(structure, serializer, msgSerializer)
|
|
}
|
|
|
|
// PreKeySignalMessageStructure is a serializable structure for
|
|
// PreKeySignalMessages.
|
|
type PreKeySignalMessageStructure struct {
|
|
RegistrationID uint32
|
|
PreKeyID *optional.Uint32
|
|
SignedPreKeyID uint32
|
|
BaseKey []byte
|
|
IdentityKey []byte
|
|
Message []byte
|
|
Version int
|
|
}
|
|
|
|
// PreKeySignalMessage is an encrypted Signal message that is designed
|
|
// to be used when building a session with someone for the first time.
|
|
type PreKeySignalMessage struct {
|
|
structure PreKeySignalMessageStructure
|
|
baseKey ecc.ECPublicKeyable
|
|
identityKey *identity.Key
|
|
message *SignalMessage
|
|
serializer PreKeySignalMessageSerializer
|
|
}
|
|
|
|
func (p *PreKeySignalMessage) MessageVersion() int {
|
|
return p.structure.Version
|
|
}
|
|
|
|
func (p *PreKeySignalMessage) IdentityKey() *identity.Key {
|
|
return p.identityKey
|
|
}
|
|
|
|
func (p *PreKeySignalMessage) RegistrationID() uint32 {
|
|
return p.structure.RegistrationID
|
|
}
|
|
|
|
func (p *PreKeySignalMessage) PreKeyID() *optional.Uint32 {
|
|
return p.structure.PreKeyID
|
|
}
|
|
|
|
func (p *PreKeySignalMessage) SignedPreKeyID() uint32 {
|
|
return p.structure.SignedPreKeyID
|
|
}
|
|
|
|
func (p *PreKeySignalMessage) BaseKey() ecc.ECPublicKeyable {
|
|
return p.baseKey
|
|
}
|
|
|
|
func (p *PreKeySignalMessage) WhisperMessage() *SignalMessage {
|
|
return p.message
|
|
}
|
|
|
|
func (p *PreKeySignalMessage) Serialize() []byte {
|
|
return p.serializer.Serialize(&p.structure)
|
|
}
|
|
|
|
func (p *PreKeySignalMessage) Type() uint32 {
|
|
return PREKEY_TYPE
|
|
}
|