2323#include " pcsc-cpp/pcsc-cpp.hpp"
2424#include " pcsc-cpp/pcsc-cpp-utils.hpp"
2525
26- #include < sstream >
26+ #include < algorithm >
2727#include < iomanip>
28+ #include < sstream>
2829
2930using namespace pcsc_cpp ;
3031using namespace std ::string_literals;
3132
32- #ifdef HIBYTE
33- #undef HIBYTE
34- #endif
35- #ifdef LOBYTE
36- #undef LOBYTE
37- #endif
38-
39- constexpr byte_type HIBYTE (size_t w) noexcept
40- {
41- return static_cast <byte_type>((w >> 8 ) & 0xff );
42- }
43- constexpr byte_type LOBYTE (size_t w) noexcept
44- {
45- return static_cast <byte_type>(w & 0xff );
46- }
47-
4833namespace
4934{
5035
@@ -93,14 +78,9 @@ void transmitApduWithExpectedResponse(const SmartCard& card, const CommandApdu&
9378 }
9479}
9580
96- size_t readDataLengthFromAsn1 (const SmartCard& card)
81+ uint16_t readDataLengthFromAsn1 (const SmartCard& card)
9782{
98- // p1 - offset size first byte, 0
99- // p2 - offset size second byte, 0
100- // le - number of bytes to read, need 4 bytes from start for length
101- const CommandApdu readBinary4Bytes {0x00 , 0xb0 , 0x00 , 0x00 , 0x04 };
102-
103- auto response = card.transmit (readBinary4Bytes);
83+ auto response = card.transmit (CommandApdu::readBinary (0 , 0x04 ));
10484
10585 // Verify expected DER header, first byte must be SEQUENCE.
10686 if (response.data [0 ] != DER_SEQUENCE_TYPE_TAG) {
@@ -121,7 +101,7 @@ size_t readDataLengthFromAsn1(const SmartCard& card)
121101 }
122102
123103 // Read 2-byte length field at offset 2 and 3 and add the 4 DER length bytes.
124- const auto length = size_t (( response.data [2 ] << 8 ) + response.data [3 ] + 4 ) ;
104+ const uint16_t length = toSW ( response.data [2 ], response.data [3 ]) + 4 ;
125105 if (length < 128 || length > 0x0f00 ) {
126106 // TODO: more specific exception
127107 THROW (Error,
@@ -132,29 +112,19 @@ size_t readDataLengthFromAsn1(const SmartCard& card)
132112 return length;
133113}
134114
135- byte_vector readBinary (const SmartCard& card, const size_t length, byte_type blockLength)
115+ byte_vector readBinary (const SmartCard& card, const uint16_t length, byte_type blockLength)
136116{
137- auto lengthCounter = length;
138117 auto resultBytes = byte_vector {};
139-
140- for (size_t offset = 0 ; lengthCounter != 0 ;
141- offset += blockLength, lengthCounter -= blockLength) {
142-
143- if (blockLength > lengthCounter) {
144- blockLength = byte_type (lengthCounter);
118+ while (resultBytes.size () < length) {
119+ blockLength = byte_type (std::min<size_t >(length - resultBytes.size (), blockLength));
120+ auto response = card.transmit (CommandApdu::readBinary (uint16_t (resultBytes.size ()), blockLength));
121+ if (response.data .size () != blockLength) {
122+ THROW (Error,
123+ " readBinary(): Invalid length received: " s + std::to_string (response.data .size ())
124+ + " excpected: " + std::to_string (blockLength));
145125 }
146-
147- CommandApdu readBinary {0x00 , 0xb0 , HIBYTE (offset), LOBYTE (offset), blockLength};
148- auto response = card.transmit (readBinary);
149-
150126 resultBytes.insert (resultBytes.end (), response.data .cbegin (), response.data .cend ());
151127 }
152-
153- if (resultBytes.size () != length) {
154- // TODO: more specific exception
155- THROW (Error, " readBinary(): Invalid length: " s + std::to_string (resultBytes.size ()));
156- }
157-
158128 return resultBytes;
159129}
160130
0 commit comments