diff options
Diffstat (limited to 'vendor/go.mau.fi/libsignal/protocol/SenderKeyDistributionMessage.go')
-rw-r--r-- | vendor/go.mau.fi/libsignal/protocol/SenderKeyDistributionMessage.go | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/vendor/go.mau.fi/libsignal/protocol/SenderKeyDistributionMessage.go b/vendor/go.mau.fi/libsignal/protocol/SenderKeyDistributionMessage.go new file mode 100644 index 00000000..55adcede --- /dev/null +++ b/vendor/go.mau.fi/libsignal/protocol/SenderKeyDistributionMessage.go @@ -0,0 +1,147 @@ +package protocol + +import ( + "fmt" + + "go.mau.fi/libsignal/ecc" + "go.mau.fi/libsignal/signalerror" +) + +// SenderKeyDistributionMessageSerializer is an interface for serializing and deserializing +// SenderKeyDistributionMessages into bytes. An implementation of this interface should be +// used to encode/decode the object into JSON, Protobuffers, etc. +type SenderKeyDistributionMessageSerializer interface { + Serialize(signalMessage *SenderKeyDistributionMessageStructure) []byte + Deserialize(serialized []byte) (*SenderKeyDistributionMessageStructure, error) +} + +// NewSenderKeyDistributionMessageFromBytes will return a Signal Ciphertext message from the given +// bytes using the given serializer. +func NewSenderKeyDistributionMessageFromBytes(serialized []byte, + serializer SenderKeyDistributionMessageSerializer) (*SenderKeyDistributionMessage, error) { + + // Use the given serializer to decode the signal message. + signalMessageStructure, err := serializer.Deserialize(serialized) + if err != nil { + return nil, err + } + + return NewSenderKeyDistributionMessageFromStruct(signalMessageStructure, serializer) +} + +// NewSenderKeyDistributionMessageFromStruct returns a Signal Ciphertext message from the +// given serializable structure. +func NewSenderKeyDistributionMessageFromStruct(structure *SenderKeyDistributionMessageStructure, + serializer SenderKeyDistributionMessageSerializer) (*SenderKeyDistributionMessage, error) { + + // Throw an error if the given message structure is an unsupported version. + if structure.Version <= UnsupportedVersion { + return nil, fmt.Errorf("%w %d (sender key distribution)", 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 (sender key distribution)", signalerror.ErrUnknownMessageVersion, structure.Version) + } + + // Throw an error if the structure is missing critical fields. + if structure.SigningKey == nil || structure.ChainKey == nil { + return nil, fmt.Errorf("%w (sender key distribution)", signalerror.ErrIncompleteMessage) + } + + // Get the signing key object from bytes. + signingKey, err := ecc.DecodePoint(structure.SigningKey, 0) + if err != nil { + return nil, err + } + + // Create the signal message object from the structure. + message := &SenderKeyDistributionMessage{ + id: structure.ID, + iteration: structure.Iteration, + chainKey: structure.ChainKey, + version: structure.Version, + signatureKey: signingKey, + serializer: serializer, + } + + // Generate the ECC key from bytes. + message.signatureKey, err = ecc.DecodePoint(structure.SigningKey, 0) + if err != nil { + return nil, err + } + + return message, nil +} + +// NewSenderKeyDistributionMessage returns a Signal Ciphertext message. +func NewSenderKeyDistributionMessage(id uint32, iteration uint32, + chainKey []byte, signatureKey ecc.ECPublicKeyable, + serializer SenderKeyDistributionMessageSerializer) *SenderKeyDistributionMessage { + + return &SenderKeyDistributionMessage{ + id: id, + iteration: iteration, + chainKey: chainKey, + signatureKey: signatureKey, + serializer: serializer, + } +} + +// SenderKeyDistributionMessageStructure is a serializeable structure for senderkey +// distribution messages. +type SenderKeyDistributionMessageStructure struct { + ID uint32 + Iteration uint32 + ChainKey []byte + SigningKey []byte + Version uint32 +} + +// SenderKeyDistributionMessage is a structure for senderkey distribution messages. +type SenderKeyDistributionMessage struct { + id uint32 + iteration uint32 + chainKey []byte + version uint32 + signatureKey ecc.ECPublicKeyable + serializer SenderKeyDistributionMessageSerializer +} + +// ID will return the message's id. +func (p *SenderKeyDistributionMessage) ID() uint32 { + return p.id +} + +// Iteration will return the message's iteration. +func (p *SenderKeyDistributionMessage) Iteration() uint32 { + return p.iteration +} + +// ChainKey will return the message's chain key in bytes. +func (p *SenderKeyDistributionMessage) ChainKey() []byte { + return p.chainKey +} + +// SignatureKey will return the message's signature public key +func (p *SenderKeyDistributionMessage) SignatureKey() ecc.ECPublicKeyable { + return p.signatureKey +} + +// Serialize will use the given serializer and return the message as +// bytes. +func (p *SenderKeyDistributionMessage) Serialize() []byte { + structure := &SenderKeyDistributionMessageStructure{ + ID: p.id, + Iteration: p.iteration, + ChainKey: p.chainKey, + SigningKey: p.signatureKey.Serialize(), + Version: CurrentVersion, + } + return p.serializer.Serialize(structure) +} + +// Type will return the message's type. +func (p *SenderKeyDistributionMessage) Type() uint32 { + return SENDERKEY_DISTRIBUTION_TYPE +} |