pickle.cpp 5.99 KB
Newer Older
Mark Haines's avatar
Mark Haines committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* Copyright 2015 OpenMarket Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
15
#include "olm/pickle.hh"
16
#include "olm/pickle.h"
17

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
std::uint8_t * olm::pickle(
    std::uint8_t * pos,
    std::uint32_t value
) {
    pos += 4;
    for (unsigned i = 4; i--;) { *(--pos) = value; value >>= 8; }
    return pos + 4;
}


std::uint8_t const * olm::unpickle(
    std::uint8_t const * pos, std::uint8_t const * end,
    std::uint32_t & value
) {
    value = 0;
Denis Kasak's avatar
Denis Kasak committed
33
    if (!pos || end <= pos + 4) return nullptr;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    for (unsigned i = 4; i--;) { value <<= 8; value |= *(pos++); }
    return pos;
}

std::uint8_t * olm::pickle(
    std::uint8_t * pos,
    bool value
) {
    *(pos++) = value ? 1 : 0;
    return pos;
}

std::uint8_t const * olm::unpickle(
    std::uint8_t const * pos, std::uint8_t const * end,
    bool & value
) {
Denis Kasak's avatar
Denis Kasak committed
50
    if (!pos || pos == end) return nullptr;
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
    value = *(pos++);
    return pos;
}

std::uint8_t * olm::pickle_bytes(
    std::uint8_t * pos,
    std::uint8_t const * bytes, std::size_t bytes_length
) {
    std::memcpy(pos, bytes, bytes_length);
    return pos + bytes_length;
}

std::uint8_t const * olm::unpickle_bytes(
    std::uint8_t const * pos, std::uint8_t const * end,
    std::uint8_t * bytes, std::size_t bytes_length
) {
Denis Kasak's avatar
Denis Kasak committed
67
    if (!pos || end < pos + bytes_length) return nullptr;
68
69
70
71
    std::memcpy(bytes, pos, bytes_length);
    return pos + bytes_length;
}

72

73
std::size_t olm::pickle_length(
74
    const _olm_curve25519_public_key & value
75
76
77
78
79
) {
    return sizeof(value.public_key);
}


80
std::uint8_t * olm::pickle(
81
    std::uint8_t * pos,
82
    const _olm_curve25519_public_key & value
83
) {
84
    pos = olm::pickle_bytes(
85
86
87
88
89
90
        pos, value.public_key, sizeof(value.public_key)
    );
    return pos;
}


91
std::uint8_t const * olm::unpickle(
92
    std::uint8_t const * pos, std::uint8_t const * end,
93
    _olm_curve25519_public_key & value
94
) {
Denis Kasak's avatar
Denis Kasak committed
95
    return olm::unpickle_bytes(
96
97
98
99
100
        pos, end, value.public_key, sizeof(value.public_key)
    );
}


101
std::size_t olm::pickle_length(
102
    const _olm_curve25519_key_pair & value
103
) {
104
105
    return sizeof(value.public_key.public_key)
        + sizeof(value.private_key.private_key);
106
107
108
}


109
std::uint8_t * olm::pickle(
110
    std::uint8_t * pos,
111
    const _olm_curve25519_key_pair & value
112
) {
113
    pos = olm::pickle_bytes(
114
115
        pos, value.public_key.public_key,
        sizeof(value.public_key.public_key)
116
    );
117
    pos = olm::pickle_bytes(
118
119
        pos, value.private_key.private_key,
        sizeof(value.private_key.private_key)
120
121
122
123
124
    );
    return pos;
}


125
std::uint8_t const * olm::unpickle(
126
    std::uint8_t const * pos, std::uint8_t const * end,
127
    _olm_curve25519_key_pair & value
128
) {
129
    pos = olm::unpickle_bytes(
130
131
        pos, end, value.public_key.public_key,
        sizeof(value.public_key.public_key)
132
    );
Denis Kasak's avatar
Denis Kasak committed
133
134
    if (!pos) return nullptr;

135
    pos = olm::unpickle_bytes(
136
137
        pos, end, value.private_key.private_key,
        sizeof(value.private_key.private_key)
138
    );
Denis Kasak's avatar
Denis Kasak committed
139
140
    if (!pos) return nullptr;

141
142
    return pos;
}
143

144
145
146
147
////// pickle.h implementations

std::size_t _olm_pickle_ed25519_public_key_length(
    const _olm_ed25519_public_key * value
148
) {
149
    return sizeof(value->public_key);
150
151
152
}


153
std::uint8_t * _olm_pickle_ed25519_public_key(
154
    std::uint8_t * pos,
155
    const _olm_ed25519_public_key *value
156
) {
Denis Kasak's avatar
Denis Kasak committed
157
    return olm::pickle_bytes(
158
        pos, value->public_key, sizeof(value->public_key)
159
160
161
162
    );
}


163
std::uint8_t const * _olm_unpickle_ed25519_public_key(
164
    std::uint8_t const * pos, std::uint8_t const * end,
165
    _olm_ed25519_public_key * value
166
) {
Denis Kasak's avatar
Denis Kasak committed
167
    return olm::unpickle_bytes(
168
        pos, end, value->public_key, sizeof(value->public_key)
169
170
171
172
    );
}


173
174
std::size_t _olm_pickle_ed25519_key_pair_length(
    const _olm_ed25519_key_pair *value
175
) {
176
177
    return sizeof(value->public_key.public_key)
        + sizeof(value->private_key.private_key);
178
179
180
}


181
std::uint8_t * _olm_pickle_ed25519_key_pair(
182
    std::uint8_t * pos,
183
    const _olm_ed25519_key_pair *value
184
185
) {
    pos = olm::pickle_bytes(
186
187
        pos, value->public_key.public_key,
        sizeof(value->public_key.public_key)
188
189
    );
    pos = olm::pickle_bytes(
190
191
        pos, value->private_key.private_key,
        sizeof(value->private_key.private_key)
192
193
194
195
196
    );
    return pos;
}


197
std::uint8_t const * _olm_unpickle_ed25519_key_pair(
198
    std::uint8_t const * pos, std::uint8_t const * end,
199
    _olm_ed25519_key_pair *value
200
201
) {
    pos = olm::unpickle_bytes(
202
203
        pos, end, value->public_key.public_key,
        sizeof(value->public_key.public_key)
204
    );
Denis Kasak's avatar
Denis Kasak committed
205
206
    if (!pos) return nullptr;

207
    pos = olm::unpickle_bytes(
208
209
        pos, end, value->private_key.private_key,
        sizeof(value->private_key.private_key)
210
    );
Denis Kasak's avatar
Denis Kasak committed
211
212
    if (!pos) return nullptr;

213
214
    return pos;
}
215

216
uint8_t * _olm_pickle_uint32(uint8_t * pos, uint32_t value) {
217
218
219
    return olm::pickle(pos, value);
}

220
uint8_t const * _olm_unpickle_uint32(
221
222
223
224
225
226
    uint8_t const * pos, uint8_t const * end,
    uint32_t *value
) {
    return olm::unpickle(pos, end, *value);
}

227
uint8_t * _olm_pickle_bool(uint8_t * pos, int value) {
228
229
230
    return olm::pickle(pos, (bool)value);
}

231
uint8_t const * _olm_unpickle_bool(
232
233
234
235
236
237
    uint8_t const * pos, uint8_t const * end,
    int *value
) {
    return olm::unpickle(pos, end, *reinterpret_cast<bool *>(value));
}

238
uint8_t * _olm_pickle_bytes(uint8_t * pos, uint8_t const * bytes,
239
240
241
242
                           size_t bytes_length) {
    return olm::pickle_bytes(pos, bytes, bytes_length);
}

243
uint8_t const * _olm_unpickle_bytes(uint8_t const * pos, uint8_t const * end,
244
245
246
                                   uint8_t * bytes, size_t bytes_length) {
    return olm::unpickle_bytes(pos, end, bytes, bytes_length);
}