Improved U2F APDU Message error handling.
This commit is contained in:
@@ -47,12 +47,22 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
|
||||
if (uMsg->cmd != U2FHID_MSG)
|
||||
throw runtime_error{ "Failed to get U2F Msg uMsg" };
|
||||
else if (uMsg->data.size() < 4)
|
||||
{
|
||||
U2F_Msg_CMD::error(uMsg->cid, APDU_STATUS::SW_WRONG_LENGTH);
|
||||
throw runtime_error{ "Msg data is incorrect size" };
|
||||
}
|
||||
|
||||
U2F_Msg_CMD cmd;
|
||||
auto &dat = uMsg->data;
|
||||
|
||||
cmd.cla = dat[0];
|
||||
|
||||
if (cmd.cla != 0)
|
||||
{
|
||||
U2F_Msg_CMD::error(uMsg->cid, APDU_STATUS::SW_COMMAND_NOT_ALLOWED);
|
||||
throw runtime_error{ "Invalid CLA value in U2F Message" };
|
||||
}
|
||||
|
||||
cmd.ins = dat[1];
|
||||
cmd.p1 = dat[2];
|
||||
cmd.p2 = dat[3];
|
||||
@@ -64,7 +74,10 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
|
||||
if (usesData.at(cmd.ins) || data.size() > 3)
|
||||
{
|
||||
if (cBCount == 0)
|
||||
{
|
||||
U2F_Msg_CMD::error(uMsg->cid, APDU_STATUS::SW_WRONG_LENGTH);
|
||||
throw runtime_error{ "Invalid command - should have attached data" };
|
||||
}
|
||||
|
||||
if (data[0] != 0) //1 byte length
|
||||
{
|
||||
@@ -79,14 +92,30 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
|
||||
|
||||
endPtr = startPtr + cmd.lc;
|
||||
|
||||
cmd.le = getLe(data.end() - endPtr, vector<uint8_t>(endPtr, data.end()));
|
||||
try
|
||||
{
|
||||
cmd.le = getLe(data.end() - endPtr, vector<uint8_t>(endPtr, data.end()));
|
||||
}
|
||||
catch (runtime_error)
|
||||
{
|
||||
U2F_Msg_CMD::error(uMsg->cid, APDU_STATUS::SW_WRONG_LENGTH);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.lc = 0;
|
||||
endPtr = startPtr;
|
||||
|
||||
cmd.le = getLe(cBCount, data);
|
||||
try
|
||||
{
|
||||
cmd.le = getLe(cBCount, data);
|
||||
}
|
||||
catch (runtime_error)
|
||||
{
|
||||
U2F_Msg_CMD::error(uMsg->cid, APDU_STATUS::SW_WRONG_LENGTH);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
const auto dBytes = vector<uint8_t>(startPtr, endPtr);
|
||||
@@ -124,16 +153,25 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
|
||||
"\t\t</table>\n"
|
||||
"\t\t<br />", cmd.le);
|
||||
|
||||
switch (cmd.ins)
|
||||
try
|
||||
{
|
||||
case APDU::U2F_REG:
|
||||
return make_shared<U2F_Register_APDU>(cmd, dBytes);
|
||||
case APDU::U2F_AUTH:
|
||||
return make_shared<U2F_Authenticate_APDU>(cmd, dBytes);
|
||||
case APDU::U2F_VER:
|
||||
return make_shared<U2F_Version_APDU>(cmd);
|
||||
default:
|
||||
throw runtime_error{ "Unknown APDU command issued" };
|
||||
switch (cmd.ins)
|
||||
{
|
||||
case APDU::U2F_REG:
|
||||
return make_shared<U2F_Register_APDU>(cmd, dBytes);
|
||||
case APDU::U2F_AUTH:
|
||||
return make_shared<U2F_Authenticate_APDU>(cmd, dBytes);
|
||||
case APDU::U2F_VER:
|
||||
return make_shared<U2F_Version_APDU>(cmd);
|
||||
default:
|
||||
cerr << "Invalid command used" << endl;
|
||||
throw APDU_STATUS::SW_INS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
catch (const APDU_STATUS e)
|
||||
{
|
||||
U2F_Msg_CMD::error(uMsg->cid, e);
|
||||
throw runtime_error{ "APDU construction error" };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user