summaryrefslogtreecommitdiffstats
path: root/vendor/go.mau.fi/libsignal/state/record/PreKeyRecord.go
blob: dcd630d211f106095b3cc5df4c612392ccf7ca30 (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
package record

import (
	"go.mau.fi/libsignal/ecc"
	"go.mau.fi/libsignal/util/bytehelper"
	"go.mau.fi/libsignal/util/optional"
)

// PreKeySerializer is an interface for serializing and deserializing
// PreKey objects into bytes. An implementation of this interface should be
// used to encode/decode the object into JSON, Protobuffers, etc.
type PreKeySerializer interface {
	Serialize(preKey *PreKeyStructure) []byte
	Deserialize(serialized []byte) (*PreKeyStructure, error)
}

// NewPreKeyFromBytes will return a prekey record from the given bytes using the given serializer.
func NewPreKeyFromBytes(serialized []byte, serializer PreKeySerializer) (*PreKey, error) {
	// Use the given serializer to decode the signal message.
	preKeyStructure, err := serializer.Deserialize(serialized)
	if err != nil {
		return nil, err
	}

	return NewPreKeyFromStruct(preKeyStructure, serializer)
}

// NewPreKeyFromStruct returns a PreKey record using the given serializable structure.
func NewPreKeyFromStruct(structure *PreKeyStructure, serializer PreKeySerializer) (*PreKey, error) {
	// Create the prekey record from the structure.
	preKey := &PreKey{
		structure:  *structure,
		serializer: serializer,
	}

	// Generate the ECC key from bytes.
	publicKey := ecc.NewDjbECPublicKey(bytehelper.SliceToArray(structure.PublicKey))
	privateKey := ecc.NewDjbECPrivateKey(bytehelper.SliceToArray(structure.PrivateKey))
	keyPair := ecc.NewECKeyPair(publicKey, privateKey)
	preKey.keyPair = keyPair

	return preKey, nil
}

// NewPreKey record returns a new pre key record that can
// be stored in a PreKeyStore.
func NewPreKey(id uint32, keyPair *ecc.ECKeyPair, serializer PreKeySerializer) *PreKey {
	return &PreKey{
		structure: PreKeyStructure{
			ID:         id,
			PublicKey:  keyPair.PublicKey().Serialize(),
			PrivateKey: bytehelper.ArrayToSlice(keyPair.PrivateKey().Serialize()),
		},
		keyPair:    keyPair,
		serializer: serializer,
	}
}

// PreKeyStructure is a structure for serializing PreKey records.
type PreKeyStructure struct {
	ID         uint32
	PublicKey  []byte
	PrivateKey []byte
}

// PreKey record is a structure for storing pre keys inside
// a PreKeyStore.
type PreKey struct {
	structure  PreKeyStructure
	keyPair    *ecc.ECKeyPair
	serializer PreKeySerializer
}

// ID returns the pre key record's id.
func (p *PreKey) ID() *optional.Uint32 {
	// TODO: manually set this to empty if empty
	return optional.NewOptionalUint32(p.structure.ID)
}

// KeyPair returns the pre key record's key pair.
func (p *PreKey) KeyPair() *ecc.ECKeyPair {
	return p.keyPair
}

// Serialize uses the PreKey serializer to return the PreKey
// as serialized bytes.
func (p *PreKey) Serialize() []byte {
	structure := p.structure
	return p.serializer.Serialize(&structure)
}