summaryrefslogtreecommitdiffstats
path: root/vendor/go.mau.fi/libsignal/protocol/SenderKeyDistributionMessage.go
blob: 55adcedee9462162ed15129c51012b24744f6f8b (plain) (blame)
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
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
}