Home | History | Annotate | Download | only in test
      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 
     27 using android::hardware::confirmationui::support::Message;
     28 using android::hardware::confirmationui::support::WriteStream;
     29 using android::hardware::confirmationui::support::ReadStream;
     30 using android::hardware::confirmationui::support::PromptUserConfirmationMsg;
     31 using android::hardware::confirmationui::support::write;
     32 using ::android::hardware::confirmationui::V1_0::UIOption;
     33 using ::android::hardware::keymaster::V4_0::HardwareAuthToken;
     34 using ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType;
     35 using ::android::hardware::hidl_string;
     36 using ::android::hardware::hidl_vec;
     37 
     38 #ifdef DEBUG_MSG_FORMATTING
     39 namespace {
     40 
     41 char nibble2hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
     42                        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
     43 
     44 std::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 
     67 TEST(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 
    110 TEST(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