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 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