1/* 2** 3** Copyright 2017, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#include <stddef.h> 19#include <stdint.h> 20#include <iomanip> 21#include <iostream> 22#include <string> 23 24#include <android/hardware/confirmationui/support/msg_formatting.h> 25#include <gtest/gtest.h> 26 27using android::hardware::confirmationui::support::Message; 28using android::hardware::confirmationui::support::WriteStream; 29using android::hardware::confirmationui::support::ReadStream; 30using android::hardware::confirmationui::support::PromptUserConfirmationMsg; 31using android::hardware::confirmationui::support::write; 32using ::android::hardware::confirmationui::V1_0::UIOption; 33using ::android::hardware::keymaster::V4_0::HardwareAuthToken; 34using ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType; 35using ::android::hardware::hidl_string; 36using ::android::hardware::hidl_vec; 37 38#ifdef DEBUG_MSG_FORMATTING 39namespace { 40 41char nibble2hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', 42 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 43 44std::ostream& hexdump(std::ostream& out, const uint8_t* data, size_t size) { 45 for (size_t i = 0; i < size; ++i) { 46 uint8_t byte = data[i]; 47 out << (nibble2hex[0x0F & (byte >> 4)]); 48 out << (nibble2hex[0x0F & byte]); 49 switch (i & 0xf) { 50 case 0xf: 51 out << "\n"; 52 break; 53 case 7: 54 out << " "; 55 break; 56 default: 57 out << " "; 58 break; 59 } 60 } 61 return out; 62} 63 64} // namespace 65#endif 66 67TEST(MsgFormattingTest, FeatureTest) { 68 uint8_t buffer[0x1000]; 69 70 WriteStream out(buffer); 71 out = unalign(out); 72 out += 4; 73 auto begin = out.pos(); 74 out = write( 75 PromptUserConfirmationMsg(), out, hidl_string("Do you?"), 76 hidl_vec<uint8_t>{0x01, 0x02, 0x03}, hidl_string("en"), 77 hidl_vec<UIOption>{UIOption::AccessibilityInverted, UIOption::AccessibilityMagnified}); 78 79 ReadStream in(buffer); 80 in = unalign(in); 81 in += 4; 82 hidl_string prompt; 83 hidl_vec<uint8_t> extra; 84 hidl_string locale; 85 hidl_vec<UIOption> uiOpts; 86 bool command_matches; 87 std::tie(in, command_matches, prompt, extra, locale, uiOpts) = 88 read(PromptUserConfirmationMsg(), in); 89 ASSERT_TRUE(in); 90 ASSERT_TRUE(command_matches); 91 ASSERT_EQ(hidl_string("Do you?"), prompt); 92 ASSERT_EQ((hidl_vec<uint8_t>{0x01, 0x02, 0x03}), extra); 93 ASSERT_EQ(hidl_string("en"), locale); 94 ASSERT_EQ( 95 (hidl_vec<UIOption>{UIOption::AccessibilityInverted, UIOption::AccessibilityMagnified}), 96 uiOpts); 97 98#ifdef DEBUG_MSG_FORMATTING 99 hexdump(std::cout, buffer, 100) << std::endl; 100#endif 101 102 // The following assertions check that the hidl_[vec|string] types are in fact read in place, 103 // and no copying occurs. Copying results in heap allocation which we intend to avoid. 104 ASSERT_EQ(8, const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(prompt.c_str())) - begin); 105 ASSERT_EQ(20, extra.data() - begin); 106 ASSERT_EQ(27, const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(locale.c_str())) - begin); 107 ASSERT_EQ(40, reinterpret_cast<uint8_t*>(uiOpts.data()) - begin); 108} 109 110TEST(MsgFormattingTest, HardwareAuthTokenTest) { 111 uint8_t buffer[0x1000]; 112 113 HardwareAuthToken expected, actual; 114 expected.authenticatorId = 0xa1a3a4a5a6a7a8; 115 expected.authenticatorType = HardwareAuthenticatorType::NONE; 116 expected.challenge = 0xb1b2b3b4b5b6b7b8; 117 expected.userId = 0x1122334455667788; 118 expected.timestamp = 0xf1f2f3f4f5f6f7f8; 119 expected.mac = 120 hidl_vec<uint8_t>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 121 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}; 122 123 WriteStream out(buffer); 124 out = write(Message<HardwareAuthToken>(), out, expected); 125 ReadStream in(buffer); 126 std::tie(in, actual) = read(Message<HardwareAuthToken>(), in); 127 ASSERT_EQ(expected, actual); 128} 129