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

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

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

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

	return NewSignedPreKeyFromStruct(signedPreKeyStructure, serializer)
}

// NewSignedPreKeyFromStruct returns a SignedPreKey record using the given
// serializable structure.
func NewSignedPreKeyFromStruct(structure *SignedPreKeyStructure,
	serializer SignedPreKeySerializer) (*SignedPreKey, error) {

	// Create the signed prekey record from the structure.
	signedPreKey := &SignedPreKey{
		structure:  *structure,
		serializer: serializer,
		signature:  bytehelper.SliceToArray64(structure.Signature),
	}

	// 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)
	signedPreKey.keyPair = keyPair

	return signedPreKey, nil
}

// NewSignedPreKey record creates a new signed pre key record
// with the given properties.
func NewSignedPreKey(id uint32, timestamp int64, keyPair *ecc.ECKeyPair,
	sig [64]byte, serializer SignedPreKeySerializer) *SignedPreKey {

	return &SignedPreKey{
		structure: SignedPreKeyStructure{
			ID:         id,
			Timestamp:  timestamp,
			PublicKey:  keyPair.PublicKey().Serialize(),
			PrivateKey: bytehelper.ArrayToSlice(keyPair.PrivateKey().Serialize()),
			Signature:  bytehelper.ArrayToSlice64(sig),
		},
		keyPair:    keyPair,
		signature:  sig,
		serializer: serializer,
	}
}

// SignedPreKeyStructure is a flat structure of a signed pre key, used
// for serialization and deserialization.
type SignedPreKeyStructure struct {
	ID         uint32
	PublicKey  []byte
	PrivateKey []byte
	Signature  []byte
	Timestamp  int64
}

// SignedPreKey record is a structure for storing a signed
// pre key in a SignedPreKey store.
type SignedPreKey struct {
	structure  SignedPreKeyStructure
	keyPair    *ecc.ECKeyPair
	signature  [64]byte
	serializer SignedPreKeySerializer
}

// ID returns the record's id.
func (s *SignedPreKey) ID() uint32 {
	return s.structure.ID
}

// Timestamp returns the record's timestamp
func (s *SignedPreKey) Timestamp() int64 {
	return s.structure.Timestamp
}

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

// Signature returns the record's signed prekey signature.
func (s *SignedPreKey) Signature() [64]byte {
	return s.signature
}

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