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 33 static inline uint32_t serialized_buffer_size(const SizedBuffer &buf) { 34 return sizeof(buf.length) + buf.length; 35 } 36 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 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 64 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 77 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 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 127 void GateKeeperMessage::SetRetryTimeout(uint32_t retry_timeout) { 128 this->retry_timeout = retry_timeout; 129 this->error = ERROR_RETRY; 130 } 131 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 142 VerifyRequest::VerifyRequest() { 143 memset_s(&password_handle, 0, sizeof(password_handle)); 144 memset_s(&provided_password, 0, sizeof(provided_password)); 145 } 146 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 158 uint32_t VerifyRequest::nonErrorSerializedSize() const { 159 return sizeof(challenge) + serialized_buffer_size(password_handle) 160 + serialized_buffer_size(provided_password); 161 } 162 163 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 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 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 199 VerifyResponse::VerifyResponse() { 200 request_reenroll = false; 201 memset_s(&auth_token, 0, sizeof(auth_token)); 202 }; 203 204 VerifyResponse::~VerifyResponse() { 205 if (auth_token.length > 0) { 206 auth_token.buffer.reset(); 207 } 208 } 209 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 215 uint32_t VerifyResponse::nonErrorSerializedSize() const { 216 return serialized_buffer_size(auth_token) + sizeof(request_reenroll); 217 } 218 219 void VerifyResponse::nonErrorSerialize(uint8_t *buffer) const { 220 append_to_buffer(&buffer, &auth_token); 221 memcpy(buffer, &request_reenroll, sizeof(request_reenroll)); 222 } 223 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 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 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 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 284 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 289 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 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 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 331 EnrollResponse::EnrollResponse() { 332 memset_s(&enrolled_password_handle, 0, sizeof(enrolled_password_handle)); 333 } 334 335 EnrollResponse::~EnrollResponse() { 336 if (enrolled_password_handle.buffer.get()) { 337 enrolled_password_handle.buffer.reset(); 338 } 339 } 340 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 346 uint32_t EnrollResponse::nonErrorSerializedSize() const { 347 return serialized_buffer_size(enrolled_password_handle); 348 } 349 350 void EnrollResponse::nonErrorSerialize(uint8_t *buffer) const { 351 append_to_buffer(&buffer, &enrolled_password_handle); 352 } 353 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