/* * Copyright (C) 2017 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. */ #include <algorithm> #include <iterator> #include <iostream> #include <gtest/gtest.h> #include <apdu/apdu.h> using android::CommandApdu; using android::ResponseApdu; /* CommandApdu */ TEST(CommandApduTest, Case1) { const CommandApdu apdu{1, 2, 3, 4}; const std::vector<uint8_t> expected{1, 2, 3, 4}; ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } TEST(CommandApduTest, Case2s) { const CommandApdu apdu{4, 3, 2, 1, 0, 3}; const std::vector<uint8_t> expected{4, 3, 2, 1, 3}; ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } TEST(CommandApduTest, Case2s_maxLe) { const CommandApdu apdu{4, 3, 2, 1, 0, 256}; const std::vector<uint8_t> expected{4, 3, 2, 1, 0}; ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } TEST(CommandApduTest, Case2e) { const CommandApdu apdu{5, 6, 7, 8, 0, 258}; const std::vector<uint8_t> expected{5, 6, 7, 8, 0, 1, 2}; ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } TEST(CommandApduTest, Case2e_maxLe) { const CommandApdu apdu{5, 6, 7, 8, 0, 65536}; const std::vector<uint8_t> expected{5, 6, 7, 8, 0, 0, 0}; ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } TEST(CommandApduTest, Case3s) { const CommandApdu apdu{8, 7, 6, 5, 5, 0}; const std::vector<uint8_t> expected{8, 7, 6, 5, 5, 0, 0, 0, 0, 0}; ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } TEST(CommandApduTest, Case3s_data) { CommandApdu apdu{8, 7, 6, 5, 3, 0}; auto it = apdu.dataBegin(); *it++ = 10; *it++ = 11; *it++ = 12; ASSERT_EQ(apdu.dataEnd(), it); const std::vector<uint8_t> expected{8, 7, 6, 5, 3, 10, 11, 12}; ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } TEST(CommandApduTest, Case3e) { const CommandApdu apdu{8, 7, 6, 5, 256, 0}; std::vector<uint8_t> expected{8, 7, 6, 5, 0, 1, 0}; expected.resize(expected.size() + 256, 0); ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } TEST(CommandApduTest, Case3e_data) { CommandApdu apdu{8, 7, 6, 5, 65535, 0}; ASSERT_EQ(size_t{65535}, apdu.dataSize()); std::fill(apdu.dataBegin(), apdu.dataEnd(), 7); std::vector<uint8_t> expected{8, 7, 6, 5, 0, 255, 255}; expected.resize(expected.size() + 65535, 7); ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } TEST(CommandApduTest, Case4s) { const CommandApdu apdu{1, 3, 5, 7, 2, 3}; const std::vector<uint8_t> expected{1, 3, 5, 7, 2, 0, 0, 3}; ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } TEST(CommandApduTest, Case4s_data) { CommandApdu apdu{1, 3, 5, 7, 1, 90}; auto it = apdu.dataBegin(); *it++ = 8; ASSERT_EQ(apdu.dataEnd(), it); const std::vector<uint8_t> expected{1, 3, 5, 7, 1, 8, 90}; ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } TEST(CommandApduTest, Case4s_maxLe) { const CommandApdu apdu{1, 3, 5, 7, 2, 256}; const std::vector<uint8_t> expected{1, 3, 5, 7, 2, 0, 0, 0}; ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } TEST(CommandApduTest, Case4e) { const CommandApdu apdu{1, 3, 5, 7, 527, 349}; std::vector<uint8_t> expected{1, 3, 5, 7, 0, 2, 15}; expected.resize(expected.size() + 527, 0); expected.push_back(1); expected.push_back(93); ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } TEST(CommandApduTest, Case4e_maxLe) { const CommandApdu apdu{1, 3, 5, 7, 20, 65536}; std::vector<uint8_t> expected{1, 3, 5, 7, 0, 0, 20}; expected.resize(expected.size() + 20, 0); expected.push_back(0); expected.push_back(0); ASSERT_EQ(expected.size(), apdu.size()); ASSERT_TRUE(std::equal(apdu.begin(), apdu.end(), expected.begin(), expected.end())); } /* ResponseApdu */ TEST(ResponseApduTest, bad) { const std::vector<uint8_t> empty{}; const ResponseApdu<std::vector<uint8_t>> apdu{empty}; ASSERT_FALSE(apdu.ok()); } TEST(ResponseApduTest, statusOnly) { const std::vector<uint8_t> statusOnly{0x90, 0x37}; const ResponseApdu<std::vector<uint8_t>> apdu{statusOnly}; ASSERT_TRUE(apdu.ok()); ASSERT_EQ(0x90, apdu.sw1()); ASSERT_EQ(0x37, apdu.sw2()); ASSERT_EQ(0x9037, apdu.status()); ASSERT_EQ(size_t{0}, apdu.dataSize()); } TEST(ResponseApduTest, data) { const std::vector<uint8_t> data{1, 2, 3, 9, 8, 7, 0x3a, 0xbc}; const ResponseApdu<std::vector<uint8_t>> apdu{data}; ASSERT_TRUE(apdu.ok()); ASSERT_EQ(0x3abc, apdu.status()); ASSERT_EQ(size_t{6}, apdu.dataSize()); const uint8_t expected[] = {1, 2, 3, 9, 8, 7}; ASSERT_TRUE(std::equal(apdu.dataBegin(), apdu.dataEnd(), std::begin(expected), std::end(expected))); } TEST(ResponseApduTest, remainingBytes) { const std::vector<uint8_t> remainingBytes{0x61, 23}; const ResponseApdu<std::vector<uint8_t>> apdu{remainingBytes}; ASSERT_EQ(23, apdu.remainingBytes()); ASSERT_FALSE(apdu.isWarning()); ASSERT_FALSE(apdu.isExecutionError()); ASSERT_FALSE(apdu.isCheckingError()); ASSERT_FALSE(apdu.isError()); } TEST(ResponseApduTest, warning) { const std::vector<uint8_t> warning{0x62, 0}; const ResponseApdu<std::vector<uint8_t>> apdu{warning}; ASSERT_TRUE(apdu.isWarning()); ASSERT_FALSE(apdu.isExecutionError()); ASSERT_FALSE(apdu.isCheckingError()); ASSERT_FALSE(apdu.isError()); } TEST(ResponseApduTest, executionError) { const std::vector<uint8_t> executionError{0x66, 0}; const ResponseApdu<std::vector<uint8_t>> apdu{executionError}; ASSERT_FALSE(apdu.isWarning()); ASSERT_TRUE(apdu.isExecutionError()); ASSERT_FALSE(apdu.isCheckingError()); ASSERT_TRUE(apdu.isError()); } TEST(ResponseApduTest, checkingError) { const std::vector<uint8_t> checkingError{0x67, 0}; const ResponseApdu<std::vector<uint8_t>> apdu{checkingError}; ASSERT_FALSE(apdu.isWarning()); ASSERT_FALSE(apdu.isExecutionError()); ASSERT_TRUE(apdu.isCheckingError()); ASSERT_TRUE(apdu.isError()); }