Home | History | Annotate | Download | only in gatekeeper
      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 using namespace std;
     23 
     24 namespace gatekeeper {
     25 
     26 /**
     27  * Methods for serializing/deserializing SizedBuffers
     28  */
     29 
     30 struct __attribute__((__packed__)) serial_header_t {
     31     uint32_t error;
     32     uint32_t user_id;
     33 };
     34 
     35 static inline uint32_t serialized_buffer_size(const SizedBuffer &buf) {
     36     return sizeof(buf.length) + buf.length;
     37 }
     38 
     39 static inline void append_to_buffer(uint8_t **buffer, const SizedBuffer *to_append) {
     40     memcpy(*buffer, &to_append->length, sizeof(to_append->length));
     41     *buffer += sizeof(to_append->length);
     42     if (to_append->length != 0) {
     43         memcpy(*buffer, to_append->buffer.get(), to_append->length);
     44         *buffer += to_append->length;
     45     }
     46 }
     47 
     48 static inline gatekeeper_error_t read_from_buffer(const uint8_t **buffer, const uint8_t *end,
     49         SizedBuffer *target) {
     50     if (*buffer + sizeof(target->length) > end) return ERROR_INVALID;
     51 
     52     memcpy(&target->length, *buffer, sizeof(target->length));
     53     *buffer += sizeof(target->length);
     54     if (target->length != 0) {
     55         const uint8_t *buffer_end = *buffer + target->length;
     56         if (buffer_end > end || buffer_end <= *buffer) return ERROR_INVALID;
     57 
     58         target->buffer.reset(new uint8_t[target->length]);
     59         memcpy(target->buffer.get(), *buffer, target->length);
     60         *buffer += target->length;
     61     }
     62     return ERROR_NONE;
     63 }
     64 
     65 
     66 uint32_t GateKeeperMessage::GetSerializedSize() const {
     67     if (error == ERROR_NONE) {
     68         uint32_t size = sizeof(serial_header_t) + nonErrorSerializedSize();
     69         return size;
     70     } else {
     71         uint32_t size = sizeof(serial_header_t);
     72         if (error == ERROR_RETRY) {
     73             size += sizeof(retry_timeout);
     74         }
     75         return size;
     76     }
     77 }
     78 
     79 uint32_t GateKeeperMessage::Serialize(uint8_t *buffer, const uint8_t *end) const {
     80     uint32_t bytes_written = 0;
     81     if (buffer + GetSerializedSize() > end) {
     82         return 0;
     83     }
     84 
     85     serial_header_t *header = reinterpret_cast<serial_header_t *>(buffer);
     86     if (error != ERROR_NONE) {
     87         if (buffer + sizeof(serial_header_t) > end) return 0;
     88         header->error = error;
     89         header->user_id = user_id;
     90         bytes_written += sizeof(*header);
     91         if (error == ERROR_RETRY) {
     92             memcpy(buffer + sizeof(serial_header_t), &retry_timeout, sizeof(retry_timeout));
     93             bytes_written  += sizeof(retry_timeout);
     94         }
     95     } else {
     96         if (buffer + sizeof(serial_header_t) + nonErrorSerializedSize() > end)
     97             return 0;
     98         header->error = error;
     99         header->user_id = user_id;
    100         nonErrorSerialize(buffer + sizeof(*header));
    101         bytes_written += sizeof(*header) + nonErrorSerializedSize();
    102     }
    103 
    104     return bytes_written;
    105 }
    106 
    107 gatekeeper_error_t GateKeeperMessage::Deserialize(const uint8_t *payload, const uint8_t *end) {
    108     if (payload + sizeof(uint32_t) > end) return ERROR_INVALID;
    109     const serial_header_t *header = reinterpret_cast<const serial_header_t *>(payload);
    110     if (header->error == ERROR_NONE) {
    111         if (payload == end) return ERROR_INVALID;
    112         user_id = header->user_id;
    113         error = nonErrorDeserialize(payload + sizeof(*header), end);
    114     } else {
    115         error = static_cast<gatekeeper_error_t>(header->error);
    116         user_id = header->user_id;
    117         if (error == ERROR_RETRY) {
    118             if (payload + sizeof(serial_header_t) < end) {
    119                 memcpy(&retry_timeout, payload + sizeof(serial_header_t), sizeof(retry_timeout));
    120             } else {
    121                 retry_timeout = 0;
    122             }
    123         }
    124     }
    125 
    126     return error;
    127 }
    128 
    129 void GateKeeperMessage::SetRetryTimeout(uint32_t retry_timeout) {
    130     this->retry_timeout = retry_timeout;
    131     this->error = ERROR_RETRY;
    132 }
    133 
    134 VerifyRequest::VerifyRequest(uint32_t user_id, uint64_t challenge,
    135         SizedBuffer *enrolled_password_handle, SizedBuffer *provided_password_payload) {
    136     this->user_id = user_id;
    137     this->challenge = challenge;
    138     this->password_handle.buffer.reset(enrolled_password_handle->buffer.release());
    139     this->password_handle.length = enrolled_password_handle->length;
    140     this->provided_password.buffer.reset(provided_password_payload->buffer.release());
    141     this->provided_password.length = provided_password_payload->length;
    142 }
    143 
    144 VerifyRequest::VerifyRequest() {
    145     memset_s(&password_handle, 0, sizeof(password_handle));
    146     memset_s(&provided_password, 0, sizeof(provided_password));
    147 }
    148 
    149 VerifyRequest::~VerifyRequest() {
    150     if (password_handle.buffer.get()) {
    151         password_handle.buffer.reset();
    152     }
    153 
    154     if (provided_password.buffer.get()) {
    155         memset_s(provided_password.buffer.get(), 0, provided_password.length);
    156         provided_password.buffer.reset();
    157     }
    158 }
    159 
    160 uint32_t VerifyRequest::nonErrorSerializedSize() const {
    161     return sizeof(challenge) + serialized_buffer_size(password_handle)
    162             + serialized_buffer_size(provided_password);
    163 }
    164 
    165 void VerifyRequest::nonErrorSerialize(uint8_t *buffer) const {
    166     memcpy(buffer, &challenge, sizeof(challenge));
    167     buffer += sizeof(challenge);
    168     append_to_buffer(&buffer, &password_handle);
    169     append_to_buffer(&buffer, &provided_password);
    170 }
    171 
    172 gatekeeper_error_t VerifyRequest::nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) {
    173     gatekeeper_error_t error = ERROR_NONE;
    174 
    175     if (password_handle.buffer.get()) {
    176         password_handle.buffer.reset();
    177     }
    178 
    179     if (provided_password.buffer.get()) {
    180         memset_s(provided_password.buffer.get(), 0, provided_password.length);
    181         provided_password.buffer.reset();
    182     }
    183 
    184     memcpy(&challenge, payload, sizeof(challenge));
    185     payload += sizeof(challenge);
    186 
    187     error = read_from_buffer(&payload, end, &password_handle);
    188     if (error != ERROR_NONE) return error;
    189 
    190     return read_from_buffer(&payload, end, &provided_password);
    191 
    192 }
    193 
    194 VerifyResponse::VerifyResponse(uint32_t user_id, SizedBuffer *auth_token) {
    195     this->user_id = user_id;
    196     this->auth_token.buffer.reset(auth_token->buffer.release());
    197     this->auth_token.length = auth_token->length;
    198     this->request_reenroll = false;
    199 }
    200 
    201 VerifyResponse::VerifyResponse() {
    202     request_reenroll = false;
    203     memset_s(&auth_token, 0, sizeof(auth_token));
    204 };
    205 
    206 VerifyResponse::~VerifyResponse() {
    207     if (auth_token.length > 0) {
    208         auth_token.buffer.reset();
    209     }
    210 }
    211 
    212 void VerifyResponse::SetVerificationToken(SizedBuffer *auth_token) {
    213     this->auth_token.buffer.reset(auth_token->buffer.release());
    214     this->auth_token.length = auth_token->length;
    215 }
    216 
    217 uint32_t VerifyResponse::nonErrorSerializedSize() const {
    218     return serialized_buffer_size(auth_token) + sizeof(request_reenroll);
    219 }
    220 
    221 void VerifyResponse::nonErrorSerialize(uint8_t *buffer) const {
    222     append_to_buffer(&buffer, &auth_token);
    223     memcpy(buffer, &request_reenroll, sizeof(request_reenroll));
    224 }
    225 
    226 gatekeeper_error_t VerifyResponse::nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) {
    227     if (auth_token.buffer.get()) {
    228         auth_token.buffer.reset();
    229     }
    230 
    231     gatekeeper_error_t err = read_from_buffer(&payload, end, &auth_token);
    232     if (err != ERROR_NONE) {
    233         return err;
    234     }
    235 
    236     memcpy(&request_reenroll, payload, sizeof(request_reenroll));
    237     return ERROR_NONE;
    238 }
    239 
    240 EnrollRequest::EnrollRequest(uint32_t user_id, SizedBuffer *password_handle,
    241         SizedBuffer *provided_password,  SizedBuffer *enrolled_password) {
    242     this->user_id = user_id;
    243     this->provided_password.buffer.reset(provided_password->buffer.release());
    244     this->provided_password.length = provided_password->length;
    245 
    246     if (enrolled_password == NULL) {
    247         this->enrolled_password.buffer.reset();
    248         this->enrolled_password.length = 0;
    249     } else {
    250         this->enrolled_password.buffer.reset(enrolled_password->buffer.release());
    251         this->enrolled_password.length = enrolled_password->length;
    252     }
    253 
    254     if (password_handle == NULL) {
    255         this->password_handle.buffer.reset();
    256         this->password_handle.length = 0;
    257     } else {
    258         this->password_handle.buffer.reset(password_handle->buffer.release());
    259         this->password_handle.length = password_handle->length;
    260     }
    261 }
    262 
    263 EnrollRequest::EnrollRequest() {
    264     memset_s(&provided_password, 0, sizeof(provided_password));
    265     memset_s(&enrolled_password, 0, sizeof(enrolled_password));
    266     memset_s(&password_handle, 0, sizeof(password_handle));
    267 }
    268 
    269 EnrollRequest::~EnrollRequest() {
    270     if (provided_password.buffer.get()) {
    271         memset_s(provided_password.buffer.get(), 0, provided_password.length);
    272         provided_password.buffer.reset();
    273     }
    274 
    275     if (enrolled_password.buffer.get()) {
    276         memset_s(enrolled_password.buffer.get(), 0, enrolled_password.length);
    277         enrolled_password.buffer.reset();
    278     }
    279 
    280     if (password_handle.buffer.get()) {
    281         memset_s(password_handle.buffer.get(), 0, password_handle.length);
    282         password_handle.buffer.reset();
    283     }
    284 }
    285 
    286 uint32_t EnrollRequest::nonErrorSerializedSize() const {
    287    return serialized_buffer_size(provided_password) + serialized_buffer_size(enrolled_password)
    288        + serialized_buffer_size(password_handle);
    289 }
    290 
    291 void EnrollRequest::nonErrorSerialize(uint8_t *buffer) const {
    292     append_to_buffer(&buffer, &provided_password);
    293     append_to_buffer(&buffer, &enrolled_password);
    294     append_to_buffer(&buffer, &password_handle);
    295 }
    296 
    297 gatekeeper_error_t EnrollRequest::nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) {
    298     gatekeeper_error_t ret;
    299     if (provided_password.buffer.get()) {
    300         memset_s(provided_password.buffer.get(), 0, provided_password.length);
    301         provided_password.buffer.reset();
    302     }
    303 
    304     if (enrolled_password.buffer.get()) {
    305         memset_s(enrolled_password.buffer.get(), 0, enrolled_password.length);
    306         enrolled_password.buffer.reset();
    307     }
    308 
    309     if (password_handle.buffer.get()) {
    310         memset_s(password_handle.buffer.get(), 0, password_handle.length);
    311         password_handle.buffer.reset();
    312     }
    313 
    314      ret = read_from_buffer(&payload, end, &provided_password);
    315      if (ret != ERROR_NONE) {
    316          return ret;
    317      }
    318 
    319      ret = read_from_buffer(&payload, end, &enrolled_password);
    320      if (ret != ERROR_NONE) {
    321          return ret;
    322      }
    323 
    324      return read_from_buffer(&payload, end, &password_handle);
    325 }
    326 
    327 EnrollResponse::EnrollResponse(uint32_t user_id, SizedBuffer *enrolled_password_handle) {
    328     this->user_id = user_id;
    329     this->enrolled_password_handle.buffer.reset(enrolled_password_handle->buffer.release());
    330     this->enrolled_password_handle.length = enrolled_password_handle->length;
    331 }
    332 
    333 EnrollResponse::EnrollResponse() {
    334     memset_s(&enrolled_password_handle, 0, sizeof(enrolled_password_handle));
    335 }
    336 
    337 EnrollResponse::~EnrollResponse() {
    338     if (enrolled_password_handle.buffer.get()) {
    339         enrolled_password_handle.buffer.reset();
    340     }
    341 }
    342 
    343 void EnrollResponse::SetEnrolledPasswordHandle(SizedBuffer *enrolled_password_handle) {
    344     this->enrolled_password_handle.buffer.reset(enrolled_password_handle->buffer.release());
    345     this->enrolled_password_handle.length = enrolled_password_handle->length;
    346 }
    347 
    348 uint32_t EnrollResponse::nonErrorSerializedSize() const {
    349     return serialized_buffer_size(enrolled_password_handle);
    350 }
    351 
    352 void EnrollResponse::nonErrorSerialize(uint8_t *buffer) const {
    353     append_to_buffer(&buffer, &enrolled_password_handle);
    354 }
    355 
    356 gatekeeper_error_t EnrollResponse::nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) {
    357     if (enrolled_password_handle.buffer.get()) {
    358         enrolled_password_handle.buffer.reset();
    359     }
    360 
    361     return read_from_buffer(&payload, end, &enrolled_password_handle);
    362 }
    363 
    364 };
    365 
    366