1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
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
}
|