summaryrefslogtreecommitdiffstats
path: root/vendor/go.mau.fi/libsignal/protocol/SenderKeyMessage.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.mau.fi/libsignal/protocol/SenderKeyMessage.go')
-rw-r--r--vendor/go.mau.fi/libsignal/protocol/SenderKeyMessage.go168
1 files changed, 168 insertions, 0 deletions
diff --git a/vendor/go.mau.fi/libsignal/protocol/SenderKeyMessage.go b/vendor/go.mau.fi/libsignal/protocol/SenderKeyMessage.go
new file mode 100644
index 00000000..cd69cea4
--- /dev/null
+++ b/vendor/go.mau.fi/libsignal/protocol/SenderKeyMessage.go
@@ -0,0 +1,168 @@
+package protocol
+
+import (
+ "fmt"
+
+ "go.mau.fi/libsignal/ecc"
+ "go.mau.fi/libsignal/signalerror"
+ "go.mau.fi/libsignal/util/bytehelper"
+)
+
+// SenderKeyMessageSerializer is an interface for serializing and deserializing
+// SenderKeyMessages into bytes. An implementation of this interface should be
+// used to encode/decode the object into JSON, Protobuffers, etc.
+type SenderKeyMessageSerializer interface {
+ Serialize(signalMessage *SenderKeyMessageStructure) []byte
+ Deserialize(serialized []byte) (*SenderKeyMessageStructure, error)
+}
+
+// NewSenderKeyMessageFromBytes will return a Signal Ciphertext message from the given
+// bytes using the given serializer.
+func NewSenderKeyMessageFromBytes(serialized []byte,
+ serializer SenderKeyMessageSerializer) (*SenderKeyMessage, error) {
+
+ // Use the given serializer to decode the signal message.
+ senderKeyMessageStructure, err := serializer.Deserialize(serialized)
+ if err != nil {
+ return nil, err
+ }
+
+ return NewSenderKeyMessageFromStruct(senderKeyMessageStructure, serializer)
+}
+
+// NewSenderKeyMessageFromStruct returns a Signal Ciphertext message from the
+// given serializable structure.
+func NewSenderKeyMessageFromStruct(structure *SenderKeyMessageStructure,
+ serializer SenderKeyMessageSerializer) (*SenderKeyMessage, 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 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 (sender key message)", signalerror.ErrUnknownMessageVersion, structure.Version)
+ }
+
+ // Throw an error if the structure is missing critical fields.
+ if structure.CipherText == nil {
+ return nil, fmt.Errorf("%w (sender key message)", signalerror.ErrIncompleteMessage)
+ }
+
+ // Create the signal message object from the structure.
+ whisperMessage := &SenderKeyMessage{
+ keyID: structure.ID,
+ version: structure.Version,
+ iteration: structure.Iteration,
+ ciphertext: structure.CipherText,
+ signature: structure.Signature,
+ serializer: serializer,
+ }
+
+ return whisperMessage, nil
+}
+
+// NewSenderKeyMessage returns a SenderKeyMessage.
+func NewSenderKeyMessage(keyID uint32, iteration uint32, ciphertext []byte,
+ signatureKey ecc.ECPrivateKeyable, serializer SenderKeyMessageSerializer) *SenderKeyMessage {
+
+ // Ensure we have a valid signature key
+ if signatureKey == nil {
+ panic("Signature is nil. Unable to sign new senderkey message.")
+ }
+
+ // Build our SenderKeyMessage.
+ senderKeyMessage := &SenderKeyMessage{
+ keyID: keyID,
+ iteration: iteration,
+ ciphertext: ciphertext,
+ version: CurrentVersion,
+ serializer: serializer,
+ }
+
+ // Sign the serialized message and include it in the message. This will be included
+ // in the signed serialized version of the message.
+ signature := ecc.CalculateSignature(signatureKey, senderKeyMessage.Serialize())
+ senderKeyMessage.signature = bytehelper.ArrayToSlice64(signature)
+
+ return senderKeyMessage
+}
+
+// SenderKeyMessageStructure is a serializeable structure for SenderKey messages.
+type SenderKeyMessageStructure struct {
+ ID uint32
+ Iteration uint32
+ CipherText []byte
+ Version uint32
+ Signature []byte
+}
+
+// SenderKeyMessage is a structure for messages using senderkey groups.
+type SenderKeyMessage struct {
+ version uint32
+ keyID uint32
+ iteration uint32
+ ciphertext []byte
+ signature []byte
+ serializer SenderKeyMessageSerializer
+}
+
+// KeyID returns the SenderKeyMessage key ID.
+func (p *SenderKeyMessage) KeyID() uint32 {
+ return p.keyID
+}
+
+// Iteration returns the SenderKeyMessage iteration.
+func (p *SenderKeyMessage) Iteration() uint32 {
+ return p.iteration
+}
+
+// Ciphertext returns the SenderKeyMessage encrypted ciphertext.
+func (p *SenderKeyMessage) Ciphertext() []byte {
+ return p.ciphertext
+}
+
+// Version returns the Signal message version of the message.
+func (p *SenderKeyMessage) Version() uint32 {
+ return p.version
+}
+
+// Serialize will use the given serializer to return the message as bytes
+// excluding the signature. This should be used for signing and verifying
+// message signatures.
+func (p *SenderKeyMessage) Serialize() []byte {
+ structure := &SenderKeyMessageStructure{
+ ID: p.keyID,
+ Iteration: p.iteration,
+ CipherText: p.ciphertext,
+ Version: p.version,
+ }
+
+ return p.serializer.Serialize(structure)
+}
+
+// SignedSerialize will use the given serializer to return the message as
+// bytes with the message signature included. This should be used when
+// sending the message over the network.
+func (p *SenderKeyMessage) SignedSerialize() []byte {
+ structure := &SenderKeyMessageStructure{
+ ID: p.keyID,
+ Iteration: p.iteration,
+ CipherText: p.ciphertext,
+ Version: p.version,
+ Signature: p.signature,
+ }
+
+ return p.serializer.Serialize(structure)
+}
+
+// Signature returns the SenderKeyMessage signature
+func (p *SenderKeyMessage) Signature() [64]byte {
+ return bytehelper.SliceToArray64(p.signature)
+}
+
+// Type returns the sender key type.
+func (p *SenderKeyMessage) Type() uint32 {
+ return SENDERKEY_TYPE
+}