Improved U2F APDU Message error handling.

This commit is contained in:
2018-08-10 13:13:38 +00:00
parent 5d1d0ccb63
commit 2ced303d3a
6 changed files with 94 additions and 41 deletions

View File

@@ -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" };
}
}