2121 */
2222
2323#include " pcsc-cpp/pcsc-cpp.hpp"
24+ #include " pcsc-cpp/pcsc-cpp-utils.hpp"
2425
2526#include < sstream>
2627#include < iomanip>
@@ -55,11 +56,13 @@ class UnexpectedResponseError : public Error
5556public:
5657 explicit UnexpectedResponseError (const CommandApdu& command,
5758 const byte_vector& expectedResponseBytes,
58- const ResponseApdu& response) :
59+ const ResponseApdu& response, const char * file, const int line,
60+ const char * callerFunctionName) :
5961 Error(" transmitApduWithExpectedResponse(): Unexpected response to command '" s
6062 + bytes2hexstr(command.toBytes()) + "' - expected '"s
61- + bytes2hexstr(expectedResponseBytes) + "', got '"s
62- + bytes2hexstr(response.toBytes()))
63+ + bytes2hexstr(expectedResponseBytes) + "', got '"s + bytes2hexstr(response.toBytes())
64+ + " in " + removeAbsolutePathPrefix(file) + ':' + std::to_string(line) + ':'
65+ + callerFunctionName)
6366 {
6467 }
6568};
@@ -95,7 +98,8 @@ void transmitApduWithExpectedResponse(const SmartCard& card, const CommandApdu&
9598{
9699 const auto response = card.transmit (command);
97100 if (response.toBytes () != expectedResponseBytes) {
98- throw UnexpectedResponseError (command, expectedResponseBytes, response);
101+ throw UnexpectedResponseError (command, expectedResponseBytes, response, __FILE__, __LINE__,
102+ __func__);
99103 }
100104}
101105
@@ -111,17 +115,19 @@ size_t readDataLengthFromAsn1(const SmartCard& card)
111115 // Verify expected DER header, first byte must be SEQUENCE.
112116 if (response.data [0 ] != DER_SEQUENCE_TYPE_TAG) {
113117 // TODO: more specific exception
114- throw Error (" readDataLengthFromAsn1(): First byte must be SEQUENCE (0x30), but is 0x" s
115- + bytes2hexstr ({response.data [0 ]}));
118+ THROW (Error,
119+ " readDataLengthFromAsn1(): First byte must be SEQUENCE (0x30), but is 0x" s
120+ + bytes2hexstr ({response.data [0 ]}));
116121 }
117122
118123 // TODO: support other lenghts besides 2.
119124 // Assume 2-byte length, so second byte must be 0x82.
120125 if (response.data [1 ] != DER_TWO_BYTE_LENGTH) {
121126 // TODO: more specific exception
122- throw Error (" readDataLengthFromAsn1(): Second byte must be two-byte length indicator " s
123- " (0x82), but is 0x" s
124- + bytes2hexstr ({response.data [1 ]}));
127+ THROW (Error,
128+ " readDataLengthFromAsn1(): Second byte must be two-byte length indicator " s
129+ " (0x82), but is 0x" s
130+ + bytes2hexstr ({response.data [1 ]}));
125131 }
126132
127133 // Read 2-byte length field at offset 2 and 3.
@@ -130,8 +136,9 @@ size_t readDataLengthFromAsn1(const SmartCard& card)
130136 const auto length = size_t ((response.data [2 ] << 8 ) + response.data [3 ] + 4 );
131137 if (length < 128 || length > 0x0f00 ) {
132138 // TODO: more specific exception
133- throw Error (" readDataLengthFromAsn1(): Unexpected data length in DER header: " s
134- + std::to_string (length));
139+ THROW (Error,
140+ " readDataLengthFromAsn1(): Unexpected data length in DER header: " s
141+ + std::to_string (length));
135142 }
136143
137144 return length;
@@ -162,7 +169,7 @@ byte_vector readBinary(const SmartCard& card, const size_t length, const size_t
162169
163170 if (resultBytes.size () != length) {
164171 // TODO: more specific exception
165- throw Error ( " readBinary(): Invalid length: " s + std::to_string (resultBytes.size ()));
172+ THROW (Error, " readBinary(): Invalid length: " s + std::to_string (resultBytes.size ()));
166173 }
167174
168175 return resultBytes;
0 commit comments