apdu_unittest.cc 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/apdu/apdu_command.h"
  5. #include "components/apdu/apdu_response.h"
  6. #include "testing/gmock/include/gmock/gmock.h"
  7. #include "testing/gtest/include/gtest/gtest.h"
  8. namespace apdu {
  9. TEST(ApduTest, TestDeserializeBasic) {
  10. uint8_t cla = 0xAA;
  11. uint8_t ins = 0xAB;
  12. uint8_t p1 = 0xAC;
  13. uint8_t p2 = 0xAD;
  14. std::vector<uint8_t> message({cla, ins, p1, p2});
  15. const auto cmd = ApduCommand::CreateFromMessage(message);
  16. ASSERT_TRUE(cmd);
  17. EXPECT_EQ(0u, cmd->response_length_);
  18. EXPECT_TRUE(cmd->data_.empty());
  19. EXPECT_EQ(cla, cmd->cla_);
  20. EXPECT_EQ(ins, cmd->ins_);
  21. EXPECT_EQ(p1, cmd->p1_);
  22. EXPECT_EQ(p2, cmd->p2_);
  23. // Invalid length.
  24. message = {cla, ins, p1};
  25. EXPECT_FALSE(ApduCommand::CreateFromMessage(message));
  26. message.push_back(p2);
  27. message.push_back(0);
  28. // Set APDU command data size as maximum.
  29. message.push_back(0xFF);
  30. message.push_back(0xFF);
  31. message.resize(message.size() + ApduCommand::kApduMaxDataLength);
  32. // Set maximum response size.
  33. message.push_back(0);
  34. message.push_back(0);
  35. // |message| is APDU encoded byte array with maximum data length.
  36. EXPECT_TRUE(ApduCommand::CreateFromMessage(message));
  37. message.push_back(0);
  38. // |message| encoding containing data of size maximum data length + 1.
  39. EXPECT_FALSE(ApduCommand::CreateFromMessage(message));
  40. }
  41. TEST(ApduTest, TestDeserializeComplex) {
  42. uint8_t cla = 0xAA;
  43. uint8_t ins = 0xAB;
  44. uint8_t p1 = 0xAC;
  45. uint8_t p2 = 0xAD;
  46. std::vector<uint8_t> data(
  47. ApduCommand::kApduMaxDataLength - ApduCommand::kApduMaxHeader - 2, 0x7F);
  48. std::vector<uint8_t> message = {cla, ins, p1, p2, 0};
  49. message.push_back((data.size() >> 8) & 0xff);
  50. message.push_back(data.size() & 0xff);
  51. message.insert(message.end(), data.begin(), data.end());
  52. // Create a message with no response expected.
  53. const auto cmd_no_response = ApduCommand::CreateFromMessage(message);
  54. ASSERT_TRUE(cmd_no_response);
  55. EXPECT_EQ(0u, cmd_no_response->response_length_);
  56. EXPECT_THAT(data, ::testing::ContainerEq(cmd_no_response->data_));
  57. EXPECT_EQ(cla, cmd_no_response->cla_);
  58. EXPECT_EQ(ins, cmd_no_response->ins_);
  59. EXPECT_EQ(p1, cmd_no_response->p1_);
  60. EXPECT_EQ(p2, cmd_no_response->p2_);
  61. // Add response length to message.
  62. message.push_back(0xF1);
  63. message.push_back(0xD0);
  64. const auto cmd = ApduCommand::CreateFromMessage(message);
  65. ASSERT_TRUE(cmd);
  66. EXPECT_THAT(data, ::testing::ContainerEq(cmd->data_));
  67. EXPECT_EQ(cla, cmd->cla_);
  68. EXPECT_EQ(ins, cmd->ins_);
  69. EXPECT_EQ(p1, cmd->p1_);
  70. EXPECT_EQ(p2, cmd->p2_);
  71. EXPECT_EQ(static_cast<size_t>(0xF1D0), cmd->response_length_);
  72. }
  73. TEST(ApduTest, TestDeserializeResponse) {
  74. ApduResponse::Status status;
  75. std::vector<uint8_t> test_vector;
  76. // Invalid length.
  77. std::vector<uint8_t> message({0xAA});
  78. EXPECT_FALSE(ApduResponse::CreateFromMessage(message));
  79. // Valid length and status.
  80. status = ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED;
  81. message = {static_cast<uint8_t>(static_cast<uint16_t>(status) >> 8),
  82. static_cast<uint8_t>(status)};
  83. auto response = ApduResponse::CreateFromMessage(message);
  84. ASSERT_TRUE(response);
  85. EXPECT_EQ(ApduResponse::Status::SW_CONDITIONS_NOT_SATISFIED,
  86. response->response_status_);
  87. EXPECT_THAT(response->data_, ::testing::ContainerEq(std::vector<uint8_t>()));
  88. // Valid length and status.
  89. status = ApduResponse::Status::SW_NO_ERROR;
  90. message = {static_cast<uint8_t>(static_cast<uint16_t>(status) >> 8),
  91. static_cast<uint8_t>(status)};
  92. test_vector = {0x01, 0x02, 0xEF, 0xFF};
  93. message.insert(message.begin(), test_vector.begin(), test_vector.end());
  94. response = ApduResponse::CreateFromMessage(message);
  95. ASSERT_TRUE(response);
  96. EXPECT_EQ(ApduResponse::Status::SW_NO_ERROR, response->response_status_);
  97. EXPECT_THAT(response->data_, ::testing::ContainerEq(test_vector));
  98. }
  99. TEST(ApduTest, TestSerializeCommand) {
  100. ApduCommand cmd;
  101. cmd.set_cla(0xA);
  102. cmd.set_ins(0xB);
  103. cmd.set_p1(0xC);
  104. cmd.set_p2(0xD);
  105. // No data, no response expected.
  106. std::vector<uint8_t> expected({0xA, 0xB, 0xC, 0xD});
  107. ASSERT_THAT(expected, ::testing::ContainerEq(cmd.GetEncodedCommand()));
  108. auto deserialized_cmd = ApduCommand::CreateFromMessage(expected);
  109. ASSERT_TRUE(deserialized_cmd);
  110. EXPECT_THAT(expected,
  111. ::testing::ContainerEq(deserialized_cmd->GetEncodedCommand()));
  112. // No data, response expected.
  113. cmd.set_response_length(0xCAFE);
  114. expected = {0xA, 0xB, 0xC, 0xD, 0x0, 0xCA, 0xFE};
  115. EXPECT_THAT(expected, ::testing::ContainerEq(cmd.GetEncodedCommand()));
  116. deserialized_cmd = ApduCommand::CreateFromMessage(expected);
  117. ASSERT_TRUE(deserialized_cmd);
  118. EXPECT_THAT(expected,
  119. ::testing::ContainerEq(deserialized_cmd->GetEncodedCommand()));
  120. // Data exists, response expected.
  121. std::vector<uint8_t> data({0x1, 0x2, 0x3, 0x4});
  122. cmd.set_data(data);
  123. expected = {0xA, 0xB, 0xC, 0xD, 0x0, 0x0, 0x4,
  124. 0x1, 0x2, 0x3, 0x4, 0xCA, 0xFE};
  125. EXPECT_THAT(expected, ::testing::ContainerEq(cmd.GetEncodedCommand()));
  126. deserialized_cmd = ApduCommand::CreateFromMessage(expected);
  127. ASSERT_TRUE(deserialized_cmd);
  128. EXPECT_THAT(expected,
  129. ::testing::ContainerEq(deserialized_cmd->GetEncodedCommand()));
  130. // Data exists, no response expected.
  131. cmd.set_response_length(0);
  132. expected = {0xA, 0xB, 0xC, 0xD, 0x0, 0x0, 0x4, 0x1, 0x2, 0x3, 0x4};
  133. EXPECT_THAT(expected, ::testing::ContainerEq(cmd.GetEncodedCommand()));
  134. EXPECT_THAT(
  135. expected,
  136. ::testing::ContainerEq(
  137. ApduCommand::CreateFromMessage(expected)->GetEncodedCommand()));
  138. }
  139. TEST(ApduTest, TestSerializeEdgeCases) {
  140. ApduCommand cmd;
  141. cmd.set_cla(0xA);
  142. cmd.set_ins(0xB);
  143. cmd.set_p1(0xC);
  144. cmd.set_p2(0xD);
  145. // Set response length to maximum, which should serialize to 0x0000.
  146. cmd.set_response_length(ApduCommand::kApduMaxResponseLength);
  147. std::vector<uint8_t> expected({0xA, 0xB, 0xC, 0xD, 0x0, 0x0, 0x0});
  148. EXPECT_THAT(expected, ::testing::ContainerEq(cmd.GetEncodedCommand()));
  149. auto deserialized_cmd = ApduCommand::CreateFromMessage(expected);
  150. ASSERT_TRUE(deserialized_cmd);
  151. EXPECT_THAT(expected,
  152. ::testing::ContainerEq(deserialized_cmd->GetEncodedCommand()));
  153. // Maximum data size.
  154. std::vector<uint8_t> oversized(ApduCommand::kApduMaxDataLength);
  155. cmd.set_data(oversized);
  156. deserialized_cmd = ApduCommand::CreateFromMessage(cmd.GetEncodedCommand());
  157. ASSERT_TRUE(deserialized_cmd);
  158. EXPECT_THAT(cmd.GetEncodedCommand(),
  159. ::testing::ContainerEq(deserialized_cmd->GetEncodedCommand()));
  160. }
  161. } // namespace apdu