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     memset_s(&auth_token, 0, sizeof(auth_token));
    203 };
    204 
    205 VerifyResponse::~VerifyResponse() {
    206     if (auth_token.length > 0) {
    207         auth_token.buffer.reset();
    208     }
    209 }
    210 
    211 void VerifyResponse::SetVerificationToken(SizedBuffer *auth_token) {
    212     this->auth_token.buffer.reset(auth_token->buffer.release());
    213     this->auth_token.length = auth_token->length;
    214 }
    215 
    216 uint32_t VerifyResponse::nonErrorSerializedSize() const {
    217     return serialized_buffer_size(auth_token) + sizeof(request_reenroll);
    218 }
    219 
    220 void VerifyResponse::nonErrorSerialize(uint8_t *buffer) const {
    221     append_to_buffer(&buffer, &auth_token);
    222     memcpy(buffer, &request_reenroll, sizeof(request_reenroll));
    223 }
    224 
    225 gatekeeper_error_t VerifyResponse::nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) {
    226     if (auth_token.buffer.get()) {
    227         auth_token.buffer.reset();
    228     }
    229 
    230     gatekeeper_error_t err = read_from_buffer(&payload, end, &auth_token);
    231     if (err != ERROR_NONE) {
    232         return err;
    233     }
    234 
    235     memcpy(&request_reenroll, payload, sizeof(request_reenroll));
    236     return ERROR_NONE;
    237 }
    238 
    239 EnrollRequest::EnrollRequest(uint32_t user_id, SizedBuffer *password_handle,
    240         SizedBuffer *provided_password,  SizedBuffer *enrolled_password) {
    241     this->user_id = user_id;
    242     this->provided_password.buffer.reset(provided_password->buffer.release());
    243     this->provided_password.length = provided_password->length;
    244 
    245     if (enrolled_password == NULL) {
    246         this->enrolled_password.buffer.reset();
    247         this->enrolled_password.length = 0;
    248     } else {
    249         this->enrolled_password.buffer.reset(enrolled_password->buffer.release());
    250         this->enrolled_password.length = enrolled_password->length;
    251     }
    252 
    253     if (password_handle == NULL) {
    254         this->password_handle.buffer.reset();
    255         this->password_handle.length = 0;
    256     } else {
    257         this->password_handle.buffer.reset(password_handle->buffer.release());
    258         this->password_handle.length = password_handle->length;
    259     }
    260 }
    261 
    262 EnrollRequest::EnrollRequest() {
    263     memset_s(&provided_password, 0, sizeof(provided_password));
    264     memset_s(&enrolled_password, 0, sizeof(enrolled_password));
    265     memset_s(&password_handle, 0, sizeof(password_handle));
    266 }
    267 
    268 EnrollRequest::~EnrollRequest() {
    269     if (provided_password.buffer.get()) {
    270         memset_s(provided_password.buffer.get(), 0, provided_password.length);
    271         provided_password.buffer.reset();
    272     }
    273 
    274     if (enrolled_password.buffer.get()) {
    275         memset_s(enrolled_password.buffer.get(), 0, enrolled_password.length);
    276         enrolled_password.buffer.reset();
    277     }
    278 
    279     if (password_handle.buffer.get()) {
    280         memset_s(password_handle.buffer.get(), 0, password_handle.length);
    281         password_handle.buffer.reset();
    282     }
    283 }
    284 
    285 uint32_t EnrollRequest::nonErrorSerializedSize() const {
    286    return serialized_buffer_size(provided_password) + serialized_buffer_size(enrolled_password)
    287        + serialized_buffer_size(password_handle);
    288 }
    289 
    290 void EnrollRequest::nonErrorSerialize(uint8_t *buffer) const {
    291     append_to_buffer(&buffer, &provided_password);
    292     append_to_buffer(&buffer, &enrolled_password);
    293     append_to_buffer(&buffer, &password_handle);
    294 }
    295 
    296 gatekeeper_error_t EnrollRequest::nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) {
    297     gatekeeper_error_t ret;
    298     if (provided_password.buffer.get()) {
    299         memset_s(provided_password.buffer.get(), 0, provided_password.length);
    300         provided_password.buffer.reset();
    301     }
    302 
    303     if (enrolled_password.buffer.get()) {
    304         memset_s(enrolled_password.buffer.get(), 0, enrolled_password.length);
    305         enrolled_password.buffer.reset();
    306     }
    307 
    308     if (password_handle.buffer.get()) {
    309         memset_s(password_handle.buffer.get(), 0, password_handle.length);
    310         password_handle.buffer.reset();
    311     }
    312 
    313      ret = read_from_buffer(&payload, end, &provided_password);
    314      if (ret != ERROR_NONE) {
    315          return ret;
    316      }
    317 
    318      ret = read_from_buffer(&payload, end, &enrolled_password);
    319      if (ret != ERROR_NONE) {
    320          return ret;
    321      }
    322 
    323      return read_from_buffer(&payload, end, &password_handle);
    324 }
    325 
    326 EnrollResponse::EnrollResponse(uint32_t user_id, SizedBuffer *enrolled_password_handle) {
    327     this->user_id = user_id;
    328     this->enrolled_password_handle.buffer.reset(enrolled_password_handle->buffer.release());
    329     this->enrolled_password_handle.length = enrolled_password_handle->length;
    330 }
    331 
    332 EnrollResponse::EnrollResponse() {
    333     memset_s(&enrolled_password_handle, 0, sizeof(enrolled_password_handle));
    334 }
    335 
    336 EnrollResponse::~EnrollResponse() {
    337     if (enrolled_password_handle.buffer.get()) {
    338         enrolled_password_handle.buffer.reset();
    339     }
    340 }
    341 
    342 void EnrollResponse::SetEnrolledPasswordHandle(SizedBuffer *enrolled_password_handle) {
    343     this->enrolled_password_handle.buffer.reset(enrolled_password_handle->buffer.release());
    344     this->enrolled_password_handle.length = enrolled_password_handle->length;
    345 }
    346 
    347 uint32_t EnrollResponse::nonErrorSerializedSize() const {
    348     return serialized_buffer_size(enrolled_password_handle);
    349 }
    350 
    351 void EnrollResponse::nonErrorSerialize(uint8_t *buffer) const {
    352     append_to_buffer(&buffer, &enrolled_password_handle);
    353 }
    354 
    355 gatekeeper_error_t EnrollResponse::nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) {
    356     if (enrolled_password_handle.buffer.get()) {
    357         enrolled_password_handle.buffer.reset();
    358     }
    359 
    360     return read_from_buffer(&payload, end, &enrolled_password_handle);
    361 }
    362 
    363 };
    364 
    365