| /* |
| * Copyright 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #ifndef GATEKEEPER_MESSAGES_H_ |
| #define GATEKEEPER_MESSAGES_H_ |
| |
| #include <stdint.h> |
| #include <gatekeeper/UniquePtr.h> |
| |
| #include <new> |
| |
| #include "gatekeeper_utils.h" |
| /** |
| * Message serialization objects for communicating with the hardware gatekeeper. |
| */ |
| namespace gatekeeper { |
| |
| const uint32_t ENROLL = 0; |
| const uint32_t VERIFY = 1; |
| const uint32_t DELETE_USER = 2; |
| const uint32_t DELETE_ALL_USERS = 3; |
| |
| typedef enum { |
| ERROR_NONE = 0, |
| ERROR_INVALID = 1, |
| ERROR_RETRY = 2, |
| ERROR_UNKNOWN = 3, |
| ERROR_MEMORY_ALLOCATION_FAILED = 4, |
| ERROR_NOT_IMPLEMENTED = 5, |
| } gatekeeper_error_t; |
| |
| struct SizedBuffer { |
| SizedBuffer() { |
| length = 0; |
| } |
| ~SizedBuffer() { |
| if (buffer && length > 0) { |
| memset_s(buffer.get(), 0, length); |
| } |
| } |
| /* |
| * Constructs a SizedBuffer out of a pointer and a length |
| * Takes ownership of the buf pointer, and deallocates it |
| * when destructed. |
| */ |
| SizedBuffer(uint8_t buf[], uint32_t len) { |
| if (buf == nullptr) { |
| length = 0; |
| } else { |
| buffer.reset(buf); |
| length = len; |
| } |
| } |
| |
| SizedBuffer(SizedBuffer && rhs) : buffer(move(rhs.buffer)), length(rhs.length) { |
| rhs.length = 0; |
| } |
| |
| SizedBuffer & operator=(SizedBuffer && rhs) { |
| if (&rhs != this) { |
| buffer = move(rhs.buffer); |
| length = rhs.length; |
| rhs.length = 0; |
| } |
| return *this; |
| } |
| |
| operator bool() const { |
| return buffer; |
| } |
| |
| uint32_t size() const { return buffer ? length : 0; } |
| |
| /** |
| * Returns an pointer to the const buffer IFF the buffer is initialized and the length |
| * field holds a values greater or equal to the size of the requested template argument type. |
| */ |
| template <typename T> |
| const T* Data() const { |
| if (buffer.get() != nullptr && sizeof(T) <= length) { |
| return reinterpret_cast<const T*>(buffer.get()); |
| } |
| return nullptr; |
| } |
| |
| private: |
| UniquePtr<uint8_t[]> buffer; |
| uint32_t length; |
| }; |
| |
| /* |
| * Abstract base class of all message objects. Handles serialization of common |
| * elements like the error and user ID. Delegates specialized serialization |
| * to protected pure virtual functions implemented by subclasses. |
| */ |
| struct GateKeeperMessage { |
| GateKeeperMessage() : error(ERROR_NONE) {} |
| explicit GateKeeperMessage(gatekeeper_error_t error) : error(error) {} |
| virtual ~GateKeeperMessage() {} |
| |
| /** |
| * Returns serialized size in bytes of the current state of the |
| * object. |
| */ |
| uint32_t GetSerializedSize() const; |
| /** |
| * Converts the object into its serialized representation. |
| * |
| * Expects payload to be allocated with GetSerializedSize bytes. |
| * |
| * Returns the number of bytes written or 0 on error. |
| */ |
| uint32_t Serialize(uint8_t *payload, const uint8_t *end) const; |
| |
| /** |
| * Inflates the object from its serial representation. |
| */ |
| gatekeeper_error_t Deserialize(const uint8_t *payload, const uint8_t *end); |
| |
| /** |
| * Calls may fail due to throttling. If so, this sets a timeout in milliseconds |
| * for when the caller should attempt the call again. Additionally, sets the |
| * error to ERROR_RETRY. |
| */ |
| void SetRetryTimeout(uint32_t retry_timeout); |
| |
| /** |
| * The following methods are intended to be implemented by subclasses. |
| * They are hooks to serialize the elements specific to each particular |
| * specialization. |
| */ |
| |
| /** |
| * Returns the size of serializing only the elements specific to the |
| * current sublclass. |
| */ |
| virtual uint32_t nonErrorSerializedSize() const { return 0; } ; |
| /** |
| * Takes a pointer to a buffer prepared by Serialize and writes |
| * the subclass specific data into it. The size of the buffer must be exactly |
| * that returned by nonErrorSerializedSize() in bytes. |
| */ |
| virtual void nonErrorSerialize(uint8_t *) const { } |
| |
| /** |
| * Deserializes subclass specific data from payload without reading past end. |
| */ |
| virtual gatekeeper_error_t nonErrorDeserialize(const uint8_t *, const uint8_t *) { |
| return ERROR_NONE; |
| } |
| |
| gatekeeper_error_t error; |
| uint32_t user_id; |
| uint32_t retry_timeout; |
| }; |
| |
| struct VerifyRequest : public GateKeeperMessage { |
| VerifyRequest( |
| uint32_t user_id, |
| uint64_t challenge, |
| SizedBuffer enrolled_password_handle, |
| SizedBuffer provided_password_payload); |
| VerifyRequest() : challenge(0) {} |
| |
| uint32_t nonErrorSerializedSize() const override; |
| void nonErrorSerialize(uint8_t *buffer) const override; |
| gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; |
| |
| uint64_t challenge; |
| SizedBuffer password_handle; |
| SizedBuffer provided_password; |
| }; |
| |
| struct VerifyResponse : public GateKeeperMessage { |
| VerifyResponse(uint32_t user_id, SizedBuffer auth_token); |
| VerifyResponse(); |
| |
| void SetVerificationToken(SizedBuffer auth_token); |
| |
| uint32_t nonErrorSerializedSize() const override; |
| void nonErrorSerialize(uint8_t *buffer) const override; |
| gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; |
| |
| SizedBuffer auth_token; |
| bool request_reenroll; |
| }; |
| |
| struct EnrollRequest : public GateKeeperMessage { |
| EnrollRequest(uint32_t user_id, SizedBuffer password_handle, |
| SizedBuffer provided_password, SizedBuffer enrolled_password); |
| EnrollRequest() = default; |
| |
| uint32_t nonErrorSerializedSize() const override; |
| void nonErrorSerialize(uint8_t *buffer) const override; |
| gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; |
| |
| /** |
| * The password handle returned from the previous call to enroll or NULL |
| * if none |
| */ |
| SizedBuffer password_handle; |
| /** |
| * The currently enrolled password as entered by the user |
| */ |
| SizedBuffer enrolled_password; |
| /** |
| * The password desired by the user |
| */ |
| SizedBuffer provided_password; |
| }; |
| |
| struct EnrollResponse : public GateKeeperMessage { |
| public: |
| EnrollResponse(uint32_t user_id, SizedBuffer enrolled_password_handle); |
| EnrollResponse() = default; |
| |
| void SetEnrolledPasswordHandle(SizedBuffer enrolled_password_handle); |
| |
| uint32_t nonErrorSerializedSize() const override; |
| void nonErrorSerialize(uint8_t *buffer) const override; |
| gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; |
| |
| SizedBuffer enrolled_password_handle; |
| }; |
| |
| struct DeleteUserRequest : public GateKeeperMessage { |
| DeleteUserRequest(uint32_t user_id); |
| DeleteUserRequest() = default; |
| |
| uint32_t nonErrorSerializedSize() const override { return 0; } |
| void nonErrorSerialize(uint8_t * /*buffer*/) const override {} |
| gatekeeper_error_t nonErrorDeserialize( |
| const uint8_t * /*payload*/, const uint8_t * /*end*/) override { return ERROR_NONE; } |
| }; |
| |
| struct DeleteUserResponse : public GateKeeperMessage { |
| DeleteUserResponse() {} |
| |
| uint32_t nonErrorSerializedSize() const override { return 0; } |
| void nonErrorSerialize(uint8_t * /*buffer*/) const override {} |
| gatekeeper_error_t nonErrorDeserialize( |
| const uint8_t * /*payload*/, const uint8_t * /*end*/) override { return ERROR_NONE; } |
| }; |
| |
| |
| struct DeleteAllUsersRequest : public GateKeeperMessage { |
| DeleteAllUsersRequest() {}; |
| |
| uint32_t nonErrorSerializedSize() const override { return 0; } |
| void nonErrorSerialize(uint8_t * /*buffer*/) const override {} |
| gatekeeper_error_t nonErrorDeserialize( |
| const uint8_t * /*payload*/, const uint8_t * /*end*/) override { return ERROR_NONE; } |
| }; |
| |
| struct DeleteAllUsersResponse : public GateKeeperMessage { |
| DeleteAllUsersResponse() {} |
| |
| uint32_t nonErrorSerializedSize() const override { return 0; } |
| void nonErrorSerialize(uint8_t * /*buffer*/) const override {} |
| gatekeeper_error_t nonErrorDeserialize( |
| const uint8_t * /*payload*/, const uint8_t * /*end*/) override { return ERROR_NONE; } |
| }; |
| |
| } |
| |
| #endif // GATEKEEPER_MESSAGES_H_ |