| /* |
| * 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()); |
| } |