Reformatting.

This commit is contained in:
2019-08-23 13:27:30 +01:00
parent 03dba21ad4
commit 01dad2ee0a
42 changed files with 859 additions and 987 deletions

View File

@@ -18,119 +18,99 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "U2F_Msg_CMD.hpp"
#include "APDU.hpp"
#include "Field.hpp"
#include "Streams.hpp"
#include "U2FMessage.hpp"
#include "U2F_Authenticate_APDU.hpp"
#include "U2F_Register_APDU.hpp"
#include "U2F_Version_APDU.hpp"
#include "U2F_Authenticate_APDU.hpp"
#include "U2FMessage.hpp"
#include "u2f.hpp"
#include "APDU.hpp"
#include <iostream>
#include "Streams.hpp"
#include "Field.hpp"
using namespace std;
uint32_t U2F_Msg_CMD::getLe(const uint32_t byteCount, vector<uint8_t> bytes)
{
if (byteCount != 0)
{
//Le must be length of data in bytes
uint32_t U2F_Msg_CMD::getLe(const uint32_t byteCount, vector<uint8_t> bytes) {
if (byteCount != 0) {
// Le must be length of data in bytes
switch (byteCount)
{
switch (byteCount) {
case 1:
return (bytes[0] == 0 ? 256 : bytes[0]);
case 2:
//Don't handle non-compliance with spec here
//This case is only possible if extended Lc used
//CBA
// Don't handle non-compliance with spec here
// This case is only possible if extended Lc used
// CBA
return (bytes[0] == 0 && bytes[1] == 0 ? 65536 : (bytes[0] << 8) + bytes[1]);
case 3:
//Don't handle non-compliance with spec here
//This case is only possible if extended Lc not used
//CBA
// Don't handle non-compliance with spec here
// This case is only possible if extended Lc not used
// CBA
if (bytes[0] != 0)
throw runtime_error{ "First byte of 3-byte Le should be 0"};
throw runtime_error{ "First byte of 3-byte Le should be 0" };
return (bytes[1] == 0 && bytes[2] == 0 ? 65536 : (bytes[1] << 8) + bytes[2]);
default:
throw runtime_error{ "Too much data for command" };
}
}
else
} else
return 0;
}
shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const U2FMessage& uMsg)
{
shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const U2FMessage& uMsg) {
if (uMsg.cmd != U2FHID_MSG)
throw runtime_error{ "Failed to get U2F Msg uMsg" };
else if (uMsg.data.size() < 4)
{
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;
auto& dat = uMsg.data;
cmd.cla = dat[0];
if (cmd.cla != 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];
cmd.p1 = dat[2];
cmd.p2 = dat[3];
vector<uint8_t> data{ dat.begin() + 4, dat.end() };
const uint32_t cBCount = data.size();
auto startPtr = data.begin(), endPtr = data.end();
if (usesData.at(cmd.ins) || data.size() > 3)
{
if (cBCount == 0)
{
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
if (data[0] != 0) // 1 byte length
{
cmd.lc = data[0];
startPtr++;
}
else
{
} else {
cmd.lc = (data[1] << 8) + data[2];
startPtr += 3;
}
endPtr = startPtr + cmd.lc;
try
{
try {
cmd.le = getLe(data.end() - endPtr, vector<uint8_t>(endPtr, data.end()));
}
catch (runtime_error& ignored)
{
} catch (runtime_error& ignored) {
U2F_Msg_CMD::error(uMsg.cid, APDU_STATUS::SW_WRONG_LENGTH);
throw;
}
}
else
{
} else {
cmd.lc = 0;
endPtr = startPtr;
try
{
try {
cmd.le = getLe(cBCount, data);
}
catch (runtime_error& ignored)
{
} catch (runtime_error& ignored) {
U2F_Msg_CMD::error(uMsg.cid, APDU_STATUS::SW_WRONG_LENGTH);
throw;
}
@@ -141,42 +121,44 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const U2FMessage& uMsg)
#ifdef DEBUG_STREAMS
auto hAS = getHostAPDUStream().get();
fprintf(hAS, "<table>\n"
"\t\t\t<thead>\n"
"\t\t\t\t<tr>\n"
"\t\t\t\t\t<th>CLA</th>\n"
"\t\t\t\t\t<th>INS</th>\n"
"\t\t\t\t\t<th>P1</th>\n"
"\t\t\t\t\t<th>P2</th>\n"
"\t\t\t\t\t<th>Lc</th>\n"
"\t\t\t\t\t<th>Data</th>\n"
"\t\t\t\t\t<th>Le</th>\n"
"\t\t\t\t</tr>\n"
"\t\t\t</thead>\n"
"\t\t\t<tbody>\n"
"\t\t\t\t<tr>\n"
"\t\t\t\t\t<td>0x%02X</td>\n"
"\t\t\t\t\t<td>0x%02X</td>\n"
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td>%3u</td>\n"
"\t\t\t\t\t<td class=\"data\">", cmd.cla, cmd.ins, cmd.p1, cmd.p2, cmd.lc);
fprintf(hAS,
"<table>\n"
"\t\t\t<thead>\n"
"\t\t\t\t<tr>\n"
"\t\t\t\t\t<th>CLA</th>\n"
"\t\t\t\t\t<th>INS</th>\n"
"\t\t\t\t\t<th>P1</th>\n"
"\t\t\t\t\t<th>P2</th>\n"
"\t\t\t\t\t<th>Lc</th>\n"
"\t\t\t\t\t<th>Data</th>\n"
"\t\t\t\t\t<th>Le</th>\n"
"\t\t\t\t</tr>\n"
"\t\t\t</thead>\n"
"\t\t\t<tbody>\n"
"\t\t\t\t<tr>\n"
"\t\t\t\t\t<td>0x%02X</td>\n"
"\t\t\t\t\t<td>0x%02X</td>\n"
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td>%u</td>\n"
"\t\t\t\t\t<td>%3u</td>\n"
"\t\t\t\t\t<td class=\"data\">",
cmd.cla, cmd.ins, cmd.p1, cmd.p2, cmd.lc);
for (auto b : dBytes)
fprintf(hAS, "%3u ", b);
fprintf(hAS, "</td>\n"
"\t\t\t\t\t<td>%5u</td>\n"
"\t\t\t\t</tr>\n"
"\t\t\t</tbody>\n"
"\t\t</table>\n"
"\t\t<br />", cmd.le);
fprintf(hAS,
"</td>\n"
"\t\t\t\t\t<td>%5u</td>\n"
"\t\t\t\t</tr>\n"
"\t\t\t</tbody>\n"
"\t\t</table>\n"
"\t\t<br />",
cmd.le);
#endif
try
{
switch (cmd.ins)
{
try {
switch (cmd.ins) {
case APDU::U2F_REG:
return make_shared<U2F_Register_APDU>(cmd, dBytes);
case APDU::U2F_AUTH:
@@ -187,17 +169,14 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const U2FMessage& uMsg)
cerr << "Invalid command used" << endl;
throw APDU_STATUS::SW_INS_NOT_SUPPORTED;
}
}
catch (const APDU_STATUS e)
{
} catch (const APDU_STATUS e) {
U2F_Msg_CMD::error(uMsg.cid, e);
throw runtime_error{ "APDU construction error" };
return {};
}
}
void U2F_Msg_CMD::error(const uint32_t channelID, const uint16_t errCode)
{
void U2F_Msg_CMD::error(const uint32_t channelID, const uint16_t errCode) {
clog << "U2F_Msg_CMD::error " << errCode << endl;
U2FMessage msg{};
msg.cid = channelID;
@@ -206,13 +185,10 @@ void U2F_Msg_CMD::error(const uint32_t channelID, const uint16_t errCode)
msg.write();
}
const map<uint8_t, bool> U2F_Msg_CMD::usesData = {
{ U2F_REG, true },
{ U2F_AUTH, true },
{ U2F_VER, false }
};
const map<uint8_t, bool> U2F_Msg_CMD::usesData = { { U2F_REG, true },
{ U2F_AUTH, true },
{ U2F_VER, false } };
void U2F_Msg_CMD::respond(const uint32_t channelID) const
{
void U2F_Msg_CMD::respond(const uint32_t channelID) const {
U2F_Msg_CMD::error(channelID, static_cast<uint16_t>(APDU_STATUS::SW_INS_NOT_SUPPORTED));
}