1 /*
2 * Copyright 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #include <gatekeeper/gatekeeper_messages.h>
19
20 #include <string.h>
21
22 namespace gatekeeper {
23
24 /**
25 * Methods for serializing/deserializing SizedBuffers
26 */
27
28 struct __attribute__((__packed__)) serial_header_t {
29 uint32_t error;
30 uint32_t user_id;
31 };
32
serialized_buffer_size(const SizedBuffer & buf)33 static inline uint32_t serialized_buffer_size(const SizedBuffer &buf) {
34 return sizeof(buf.length) + buf.length;
35 }
36
append_to_buffer(uint8_t ** buffer,const SizedBuffer * to_append)37 static inline void append_to_buffer(uint8_t **buffer, const SizedBuffer *to_append) {
38 memcpy(*buffer, &to_append->length, sizeof(to_append->length));
39 *buffer += sizeof(to_append->length);
40 if (to_append->length != 0) {
41 memcpy(*buffer, to_append->buffer.get(), to_append->length);
42 *buffer += to_append->length;
43 }
44 }
45
read_from_buffer(const uint8_t ** buffer,const uint8_t * end,SizedBuffer * target)46 static inline gatekeeper_error_t read_from_buffer(const uint8_t **buffer, const uint8_t *end,
47 SizedBuffer *target) {
48 if (*buffer + sizeof(target->length) > end) return ERROR_INVALID;
49
50 memcpy(&target->length, *buffer, sizeof(target->length));
51 *buffer += sizeof(target->length);
52 if (target->length != 0) {
53 const size_t buffer_size = end - *buffer;
54 if (buffer_size < target->length) return ERROR_INVALID;
55
56 target->buffer.reset(new uint8_t[target->length]);
57 memcpy(target->buffer.get(), *buffer, target->length);
58 *buffer += target->length;
59 }
60 return ERROR_NONE;
61 }
62
63
GetSerializedSize() const64 uint32_t GateKeeperMessage::GetSerializedSize() const {
65 if (error == ERROR_NONE) {
66 uint32_t size = sizeof(serial_header_t) + nonErrorSerializedSize();
67 return size;
68 } else {
69 uint32_t size = sizeof(serial_header_t);
70 if (error == ERROR_RETRY) {
71 size += sizeof(retry_timeout);
72 }
73 return size;
74 }
75 }
76
Serialize(uint8_t * buffer,const uint8_t * end) const77 uint32_t GateKeeperMessage::Serialize(uint8_t *buffer, const uint8_t *end) const {
78 uint32_t bytes_written = 0;
79 if (buffer + GetSerializedSize() > end) {
80 return 0;
81 }
82
83 serial_header_t *header = reinterpret_cast<serial_header_t *>(buffer);
84 if (error != ERROR_NONE) {
85 if (buffer + sizeof(serial_header_t) > end) return 0;
86 header->error = error;
87 header->user_id = user_id;
88 bytes_written += sizeof(*header);
89 if (error == ERROR_RETRY) {
90 memcpy(buffer + sizeof(serial_header_t), &retry_timeout, sizeof(retry_timeout));
91 bytes_written += sizeof(retry_timeout);
92 }
93 } else {
94 if (buffer + sizeof(serial_header_t) + nonErrorSerializedSize() > end)
95 return 0;
96 header->error = error;
97 header->user_id = user_id;
98 nonErrorSerialize(buffer + sizeof(*header));
99 bytes_written += sizeof(*header) + nonErrorSerializedSize();
100 }
101
102 return bytes_written;
103 }
104
Deserialize(const uint8_t * payload,const uint8_t * end)105 gatekeeper_error_t GateKeeperMessage::Deserialize(const uint8_t *payload, const uint8_t *end) {
106 if (payload + sizeof(uint32_t) > end) return ERROR_INVALID;
107 const serial_header_t *header = reinterpret_cast<const serial_header_t *>(payload);
108 if (header->error == ERROR_NONE) {
109 if (payload == end) return ERROR_INVALID;
110 user_id = header->user_id;
111 error = nonErrorDeserialize(payload + sizeof(*header), end);
112 } else {
113 error = static_cast<gatekeeper_error_t>(header->error);
114 user_id = header->user_id;
115 if (error == ERROR_RETRY) {
116 if (payload + sizeof(serial_header_t) < end) {
117 memcpy(&retry_timeout, payload + sizeof(serial_header_t), sizeof(retry_timeout));
118 } else {
119 retry_timeout = 0;
120 }
121 }
122 }
123
124 return error;
125 }
126
SetRetryTimeout(uint32_t retry_timeout)127 void GateKeeperMessage::SetRetryTimeout(uint32_t retry_timeout) {
128 this->retry_timeout = retry_timeout;
129 this->error = ERROR_RETRY;
130 }
131
VerifyRequest(uint32_t user_id,uint64_t challenge,SizedBuffer * enrolled_password_handle,SizedBuffer * provided_password_payload)132 VerifyRequest::VerifyRequest(uint32_t user_id, uint64_t challenge,
133 SizedBuffer *enrolled_password_handle, SizedBuffer *provided_password_payload) {
134 this->user_id = user_id;
135 this->challenge = challenge;
136 this->password_handle.buffer.reset(enrolled_password_handle->buffer.release());
137 this->password_handle.length = enrolled_password_handle->length;
138 this->provided_password.buffer.reset(provided_password_payload->buffer.release());
139 this->provided_password.length = provided_password_payload->length;
140 }
141
VerifyRequest()142 VerifyRequest::VerifyRequest() {
143 memset_s(&password_handle, 0, sizeof(password_handle));
144 memset_s(&provided_password, 0, sizeof(provided_password));
145 }
146
~VerifyRequest()147 VerifyRequest::~VerifyRequest() {
148 if (password_handle.buffer.get()) {
149 password_handle.buffer.reset();
150 }
151
152 if (provided_password.buffer.get()) {
153 memset_s(provided_password.buffer.get(), 0, provided_password.length);
154 provided_password.buffer.reset();
155 }
156 }
157
nonErrorSerializedSize() const158 uint32_t VerifyRequest::nonErrorSerializedSize() const {
159 return sizeof(challenge) + serialized_buffer_size(password_handle)
160 + serialized_buffer_size(provided_password);
161 }
162
nonErrorSerialize(uint8_t * buffer) const163 void VerifyRequest::nonErrorSerialize(uint8_t *buffer) const {
164 memcpy(buffer, &challenge, sizeof(challenge));
165 buffer += sizeof(challenge);
166 append_to_buffer(&buffer, &password_handle);
167 append_to_buffer(&buffer, &provided_password);
168 }
169
nonErrorDeserialize(const uint8_t * payload,const uint8_t * end)170 gatekeeper_error_t VerifyRequest::nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) {
171 gatekeeper_error_t error = ERROR_NONE;
172
173 if (password_handle.buffer.get()) {
174 password_handle.buffer.reset();
175 }
176
177 if (provided_password.buffer.get()) {
178 memset_s(provided_password.buffer.get(), 0, provided_password.length);
179 provided_password.buffer.reset();
180 }
181
182 memcpy(&challenge, payload, sizeof(challenge));
183 payload += sizeof(challenge);
184
185 error = read_from_buffer(&payload, end, &password_handle);
186 if (error != ERROR_NONE) return error;
187
188 return read_from_buffer(&payload, end, &provided_password);
189
190 }
191
VerifyResponse(uint32_t user_id,SizedBuffer * auth_token)192 VerifyResponse::VerifyResponse(uint32_t user_id, SizedBuffer *auth_token) {
193 this->user_id = user_id;
194 this->auth_token.buffer.reset(auth_token->buffer.release());
195 this->auth_token.length = auth_token->length;
196 this->request_reenroll = false;
197 }
198
VerifyResponse()199 VerifyResponse::VerifyResponse() {
200 request_reenroll = false;
201 memset_s(&auth_token, 0, sizeof(auth_token));
202 };
203
~VerifyResponse()204 VerifyResponse::~VerifyResponse() {
205 if (auth_token.length > 0) {
206 auth_token.buffer.reset();
207 }
208 }
209
SetVerificationToken(SizedBuffer * auth_token)210 void VerifyResponse::SetVerificationToken(SizedBuffer *auth_token) {
211 this->auth_token.buffer.reset(auth_token->buffer.release());
212 this->auth_token.length = auth_token->length;
213 }
214
nonErrorSerializedSize() const215 uint32_t VerifyResponse::nonErrorSerializedSize() const {
216 return serialized_buffer_size(auth_token) + sizeof(request_reenroll);
217 }
218
nonErrorSerialize(uint8_t * buffer) const219 void VerifyResponse::nonErrorSerialize(uint8_t *buffer) const {
220 append_to_buffer(&buffer, &auth_token);
221 memcpy(buffer, &request_reenroll, sizeof(request_reenroll));
222 }
223
nonErrorDeserialize(const uint8_t * payload,const uint8_t * end)224 gatekeeper_error_t VerifyResponse::nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) {
225 if (auth_token.buffer.get()) {
226 auth_token.buffer.reset();
227 }
228
229 gatekeeper_error_t err = read_from_buffer(&payload, end, &auth_token);
230 if (err != ERROR_NONE) {
231 return err;
232 }
233
234 memcpy(&request_reenroll, payload, sizeof(request_reenroll));
235 return ERROR_NONE;
236 }
237
EnrollRequest(uint32_t user_id,SizedBuffer * password_handle,SizedBuffer * provided_password,SizedBuffer * enrolled_password)238 EnrollRequest::EnrollRequest(uint32_t user_id, SizedBuffer *password_handle,
239 SizedBuffer *provided_password, SizedBuffer *enrolled_password) {
240 this->user_id = user_id;
241 this->provided_password.buffer.reset(provided_password->buffer.release());
242 this->provided_password.length = provided_password->length;
243
244 if (enrolled_password == NULL) {
245 this->enrolled_password.buffer.reset();
246 this->enrolled_password.length = 0;
247 } else {
248 this->enrolled_password.buffer.reset(enrolled_password->buffer.release());
249 this->enrolled_password.length = enrolled_password->length;
250 }
251
252 if (password_handle == NULL) {
253 this->password_handle.buffer.reset();
254 this->password_handle.length = 0;
255 } else {
256 this->password_handle.buffer.reset(password_handle->buffer.release());
257 this->password_handle.length = password_handle->length;
258 }
259 }
260
EnrollRequest()261 EnrollRequest::EnrollRequest() {
262 memset_s(&provided_password, 0, sizeof(provided_password));
263 memset_s(&enrolled_password, 0, sizeof(enrolled_password));
264 memset_s(&password_handle, 0, sizeof(password_handle));
265 }
266
~EnrollRequest()267 EnrollRequest::~EnrollRequest() {
268 if (provided_password.buffer.get()) {
269 memset_s(provided_password.buffer.get(), 0, provided_password.length);
270 provided_password.buffer.reset();
271 }
272
273 if (enrolled_password.buffer.get()) {
274 memset_s(enrolled_password.buffer.get(), 0, enrolled_password.length);
275 enrolled_password.buffer.reset();
276 }
277
278 if (password_handle.buffer.get()) {
279 memset_s(password_handle.buffer.get(), 0, password_handle.length);
280 password_handle.buffer.reset();
281 }
282 }
283
nonErrorSerializedSize() const284 uint32_t EnrollRequest::nonErrorSerializedSize() const {
285 return serialized_buffer_size(provided_password) + serialized_buffer_size(enrolled_password)
286 + serialized_buffer_size(password_handle);
287 }
288
nonErrorSerialize(uint8_t * buffer) const289 void EnrollRequest::nonErrorSerialize(uint8_t *buffer) const {
290 append_to_buffer(&buffer, &provided_password);
291 append_to_buffer(&buffer, &enrolled_password);
292 append_to_buffer(&buffer, &password_handle);
293 }
294
nonErrorDeserialize(const uint8_t * payload,const uint8_t * end)295 gatekeeper_error_t EnrollRequest::nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) {
296 gatekeeper_error_t ret;
297 if (provided_password.buffer.get()) {
298 memset_s(provided_password.buffer.get(), 0, provided_password.length);
299 provided_password.buffer.reset();
300 }
301
302 if (enrolled_password.buffer.get()) {
303 memset_s(enrolled_password.buffer.get(), 0, enrolled_password.length);
304 enrolled_password.buffer.reset();
305 }
306
307 if (password_handle.buffer.get()) {
308 memset_s(password_handle.buffer.get(), 0, password_handle.length);
309 password_handle.buffer.reset();
310 }
311
312 ret = read_from_buffer(&payload, end, &provided_password);
313 if (ret != ERROR_NONE) {
314 return ret;
315 }
316
317 ret = read_from_buffer(&payload, end, &enrolled_password);
318 if (ret != ERROR_NONE) {
319 return ret;
320 }
321
322 return read_from_buffer(&payload, end, &password_handle);
323 }
324
EnrollResponse(uint32_t user_id,SizedBuffer * enrolled_password_handle)325 EnrollResponse::EnrollResponse(uint32_t user_id, SizedBuffer *enrolled_password_handle) {
326 this->user_id = user_id;
327 this->enrolled_password_handle.buffer.reset(enrolled_password_handle->buffer.release());
328 this->enrolled_password_handle.length = enrolled_password_handle->length;
329 }
330
EnrollResponse()331 EnrollResponse::EnrollResponse() {
332 memset_s(&enrolled_password_handle, 0, sizeof(enrolled_password_handle));
333 }
334
~EnrollResponse()335 EnrollResponse::~EnrollResponse() {
336 if (enrolled_password_handle.buffer.get()) {
337 enrolled_password_handle.buffer.reset();
338 }
339 }
340
SetEnrolledPasswordHandle(SizedBuffer * enrolled_password_handle)341 void EnrollResponse::SetEnrolledPasswordHandle(SizedBuffer *enrolled_password_handle) {
342 this->enrolled_password_handle.buffer.reset(enrolled_password_handle->buffer.release());
343 this->enrolled_password_handle.length = enrolled_password_handle->length;
344 }
345
nonErrorSerializedSize() const346 uint32_t EnrollResponse::nonErrorSerializedSize() const {
347 return serialized_buffer_size(enrolled_password_handle);
348 }
349
nonErrorSerialize(uint8_t * buffer) const350 void EnrollResponse::nonErrorSerialize(uint8_t *buffer) const {
351 append_to_buffer(&buffer, &enrolled_password_handle);
352 }
353
nonErrorDeserialize(const uint8_t * payload,const uint8_t * end)354 gatekeeper_error_t EnrollResponse::nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) {
355 if (enrolled_password_handle.buffer.get()) {
356 enrolled_password_handle.buffer.reset();
357 }
358
359 return read_from_buffer(&payload, end, &enrolled_password_handle);
360 }
361
362 };
363
364