Reformat
This commit is contained in:
10
APDU.hpp
10
APDU.hpp
@@ -18,15 +18,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
enum APDU : uint8_t
|
||||
{
|
||||
U2F_REG = 0x01,
|
||||
U2F_AUTH = 0x02,
|
||||
U2F_VER = 0x03
|
||||
};
|
||||
enum APDU : uint8_t { U2F_REG = 0x01, U2F_AUTH = 0x02, U2F_VER = 0x03 };
|
||||
|
||||
enum APDU_STATUS : uint16_t
|
||||
{
|
||||
enum APDU_STATUS : uint16_t {
|
||||
SW_NO_ERROR = 0x9000,
|
||||
SW_WRONG_LENGTH = 0x6700,
|
||||
SW_CONDITIONS_NOT_SATISFIED = 0x6985,
|
||||
|
||||
@@ -31,7 +31,9 @@ template <typename InContainer, typename Elem, size_t count>
|
||||
void b64decode(const InContainer& iContainer, std::array<Elem, count>& oArr);
|
||||
|
||||
template <typename InContainerIter, typename OutContainerIter>
|
||||
void b64encode(const InContainerIter beginIter, const InContainerIter endIter, OutContainerIter oBeginIter);
|
||||
void b64encode(const InContainerIter beginIter, const InContainerIter endIter,
|
||||
OutContainerIter oBeginIter);
|
||||
|
||||
template <typename InContainerIter, typename OutContainerIter>
|
||||
void b64decode(const InContainerIter beginIter, const InContainerIter endIter, OutContainerIter oBeginIter);
|
||||
void b64decode(const InContainerIter beginIter, const InContainerIter endIter,
|
||||
OutContainerIter oBeginIter);
|
||||
|
||||
104
Certificates.cpp
104
Certificates.cpp
@@ -25,66 +25,50 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// You can generate your own using the method detailed in the README.
|
||||
|
||||
uint8_t attestCert[] = {
|
||||
0x30, 0x82, 0x02, 0x29, 0x30, 0x82, 0x01, 0xd0, 0xa0, 0x03, 0x02, 0x01,
|
||||
0x02, 0x02, 0x09, 0x00, 0x8a, 0xe2, 0x21, 0x3f, 0x2f, 0x8b, 0x72, 0x52,
|
||||
0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
|
||||
0x30, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x55, 0x4b, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
|
||||
0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
|
||||
0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
|
||||
0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31,
|
||||
0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x55, 0x32,
|
||||
0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x74, 0x50, 0x46, 0x53, 0x71, 0x54,
|
||||
0x71, 0x6f, 0x5a, 0x6d, 0x62, 0x37, 0x38, 0x61, 0x6a, 0x6f, 0x2f, 0x75,
|
||||
0x58, 0x50, 0x73, 0x51, 0x3d, 0x3d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38,
|
||||
0x30, 0x36, 0x33, 0x30, 0x31, 0x39, 0x30, 0x37, 0x35, 0x31, 0x5a, 0x17,
|
||||
0x0d, 0x32, 0x38, 0x30, 0x36, 0x32, 0x37, 0x31, 0x39, 0x30, 0x37, 0x35,
|
||||
0x31, 0x5a, 0x30, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
|
||||
0x06, 0x13, 0x02, 0x55, 0x4b, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
|
||||
0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61,
|
||||
0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
|
||||
0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69,
|
||||
0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74,
|
||||
0x64, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20,
|
||||
0x55, 0x32, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x74, 0x50, 0x46, 0x53,
|
||||
0x71, 0x54, 0x71, 0x6f, 0x5a, 0x6d, 0x62, 0x37, 0x38, 0x61, 0x6a, 0x6f,
|
||||
0x2f, 0x75, 0x58, 0x50, 0x73, 0x51, 0x3d, 0x3d, 0x30, 0x59, 0x30, 0x13,
|
||||
0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
|
||||
0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x32,
|
||||
0x41, 0xc3, 0xb8, 0x96, 0x97, 0xd8, 0x90, 0x66, 0x41, 0x88, 0x96, 0xd4,
|
||||
0x73, 0xb6, 0x37, 0xf7, 0x85, 0x29, 0xaf, 0x3b, 0x15, 0x0f, 0x83, 0x61,
|
||||
0x67, 0xea, 0xc9, 0xb2, 0xdb, 0x82, 0xb3, 0x2c, 0x99, 0x60, 0x8a, 0x98,
|
||||
0x7c, 0xd4, 0x04, 0xa0, 0x92, 0x22, 0x05, 0xaa, 0xf7, 0x7a, 0x91, 0x02,
|
||||
0x03, 0xdd, 0x15, 0x88, 0x87, 0x6a, 0x26, 0xe9, 0xee, 0xcf, 0x99, 0xb1,
|
||||
0x66, 0xc0, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55,
|
||||
0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xcf, 0x7f, 0xfa, 0x7d, 0xc4, 0x8d,
|
||||
0xba, 0x60, 0x52, 0x4c, 0xb6, 0x16, 0x2e, 0x88, 0x62, 0xc7, 0x8c, 0xfc,
|
||||
0xe0, 0x63, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
|
||||
0x16, 0x80, 0x14, 0xcf, 0x7f, 0xfa, 0x7d, 0xc4, 0x8d, 0xba, 0x60, 0x52,
|
||||
0x4c, 0xb6, 0x16, 0x2e, 0x88, 0x62, 0xc7, 0x8c, 0xfc, 0xe0, 0x63, 0x30,
|
||||
0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30,
|
||||
0x03, 0x01, 0x01, 0xff, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
|
||||
0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x72,
|
||||
0x25, 0x89, 0xc1, 0x32, 0x54, 0x66, 0xf8, 0x0e, 0x58, 0x77, 0xe3, 0xb5,
|
||||
0x62, 0x47, 0x33, 0x18, 0x5a, 0xdc, 0x28, 0x6a, 0x4a, 0x56, 0xcb, 0x58,
|
||||
0x63, 0xe3, 0xa1, 0x02, 0x6a, 0xf0, 0xd8, 0x02, 0x20, 0x65, 0x26, 0x84,
|
||||
0x7c, 0xc3, 0x3b, 0x7d, 0x6a, 0x22, 0x0c, 0x22, 0x3d, 0xc8, 0x43, 0xb7,
|
||||
0x84, 0x8b, 0x7b, 0x48, 0x23, 0xb0, 0x1e, 0x13, 0x35, 0x1d, 0x1a, 0x90,
|
||||
0x44, 0x62, 0x6c, 0xab, 0x9b
|
||||
0x30, 0x82, 0x02, 0x29, 0x30, 0x82, 0x01, 0xd0, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
|
||||
0x8a, 0xe2, 0x21, 0x3f, 0x2f, 0x8b, 0x72, 0x52, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
|
||||
0x3d, 0x04, 0x03, 0x02, 0x30, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
|
||||
0x02, 0x55, 0x4b, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f,
|
||||
0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
|
||||
0x0a, 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
|
||||
0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x29, 0x30, 0x27, 0x06,
|
||||
0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x55, 0x32, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x74, 0x50,
|
||||
0x46, 0x53, 0x71, 0x54, 0x71, 0x6f, 0x5a, 0x6d, 0x62, 0x37, 0x38, 0x61, 0x6a, 0x6f, 0x2f, 0x75,
|
||||
0x58, 0x50, 0x73, 0x51, 0x3d, 0x3d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x36, 0x33, 0x30,
|
||||
0x31, 0x39, 0x30, 0x37, 0x35, 0x31, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x36, 0x32, 0x37, 0x31,
|
||||
0x39, 0x30, 0x37, 0x35, 0x31, 0x5a, 0x30, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
|
||||
0x06, 0x13, 0x02, 0x55, 0x4b, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a,
|
||||
0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
|
||||
0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69,
|
||||
0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x29, 0x30,
|
||||
0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x55, 0x32, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20,
|
||||
0x74, 0x50, 0x46, 0x53, 0x71, 0x54, 0x71, 0x6f, 0x5a, 0x6d, 0x62, 0x37, 0x38, 0x61, 0x6a, 0x6f,
|
||||
0x2f, 0x75, 0x58, 0x50, 0x73, 0x51, 0x3d, 0x3d, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
|
||||
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
|
||||
0x42, 0x00, 0x04, 0x32, 0x41, 0xc3, 0xb8, 0x96, 0x97, 0xd8, 0x90, 0x66, 0x41, 0x88, 0x96, 0xd4,
|
||||
0x73, 0xb6, 0x37, 0xf7, 0x85, 0x29, 0xaf, 0x3b, 0x15, 0x0f, 0x83, 0x61, 0x67, 0xea, 0xc9, 0xb2,
|
||||
0xdb, 0x82, 0xb3, 0x2c, 0x99, 0x60, 0x8a, 0x98, 0x7c, 0xd4, 0x04, 0xa0, 0x92, 0x22, 0x05, 0xaa,
|
||||
0xf7, 0x7a, 0x91, 0x02, 0x03, 0xdd, 0x15, 0x88, 0x87, 0x6a, 0x26, 0xe9, 0xee, 0xcf, 0x99, 0xb1,
|
||||
0x66, 0xc0, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
|
||||
0x04, 0x14, 0xcf, 0x7f, 0xfa, 0x7d, 0xc4, 0x8d, 0xba, 0x60, 0x52, 0x4c, 0xb6, 0x16, 0x2e, 0x88,
|
||||
0x62, 0xc7, 0x8c, 0xfc, 0xe0, 0x63, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
|
||||
0x16, 0x80, 0x14, 0xcf, 0x7f, 0xfa, 0x7d, 0xc4, 0x8d, 0xba, 0x60, 0x52, 0x4c, 0xb6, 0x16, 0x2e,
|
||||
0x88, 0x62, 0xc7, 0x8c, 0xfc, 0xe0, 0x63, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
|
||||
0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
|
||||
0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x72, 0x25, 0x89, 0xc1, 0x32,
|
||||
0x54, 0x66, 0xf8, 0x0e, 0x58, 0x77, 0xe3, 0xb5, 0x62, 0x47, 0x33, 0x18, 0x5a, 0xdc, 0x28, 0x6a,
|
||||
0x4a, 0x56, 0xcb, 0x58, 0x63, 0xe3, 0xa1, 0x02, 0x6a, 0xf0, 0xd8, 0x02, 0x20, 0x65, 0x26, 0x84,
|
||||
0x7c, 0xc3, 0x3b, 0x7d, 0x6a, 0x22, 0x0c, 0x22, 0x3d, 0xc8, 0x43, 0xb7, 0x84, 0x8b, 0x7b, 0x48,
|
||||
0x23, 0xb0, 0x1e, 0x13, 0x35, 0x1d, 0x1a, 0x90, 0x44, 0x62, 0x6c, 0xab, 0x9b
|
||||
};
|
||||
|
||||
uint8_t attestPrivKey[] = {
|
||||
0x7e, 0xbd, 0x91, 0x05, 0x5a, 0x80, 0x9f, 0x36, 0xe5, 0x2f, 0xe0, 0xd0,
|
||||
0xa9, 0x63, 0x0c, 0x86, 0x04, 0xb1, 0x04, 0xe3, 0xd1, 0xfb, 0xd0, 0x83,
|
||||
0xc7, 0x2e, 0x2f, 0x34, 0xb6, 0xd6, 0xa4, 0xb2
|
||||
};
|
||||
uint8_t attestPrivKey[] = { 0x7e, 0xbd, 0x91, 0x05, 0x5a, 0x80, 0x9f, 0x36, 0xe5, 0x2f, 0xe0,
|
||||
0xd0, 0xa9, 0x63, 0x0c, 0x86, 0x04, 0xb1, 0x04, 0xe3, 0xd1, 0xfb,
|
||||
0xd0, 0x83, 0xc7, 0x2e, 0x2f, 0x34, 0xb6, 0xd6, 0xa4, 0xb2 };
|
||||
|
||||
uint8_t attestPubKey[] = {
|
||||
0x04, 0x32, 0x41, 0xc3, 0xb8, 0x96, 0x97, 0xd8, 0x90, 0x66, 0x41, 0x88,
|
||||
0x96, 0xd4, 0x73, 0xb6, 0x37, 0xf7, 0x85, 0x29, 0xaf, 0x3b, 0x15, 0x0f,
|
||||
0x83, 0x61, 0x67, 0xea, 0xc9, 0xb2, 0xdb, 0x82, 0xb3, 0x2c, 0x99, 0x60,
|
||||
0x8a, 0x98, 0x7c, 0xd4, 0x04, 0xa0, 0x92, 0x22, 0x05, 0xaa, 0xf7, 0x7a,
|
||||
0x91, 0x02, 0x03, 0xdd, 0x15, 0x88, 0x87, 0x6a, 0x26, 0xe9, 0xee, 0xcf,
|
||||
0x99, 0xb1, 0x66, 0xc0, 0x01
|
||||
};
|
||||
uint8_t attestPubKey[] = { 0x04, 0x32, 0x41, 0xc3, 0xb8, 0x96, 0x97, 0xd8, 0x90, 0x66, 0x41,
|
||||
0x88, 0x96, 0xd4, 0x73, 0xb6, 0x37, 0xf7, 0x85, 0x29, 0xaf, 0x3b,
|
||||
0x15, 0x0f, 0x83, 0x61, 0x67, 0xea, 0xc9, 0xb2, 0xdb, 0x82, 0xb3,
|
||||
0x2c, 0x99, 0x60, 0x8a, 0x98, 0x7c, 0xd4, 0x04, 0xa0, 0x92, 0x22,
|
||||
0x05, 0xaa, 0xf7, 0x7a, 0x91, 0x02, 0x03, 0xdd, 0x15, 0x88, 0x87,
|
||||
0x6a, 0x26, 0xe9, 0xee, 0xcf, 0x99, 0xb1, 0x66, 0xc0, 0x01 };
|
||||
|
||||
21
Channel.cpp
21
Channel.cpp
@@ -17,24 +17,23 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Channel.hpp"
|
||||
#include <stdexcept>
|
||||
#include "u2f.hpp"
|
||||
#include "U2F_CMD.hpp"
|
||||
#include "u2f.hpp"
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
|
||||
Channel::Channel(const uint32_t channelID)
|
||||
: cid{ channelID }, initState{ ChannelInitState::Unitialised }, lockedState{ ChannelLockedState::Unlocked }
|
||||
{}
|
||||
: cid{ channelID }, initState{ ChannelInitState::Unitialised }, lockedState{
|
||||
ChannelLockedState::Unlocked
|
||||
} {}
|
||||
|
||||
uint32_t Channel::getCID() const
|
||||
{
|
||||
uint32_t Channel::getCID() const {
|
||||
return cid;
|
||||
}
|
||||
|
||||
void Channel::handle(const shared_ptr<U2FMessage> uMsg)
|
||||
{
|
||||
void Channel::handle(const shared_ptr<U2FMessage> uMsg) {
|
||||
if (uMsg->cmd == U2FHID_INIT)
|
||||
this->initState = ChannelInitState::Initialised;
|
||||
else if (uMsg->cid != this->cid)
|
||||
@@ -51,12 +50,10 @@ void Channel::handle(const shared_ptr<U2FMessage> uMsg)
|
||||
return cmd->respond(this->cid);
|
||||
}
|
||||
|
||||
void Channel::init(const ChannelInitState newInitState)
|
||||
{
|
||||
void Channel::init(const ChannelInitState newInitState) {
|
||||
this->initState = newInitState;
|
||||
}
|
||||
|
||||
void Channel::lock(const ChannelLockedState newLockedState)
|
||||
{
|
||||
void Channel::lock(const ChannelLockedState newLockedState) {
|
||||
this->lockedState = newLockedState;
|
||||
}
|
||||
|
||||
17
Channel.hpp
17
Channel.hpp
@@ -17,24 +17,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "U2FMessage.hpp"
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include "U2FMessage.hpp"
|
||||
|
||||
enum class ChannelInitState
|
||||
{
|
||||
Unitialised,
|
||||
Initialised
|
||||
};
|
||||
enum class ChannelInitState { Unitialised, Initialised };
|
||||
|
||||
enum class ChannelLockedState
|
||||
{
|
||||
Locked,
|
||||
Unlocked
|
||||
};
|
||||
enum class ChannelLockedState { Locked, Unlocked };
|
||||
|
||||
class Channel
|
||||
{
|
||||
class Channel {
|
||||
protected:
|
||||
uint32_t cid;
|
||||
ChannelInitState initState;
|
||||
|
||||
@@ -17,28 +17,25 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Controller.hpp"
|
||||
#include "u2f.hpp"
|
||||
#include <iostream>
|
||||
#include "IO.hpp"
|
||||
#include "LED.hpp"
|
||||
#include "u2f.hpp"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
Controller::Controller(const uint32_t startChannel)
|
||||
: channels{}, currChannel{ startChannel }
|
||||
{}
|
||||
Controller::Controller(const uint32_t startChannel) : channels{}, currChannel{ startChannel } {}
|
||||
|
||||
void Controller::handleTransaction()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (channels.size() != 0 && chrono::duration_cast<chrono::seconds>(chrono::system_clock::now() - lastMessage) < chrono::seconds(5))
|
||||
void Controller::handleTransaction() {
|
||||
try {
|
||||
if (channels.size() != 0 &&
|
||||
chrono::duration_cast<chrono::seconds>(chrono::system_clock::now() - lastMessage) <
|
||||
chrono::seconds(5))
|
||||
toggleACTLED();
|
||||
else
|
||||
enableACTLED(false);
|
||||
} catch (runtime_error& ignored) {
|
||||
}
|
||||
catch (runtime_error& ignored)
|
||||
{}
|
||||
|
||||
auto msg = U2FMessage::readNonBlock();
|
||||
|
||||
@@ -49,17 +46,13 @@ void Controller::handleTransaction()
|
||||
|
||||
auto opChannel = msg->cid;
|
||||
|
||||
if (msg->cmd == U2FHID_INIT)
|
||||
{
|
||||
if (msg->cmd == U2FHID_INIT) {
|
||||
opChannel = nextChannel();
|
||||
auto channel = Channel{ opChannel };
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
channels.emplace(opChannel, channel); // In case of wrap-around replace existing one
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
} catch (...) {
|
||||
channels.insert(make_pair(opChannel, channel));
|
||||
}
|
||||
}
|
||||
@@ -72,8 +65,7 @@ void Controller::handleTransaction()
|
||||
channels.at(opChannel).handle(msg);
|
||||
}
|
||||
|
||||
uint32_t Controller::nextChannel()
|
||||
{
|
||||
uint32_t Controller::nextChannel() {
|
||||
do
|
||||
currChannel++;
|
||||
while (currChannel == 0xFFFFFFFF || currChannel == 0);
|
||||
|
||||
@@ -17,12 +17,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <chrono>
|
||||
#include "Channel.hpp"
|
||||
#include <chrono>
|
||||
#include <map>
|
||||
|
||||
class Controller
|
||||
{
|
||||
class Controller {
|
||||
protected:
|
||||
std::map<uint32_t, Channel> channels;
|
||||
uint32_t currChannel;
|
||||
|
||||
@@ -20,7 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using namespace std;
|
||||
|
||||
vector<uint8_t> beEncode(const uint8_t* val, const size_t byteCount)
|
||||
{
|
||||
return { reverse_iterator<const uint8_t *>(val + byteCount), reverse_iterator<const uint8_t *>(val) };
|
||||
vector<uint8_t> beEncode(const uint8_t* val, const size_t byteCount) {
|
||||
return { reverse_iterator<const uint8_t*>(val + byteCount),
|
||||
reverse_iterator<const uint8_t*>(val) };
|
||||
}
|
||||
|
||||
10
Field.hpp
10
Field.hpp
@@ -17,13 +17,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
template <typename Type>
|
||||
std::vector<uint8_t> beEncode(const Type val);
|
||||
|
||||
std::vector<uint8_t> beEncode(const uint8_t* val, const std::size_t byteCount);
|
||||
|
||||
#define FIELD(name) reinterpret_cast<const uint8_t*>(&name), (reinterpret_cast<const uint8_t*>(&name) + sizeof(name))
|
||||
#define FIELD_BE(name) reverse_iterator<const uint8_t*>(reinterpret_cast<const uint8_t*>(&name) + sizeof(name)), reverse_iterator<const uint8_t*>(reinterpret_cast<const uint8_t*>(&name))
|
||||
#define FIELD(name) \
|
||||
reinterpret_cast<const uint8_t*>(&name), \
|
||||
(reinterpret_cast<const uint8_t*>(&name) + sizeof(name))
|
||||
#define FIELD_BE(name) \
|
||||
reverse_iterator<const uint8_t*>(reinterpret_cast<const uint8_t*>(&name) + sizeof(name)), \
|
||||
reverse_iterator<const uint8_t*>(reinterpret_cast<const uint8_t*>(&name))
|
||||
|
||||
62
IO.cpp
62
IO.cpp
@@ -21,26 +21,24 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
//#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <chrono>
|
||||
#include <ratio>
|
||||
#include "u2f.hpp"
|
||||
#include "Macro.hpp"
|
||||
#include "U2FDevice.hpp"
|
||||
#include "u2f.hpp"
|
||||
#include <chrono>
|
||||
#include <fcntl.h>
|
||||
#include <ratio>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool bytesAvailable(const size_t count);
|
||||
vector<uint8_t>& getBuffer();
|
||||
|
||||
vector<uint8_t> readNonBlock(const size_t count)
|
||||
{
|
||||
if (!bytesAvailable(count))
|
||||
{
|
||||
vector<uint8_t> readNonBlock(const size_t count) {
|
||||
if (!bytesAvailable(count)) {
|
||||
return vector<uint8_t>{};
|
||||
}
|
||||
|
||||
@@ -54,32 +52,29 @@ vector<uint8_t> readNonBlock(const size_t count)
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void write(const uint8_t* bytes, const size_t count)
|
||||
{
|
||||
void write(const uint8_t* bytes, const size_t count) {
|
||||
size_t totalBytes = 0;
|
||||
auto hostDescriptor = *getHostDescriptor();
|
||||
|
||||
while (totalBytes < count)
|
||||
{
|
||||
while (totalBytes < count) {
|
||||
auto writtenBytes = write(hostDescriptor, bytes + totalBytes, count - totalBytes);
|
||||
|
||||
if (writtenBytes > 0)
|
||||
totalBytes += writtenBytes;
|
||||
else if (errno != 0 && errno != EAGAIN && errno != EWOULDBLOCK) //Expect file blocking behaviour
|
||||
else if (errno != 0 && errno != EAGAIN &&
|
||||
errno != EWOULDBLOCK) // Expect file blocking behaviour
|
||||
ERR();
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
bool bytesAvailable(const size_t count)
|
||||
{
|
||||
bool bytesAvailable(const size_t count) {
|
||||
auto startTime = std::chrono::high_resolution_clock::now();
|
||||
const timespec iterDelay{ 0, 1000 };
|
||||
chrono::duration<double, milli> delay{ 0 };
|
||||
|
||||
while (delay.count() < U2FHID_TRANS_TIMEOUT && contProc)
|
||||
{
|
||||
while (delay.count() < U2FHID_TRANS_TIMEOUT && contProc) {
|
||||
delay = chrono::high_resolution_clock::now() - startTime;
|
||||
if (getBuffer().size() >= count) {
|
||||
#ifdef DEBUG_MSGS
|
||||
@@ -97,49 +92,42 @@ bool bytesAvailable(const size_t count)
|
||||
return false;
|
||||
}
|
||||
|
||||
vector<uint8_t>& bufferVar()
|
||||
{
|
||||
vector<uint8_t>& bufferVar() {
|
||||
static vector<uint8_t> buffer{};
|
||||
return buffer;
|
||||
}
|
||||
|
||||
vector<uint8_t>& getBuffer()
|
||||
{
|
||||
vector<uint8_t>& getBuffer() {
|
||||
auto& buff = bufferVar();
|
||||
array<uint8_t, HID_RPT_SIZE> bytes{};
|
||||
auto hostDescriptor = *getHostDescriptor();
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (true) {
|
||||
auto readByteCount = read(hostDescriptor, bytes.data(), HID_RPT_SIZE);
|
||||
|
||||
if (readByteCount > 0 && readByteCount != HID_RPT_SIZE)
|
||||
{
|
||||
if (readByteCount > 0 && readByteCount != HID_RPT_SIZE) {
|
||||
// Failed to copy an entire packet in, so log this packet
|
||||
#ifdef DEBUG_MSGS
|
||||
cerr << "Only retrieved " << readByteCount << " bytes from expected full packet." << endl;
|
||||
cerr << "Only retrieved " << readByteCount << " bytes from expected full packet."
|
||||
<< endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (readByteCount > 0)
|
||||
{
|
||||
if (readByteCount > 0) {
|
||||
copy(bytes.begin(), bytes.begin() + readByteCount, back_inserter(buff));
|
||||
|
||||
#ifdef DEBUG_STREAMS
|
||||
fwrite(bytes.data(), 1, readByteCount, getComHostStream().get());
|
||||
#endif
|
||||
|
||||
}
|
||||
else if (errno != EAGAIN && errno != EWOULDBLOCK) //Expect read would block
|
||||
} else if (errno != EAGAIN && errno != EWOULDBLOCK) // Expect read would block
|
||||
{
|
||||
ERR();
|
||||
#ifdef DEBUG_MSGS
|
||||
cerr << "Unknown stream error: " << errno << endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
errno = 0;
|
||||
break; // Escape loop if blocking would occur
|
||||
}
|
||||
|
||||
15
LED.cpp
15
LED.cpp
@@ -24,19 +24,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool& ledState()
|
||||
{
|
||||
bool& ledState() {
|
||||
static bool state = true;
|
||||
return state;
|
||||
}
|
||||
|
||||
bool getLEDState()
|
||||
{
|
||||
bool getLEDState() {
|
||||
return ledState();
|
||||
}
|
||||
|
||||
void disableACTTrigger([[maybe_unused]] bool nowDisabled)
|
||||
{
|
||||
void disableACTTrigger([[maybe_unused]] bool nowDisabled) {
|
||||
#ifdef LEDS
|
||||
ofstream trigFile{ "/sys/class/leds/led0/trigger", ofstream::out | ofstream::trunc };
|
||||
|
||||
@@ -48,8 +45,7 @@ void disableACTTrigger([[maybe_unused]] bool nowDisabled)
|
||||
#endif
|
||||
}
|
||||
|
||||
void enableACTLED([[maybe_unused]] bool nowOn)
|
||||
{
|
||||
void enableACTLED([[maybe_unused]] bool nowOn) {
|
||||
#ifdef LEDS
|
||||
if (nowOn == getLEDState())
|
||||
return;
|
||||
@@ -66,7 +62,6 @@ void enableACTLED([[maybe_unused]] bool nowOn)
|
||||
#endif
|
||||
}
|
||||
|
||||
void toggleACTLED()
|
||||
{
|
||||
void toggleACTLED() {
|
||||
enableACTLED(!getLEDState());
|
||||
}
|
||||
|
||||
@@ -17,7 +17,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
|
||||
#define ERR() if (errno != 0) perror((string{ "(" } + __FILE__ + ":" + to_string(__LINE__) + ")" + " " + __PRETTY_FUNCTION__).c_str()), errno = 0
|
||||
#define ERR() \
|
||||
if (errno != 0) \
|
||||
perror( \
|
||||
(string{ "(" } + __FILE__ + ":" + to_string(__LINE__) + ")" + " " + __PRETTY_FUNCTION__) \
|
||||
.c_str()), \
|
||||
errno = 0
|
||||
|
||||
63
Packet.cpp
63
Packet.cpp
@@ -18,24 +18,22 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Packet.hpp"
|
||||
#include "IO.hpp"
|
||||
#include "Streams.hpp"
|
||||
#include "u2f.hpp"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include "Streams.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t rCMD)
|
||||
{
|
||||
shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t rCMD) {
|
||||
static size_t bytesRead = 0;
|
||||
static uint8_t bcnth;
|
||||
static uint8_t bcntl;
|
||||
static decltype(InitPacket::data) dataBytes;
|
||||
vector<uint8_t> bytes{};
|
||||
|
||||
switch (bytesRead)
|
||||
{
|
||||
switch (bytesRead) {
|
||||
case 0:
|
||||
bytes = readNonBlock(1);
|
||||
|
||||
@@ -62,7 +60,8 @@ shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t
|
||||
if (bytes.size() == 0)
|
||||
return {};
|
||||
|
||||
copy(bytes.begin(), bytes.end(), dataBytes.begin());;
|
||||
copy(bytes.begin(), bytes.end(), dataBytes.begin());
|
||||
;
|
||||
bytesRead += bytes.size();
|
||||
[[fallthrough]];
|
||||
|
||||
@@ -82,7 +81,8 @@ shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t
|
||||
|
||||
#ifdef DEBUG_STREAMS
|
||||
auto hPStream = getHostPacketStream().get();
|
||||
fprintf(hPStream, "\t\t<table>\n"
|
||||
fprintf(hPStream,
|
||||
"\t\t<table>\n"
|
||||
"\t\t\t<thead>\n"
|
||||
"\t\t\t\t<tr>\n"
|
||||
"\t\t\t\t\t<th>CID</th>\n"
|
||||
@@ -98,7 +98,8 @@ shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t
|
||||
"\t\t\t\t\t<td>%u</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 class=\"data\">", p->cid, p->cmd, p->bcnth, p->bcntl);
|
||||
"\t\t\t\t\t<td class=\"data\">",
|
||||
p->cid, p->cmd, p->bcnth, p->bcntl);
|
||||
|
||||
for (auto elem : dataBytes)
|
||||
fprintf(hPStream, "%3u ", elem);
|
||||
@@ -114,16 +115,14 @@ shared_ptr<InitPacket> InitPacket::getPacket(const uint32_t rCID, const uint8_t
|
||||
return p;
|
||||
}
|
||||
|
||||
shared_ptr<ContPacket> ContPacket::getPacket(const uint32_t rCID, const uint8_t rSeq)
|
||||
{
|
||||
shared_ptr<ContPacket> ContPacket::getPacket(const uint32_t rCID, const uint8_t rSeq) {
|
||||
static size_t readBytes = 0;
|
||||
static decltype(ContPacket::data) dataBytes;
|
||||
|
||||
vector<uint8_t> bytes{};
|
||||
auto p = make_shared<ContPacket>();
|
||||
|
||||
if (readBytes != dataBytes.size())
|
||||
{
|
||||
if (readBytes != dataBytes.size()) {
|
||||
dataBytes = {};
|
||||
bytes = readNonBlock(dataBytes.size());
|
||||
|
||||
@@ -140,7 +139,8 @@ shared_ptr<ContPacket> ContPacket::getPacket(const uint32_t rCID, const uint8_t
|
||||
|
||||
#ifdef DEBUG_STREAMS
|
||||
auto hPStream = getHostPacketStream().get();
|
||||
fprintf(hPStream, "\t\t<table>\n"
|
||||
fprintf(hPStream,
|
||||
"\t\t<table>\n"
|
||||
"\t\t\t<thead>\n"
|
||||
"\t\t\t\t<tr>\n"
|
||||
"\t\t\t\t\t<th>CID</th>\n"
|
||||
@@ -152,7 +152,8 @@ shared_ptr<ContPacket> ContPacket::getPacket(const uint32_t rCID, const uint8_t
|
||||
"\t\t\t\t<tr>\n"
|
||||
"\t\t\t\t\t<td>0x%08X</td>\n"
|
||||
"\t\t\t\t\t<td>%u</td>\n"
|
||||
"\t\t\t\t\t<td class=\"data\">", p->cid, p->seq);
|
||||
"\t\t\t\t\t<td class=\"data\">",
|
||||
p->cid, p->seq);
|
||||
|
||||
for (auto elem : dataBytes)
|
||||
fprintf(hPStream, "%3u ", elem);
|
||||
@@ -168,8 +169,7 @@ shared_ptr<ContPacket> ContPacket::getPacket(const uint32_t rCID, const uint8_t
|
||||
return p;
|
||||
}
|
||||
|
||||
shared_ptr<Packet> Packet::getPacket()
|
||||
{
|
||||
shared_ptr<Packet> Packet::getPacket() {
|
||||
static size_t bytesRead = 0;
|
||||
vector<uint8_t> bytes{};
|
||||
|
||||
@@ -177,8 +177,7 @@ shared_ptr<Packet> Packet::getPacket()
|
||||
static uint8_t b;
|
||||
shared_ptr<Packet> packet{};
|
||||
|
||||
switch (bytesRead)
|
||||
{
|
||||
switch (bytesRead) {
|
||||
case 0:
|
||||
bytes = readNonBlock(4);
|
||||
|
||||
@@ -200,8 +199,7 @@ shared_ptr<Packet> Packet::getPacket()
|
||||
[[fallthrough]];
|
||||
|
||||
case 5:
|
||||
if (b & TYPE_MASK)
|
||||
{
|
||||
if (b & TYPE_MASK) {
|
||||
// Init packet
|
||||
packet = InitPacket::getPacket(cid, b);
|
||||
|
||||
@@ -209,9 +207,7 @@ shared_ptr<Packet> Packet::getPacket()
|
||||
bytesRead = 0;
|
||||
|
||||
return packet;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Cont packet
|
||||
packet = ContPacket::getPacket(cid, b);
|
||||
|
||||
@@ -225,14 +221,12 @@ shared_ptr<Packet> Packet::getPacket()
|
||||
}
|
||||
}
|
||||
|
||||
void Packet::writePacket()
|
||||
{
|
||||
void Packet::writePacket() {
|
||||
memset(this->buf, 0, HID_RPT_SIZE);
|
||||
memcpy(this->buf, &cid, 4);
|
||||
}
|
||||
|
||||
void InitPacket::writePacket()
|
||||
{
|
||||
void InitPacket::writePacket() {
|
||||
Packet::writePacket();
|
||||
|
||||
#ifdef DEBUG_STREAMS
|
||||
@@ -249,7 +243,8 @@ void InitPacket::writePacket()
|
||||
fwrite(this->buf, 1, sizeof(this->buf), devStream);
|
||||
|
||||
auto dPStream = getDevPacketStream().get();
|
||||
fprintf(dPStream, "\t\t<table>\n"
|
||||
fprintf(dPStream,
|
||||
"\t\t<table>\n"
|
||||
"\t\t\t<thead>\n"
|
||||
"\t\t\t\t<tr>\n"
|
||||
"\t\t\t\t\t<th>CID</th>\n"
|
||||
@@ -265,7 +260,8 @@ void InitPacket::writePacket()
|
||||
"\t\t\t\t\t<td>%u</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 class=\"data\">", cid, cmd, bcnth, bcntl);
|
||||
"\t\t\t\t\t<td class=\"data\">",
|
||||
cid, cmd, bcnth, bcntl);
|
||||
|
||||
for (auto elem : data)
|
||||
fprintf(dPStream, "%3u ", elem);
|
||||
@@ -278,8 +274,7 @@ void InitPacket::writePacket()
|
||||
#endif
|
||||
}
|
||||
|
||||
void ContPacket::writePacket()
|
||||
{
|
||||
void ContPacket::writePacket() {
|
||||
Packet::writePacket();
|
||||
|
||||
#ifdef DEBUG_STREAMS
|
||||
@@ -295,7 +290,8 @@ void ContPacket::writePacket()
|
||||
|
||||
auto dPStream = getDevPacketStream().get();
|
||||
|
||||
fprintf(dPStream, "\t\t<table>\n"
|
||||
fprintf(dPStream,
|
||||
"\t\t<table>\n"
|
||||
"\t\t\t<thead>\n"
|
||||
"\t\t\t\t<tr>\n"
|
||||
"\t\t\t\t\t<th>CID</th>\n"
|
||||
@@ -307,7 +303,8 @@ void ContPacket::writePacket()
|
||||
"\t\t\t\t<tr>\n"
|
||||
"\t\t\t\t\t<td>0x%08X</td>\n"
|
||||
"\t\t\t\t\t<td>%u</td>\n"
|
||||
"\t\t\t\t\t<td class=\"data\">", cid, seq);
|
||||
"\t\t\t\t\t<td class=\"data\">",
|
||||
cid, seq);
|
||||
|
||||
for (auto elem : data)
|
||||
fprintf(dPStream, "%3u ", elem);
|
||||
|
||||
13
Packet.hpp
13
Packet.hpp
@@ -17,13 +17,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "u2f.hpp"
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <array>
|
||||
#include "u2f.hpp"
|
||||
|
||||
struct Packet
|
||||
{
|
||||
struct Packet {
|
||||
public:
|
||||
uint32_t cid;
|
||||
uint8_t buf[HID_RPT_SIZE];
|
||||
@@ -37,8 +36,7 @@ struct Packet
|
||||
virtual ~Packet() = default;
|
||||
};
|
||||
|
||||
struct InitPacket : Packet
|
||||
{
|
||||
struct InitPacket : Packet {
|
||||
public:
|
||||
uint8_t cmd;
|
||||
uint8_t bcnth;
|
||||
@@ -51,8 +49,7 @@ struct InitPacket : Packet
|
||||
void writePacket() override;
|
||||
};
|
||||
|
||||
struct ContPacket : Packet
|
||||
{
|
||||
struct ContPacket : Packet {
|
||||
public:
|
||||
uint8_t seq;
|
||||
std::array<uint8_t, HID_RPT_SIZE - 5> data{};
|
||||
|
||||
@@ -22,21 +22,18 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
using namespace std;
|
||||
|
||||
// Ripped from https://github.com/pratikd650/Teensy_U2F/blob/master/Teensy_U2F.cpp
|
||||
void appendSignatureAsDER(vector<uint8_t> &response, const array<uint8_t, 64> &signature)
|
||||
{
|
||||
void appendSignatureAsDER(vector<uint8_t>& response, const array<uint8_t, 64>& signature) {
|
||||
response.push_back(0x30); // Start of ASN.1 SEQUENCE
|
||||
response.push_back(68); // total length from (2 * (32 + 2)) to (2 * (33 + 2))
|
||||
size_t countByte = response.size() - 1;
|
||||
|
||||
// Loop twice - for R and S
|
||||
for(unsigned int i = 0; i < 2; i++)
|
||||
{
|
||||
for (unsigned int i = 0; i < 2; i++) {
|
||||
unsigned int sigOffs = i * 32;
|
||||
auto offset = signature.begin() + sigOffs;
|
||||
response.push_back(0x02); // header: integer
|
||||
response.push_back(32); // 32 byte
|
||||
if (signature[sigOffs] > 0x7f)
|
||||
{
|
||||
if (signature[sigOffs] > 0x7f) {
|
||||
// Integer needs to be represented in 2's completement notion
|
||||
response.back()++;
|
||||
response.push_back(0); // add leading 0, to indicate it is a positive number
|
||||
|
||||
@@ -17,8 +17,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
using Digest = std::array<uint8_t, 32>;
|
||||
using Signature = std::array<uint8_t, 64>;
|
||||
|
||||
22
Storage.cpp
22
Storage.cpp
@@ -17,10 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Storage.hpp"
|
||||
#include <exception>
|
||||
#include <sstream>
|
||||
#include "Base64.tpp"
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -30,15 +30,13 @@ std::map<Storage::KeyHandle, Storage::PrivKey> Storage::privKeys{};
|
||||
std::map<Storage::KeyHandle, Storage::PubKey> Storage::pubKeys{};
|
||||
std::map<Storage::KeyHandle, Storage::KeyCount> Storage::keyCounts{};
|
||||
|
||||
void Storage::init(const string &dirPrefix)
|
||||
{
|
||||
void Storage::init(const string& dirPrefix) {
|
||||
Storage::filename = dirPrefix + "U2F_Priv_Keys.txt";
|
||||
ifstream file{ Storage::filename };
|
||||
string line;
|
||||
size_t lineNumber = 0;
|
||||
|
||||
while (getline(file, line))
|
||||
{
|
||||
while (getline(file, line)) {
|
||||
auto strLineNum = to_string(lineNumber);
|
||||
stringstream ss{ line };
|
||||
string keyHStr, appStr, privStr, pubStr, keyCStr;
|
||||
@@ -48,13 +46,15 @@ void Storage::init(const string &dirPrefix)
|
||||
throw runtime_error{ string{ "Invalid syntax of line " } + strLineNum };
|
||||
|
||||
char* endP = nullptr;
|
||||
Storage::KeyHandle keyH{ static_cast<Storage::KeyHandle>(strtoull(keyHStr.c_str(), &endP, 10)) };
|
||||
Storage::KeyHandle keyH{ static_cast<Storage::KeyHandle>(
|
||||
strtoull(keyHStr.c_str(), &endP, 10)) };
|
||||
|
||||
if (!endP)
|
||||
throw runtime_error{ "Invalid keyhandle format on line " + strLineNum };
|
||||
|
||||
endP = nullptr;
|
||||
Storage::KeyCount keyC{ static_cast<Storage::KeyCount>(strtoull(keyCStr.c_str(), &endP, 10)) };
|
||||
Storage::KeyCount keyC{ static_cast<Storage::KeyCount>(
|
||||
strtoull(keyCStr.c_str(), &endP, 10)) };
|
||||
|
||||
if (!endP)
|
||||
throw runtime_error{ "Invalid key count format on line " + strLineNum };
|
||||
@@ -77,12 +77,10 @@ void Storage::init(const string &dirPrefix)
|
||||
}
|
||||
}
|
||||
|
||||
void Storage::save()
|
||||
{
|
||||
void Storage::save() {
|
||||
ofstream file{ Storage::filename };
|
||||
|
||||
for (auto &keypair : Storage::appParams)
|
||||
{
|
||||
for (auto& keypair : Storage::appParams) {
|
||||
const auto& keyID = keypair.first;
|
||||
const auto& appParam = keypair.second;
|
||||
const auto& privKey = Storage::privKeys[keyID];
|
||||
|
||||
@@ -17,13 +17,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class Storage
|
||||
{
|
||||
class Storage {
|
||||
public:
|
||||
using KeyHandle = uint32_t;
|
||||
using KeyCount = uint32_t;
|
||||
|
||||
56
Streams.cpp
56
Streams.cpp
@@ -17,11 +17,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Streams.hpp"
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <cstdio>
|
||||
#include <fcntl.h>
|
||||
#include <iostream>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace std;
|
||||
@@ -31,8 +31,7 @@ FILE* initHTML(FILE *fPtr, const string &title);
|
||||
void closeHTML(FILE* fPtr);
|
||||
#endif
|
||||
|
||||
shared_ptr<int> getHostDescriptor()
|
||||
{
|
||||
shared_ptr<int> getHostDescriptor() {
|
||||
static shared_ptr<int> descriptor{};
|
||||
|
||||
descriptor.reset(new int{ open(HID_DEV, O_RDWR | O_NONBLOCK | O_APPEND) }, [](int* fd) {
|
||||
@@ -47,8 +46,7 @@ shared_ptr<int> getHostDescriptor()
|
||||
}
|
||||
|
||||
#ifdef DEBUG_STREAMS
|
||||
shared_ptr<FILE> getComHostStream()
|
||||
{
|
||||
shared_ptr<FILE> getComHostStream() {
|
||||
static shared_ptr<FILE> stream{ fopen(DEBUG_STREAMS "comhost.txt", "wb"), [](FILE* f) {
|
||||
clog << "Closing comhost stream" << endl;
|
||||
fclose(f);
|
||||
@@ -60,9 +58,10 @@ shared_ptr<FILE> getComHostStream()
|
||||
return stream;
|
||||
}
|
||||
|
||||
shared_ptr<FILE> getHostPacketStream()
|
||||
{
|
||||
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "hostpackets.html", "wb"), "Host Packets"), [](FILE *f){
|
||||
shared_ptr<FILE> getHostPacketStream() {
|
||||
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "hostpackets.html", "wb"),
|
||||
"Host Packets"),
|
||||
[](FILE* f) {
|
||||
clog << "Closing hostPackets stream" << endl;
|
||||
closeHTML(f);
|
||||
} };
|
||||
@@ -73,9 +72,10 @@ shared_ptr<FILE> getHostPacketStream()
|
||||
return stream;
|
||||
}
|
||||
|
||||
shared_ptr<FILE> getHostAPDUStream()
|
||||
{
|
||||
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "hostAPDU.html", "wb"), "Host APDU"), [](FILE *f){
|
||||
shared_ptr<FILE> getHostAPDUStream() {
|
||||
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "hostAPDU.html", "wb"),
|
||||
"Host APDU"),
|
||||
[](FILE* f) {
|
||||
clog << "Closing host APDU stream" << endl;
|
||||
closeHTML(f);
|
||||
} };
|
||||
@@ -86,8 +86,7 @@ shared_ptr<FILE> getHostAPDUStream()
|
||||
return stream;
|
||||
}
|
||||
|
||||
shared_ptr<FILE> getComDevStream()
|
||||
{
|
||||
shared_ptr<FILE> getComDevStream() {
|
||||
static shared_ptr<FILE> stream{ fopen(DEBUG_STREAMS "comdev.txt", "wb"), [](FILE* f) {
|
||||
clog << "Closing comdev stream" << endl;
|
||||
fclose(f);
|
||||
@@ -99,9 +98,10 @@ shared_ptr<FILE> getComDevStream()
|
||||
return stream;
|
||||
}
|
||||
|
||||
shared_ptr<FILE> getDevPacketStream()
|
||||
{
|
||||
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "devpackets.html", "wb"), "Dev Packets"), [](FILE *f){
|
||||
shared_ptr<FILE> getDevPacketStream() {
|
||||
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "devpackets.html", "wb"),
|
||||
"Dev Packets"),
|
||||
[](FILE* f) {
|
||||
clog << "Closing devPackets stream" << endl;
|
||||
closeHTML(f);
|
||||
} };
|
||||
@@ -112,9 +112,9 @@ shared_ptr<FILE> getDevPacketStream()
|
||||
return stream;
|
||||
}
|
||||
|
||||
shared_ptr<FILE> getDevAPDUStream()
|
||||
{
|
||||
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "devAPDU.html", "wb"), "Dev APDU"), [](FILE *f){
|
||||
shared_ptr<FILE> getDevAPDUStream() {
|
||||
static shared_ptr<FILE> stream{ initHTML(fopen(DEBUG_STREAMS "devAPDU.html", "wb"), "Dev APDU"),
|
||||
[](FILE* f) {
|
||||
clog << "Closing dev APDU stream" << endl;
|
||||
closeHTML(f);
|
||||
} };
|
||||
@@ -125,9 +125,9 @@ shared_ptr<FILE> getDevAPDUStream()
|
||||
return stream;
|
||||
}
|
||||
|
||||
FILE* initHTML(FILE *fPtr, const string &title)
|
||||
{
|
||||
fprintf(fPtr, "<html>\n"
|
||||
FILE* initHTML(FILE* fPtr, const string& title) {
|
||||
fprintf(fPtr,
|
||||
"<html>\n"
|
||||
"\t<head>\n"
|
||||
"\t\t<title>%s</title>\n"
|
||||
"\t\t<style>\n"
|
||||
@@ -164,13 +164,13 @@ FILE* initHTML(FILE *fPtr, const string &title)
|
||||
"\t\t</style>\n"
|
||||
"\t</head>\n"
|
||||
"\n"
|
||||
"\t<body>", title.c_str());
|
||||
"\t<body>",
|
||||
title.c_str());
|
||||
|
||||
return fPtr;
|
||||
}
|
||||
|
||||
void closeHTML(FILE *fPtr)
|
||||
{
|
||||
void closeHTML(FILE* fPtr) {
|
||||
fprintf(fPtr, "\t</body>\n"
|
||||
"</html>");
|
||||
fclose(fPtr);
|
||||
|
||||
@@ -17,9 +17,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "Architecture.hpp"
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include "Architecture.hpp"
|
||||
|
||||
std::shared_ptr<int> getHostDescriptor();
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Architecture.hpp"
|
||||
#include <iostream>
|
||||
#include "Storage.hpp"
|
||||
#include "Controller.hpp"
|
||||
#include "LED.hpp"
|
||||
#include "Storage.hpp"
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -31,13 +31,10 @@ void signalCallback(int signum);
|
||||
volatile bool contProc = true;
|
||||
|
||||
bool initialiseLights(const string& prog) {
|
||||
try
|
||||
{
|
||||
try {
|
||||
disableACTTrigger(true);
|
||||
enableACTLED(false);
|
||||
}
|
||||
catch (runtime_error &e)
|
||||
{
|
||||
} catch (runtime_error& e) {
|
||||
cerr << e.what() << endl;
|
||||
|
||||
if (getuid() != 0)
|
||||
@@ -49,20 +46,15 @@ bool initialiseLights(const string& prog) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int handleTransactions(const string& prog, const string& privKeyDir)
|
||||
{
|
||||
int handleTransactions(const string& prog, const string& privKeyDir) {
|
||||
signal(SIGINT, signalCallback);
|
||||
Storage::init(privKeyDir);
|
||||
Controller ch{ 0xF1D00000 };
|
||||
|
||||
while (contProc)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (contProc) {
|
||||
try {
|
||||
ch.handleTransaction();
|
||||
}
|
||||
catch (const runtime_error &e)
|
||||
{
|
||||
} catch (const runtime_error& e) {
|
||||
cerr << e.what() << endl;
|
||||
|
||||
if (getuid() != 0)
|
||||
@@ -79,13 +71,10 @@ int handleTransactions(const string& prog, const string& privKeyDir)
|
||||
}
|
||||
|
||||
bool deinitialiseLights(const string& prog) {
|
||||
try
|
||||
{
|
||||
try {
|
||||
disableACTTrigger(false);
|
||||
enableACTLED(true);
|
||||
}
|
||||
catch (runtime_error &e)
|
||||
{
|
||||
} catch (runtime_error& e) {
|
||||
cerr << e.what() << endl;
|
||||
|
||||
if (getuid() != 0)
|
||||
@@ -97,8 +86,7 @@ bool deinitialiseLights(const string& prog) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void signalCallback([[maybe_unused]] int signum)
|
||||
{
|
||||
void signalCallback([[maybe_unused]] int signum) {
|
||||
contProc = false;
|
||||
clog << "\nClosing" << endl;
|
||||
}
|
||||
|
||||
@@ -24,4 +24,3 @@ extern volatile bool contProc;
|
||||
bool initialiseLights(const std::string& prog);
|
||||
bool deinitialiseLights(const std::string& prog);
|
||||
int handleTransactions(const std::string& prog, const std::string& privKeyDir);
|
||||
|
||||
|
||||
@@ -17,18 +17,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "U2FMessage.hpp"
|
||||
#include "IO.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "Streams.hpp"
|
||||
#include "u2f.hpp"
|
||||
#include "IO.hpp"
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
|
||||
shared_ptr<U2FMessage> U2FMessage::readNonBlock()
|
||||
{
|
||||
shared_ptr<U2FMessage> U2FMessage::readNonBlock() {
|
||||
const static size_t startSeq = (size_t)-1ull;
|
||||
static size_t currSeq = startSeq;
|
||||
static uint16_t messageSize;
|
||||
@@ -38,16 +37,14 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
|
||||
|
||||
shared_ptr<Packet> p{};
|
||||
|
||||
if (currSeq == startSeq)
|
||||
{
|
||||
if (currSeq == startSeq) {
|
||||
cid = 0;
|
||||
cmd = 0;
|
||||
messageSize = 0;
|
||||
dataBytes = {};
|
||||
|
||||
shared_ptr<InitPacket> initPack{};
|
||||
do
|
||||
{
|
||||
do {
|
||||
p = Packet::getPacket();
|
||||
|
||||
if (!p)
|
||||
@@ -62,16 +59,19 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
|
||||
} while (!initPack); // Spurious cont. packet - spec states ignore
|
||||
|
||||
messageSize = ((static_cast<uint16_t>(initPack->bcnth) << 8u) + initPack->bcntl);
|
||||
const uint16_t copyByteCount = min(static_cast<uint16_t>(initPack->data.size()), messageSize);
|
||||
const uint16_t copyByteCount =
|
||||
min(static_cast<uint16_t>(initPack->data.size()), messageSize);
|
||||
|
||||
cid = initPack->cid;
|
||||
cmd = initPack->cmd;
|
||||
|
||||
copy(initPack->data.begin(), initPack->data.begin() + copyByteCount, back_inserter(dataBytes));
|
||||
copy(initPack->data.begin(), initPack->data.begin() + copyByteCount,
|
||||
back_inserter(dataBytes));
|
||||
currSeq = 0;
|
||||
}
|
||||
|
||||
while (messageSize > dataBytes.size() && static_cast<bool>(p = Packet::getPacket())) //While there is a packet
|
||||
while (messageSize > dataBytes.size() &&
|
||||
static_cast<bool>(p = Packet::getPacket())) // While there is a packet
|
||||
{
|
||||
auto contPack = dynamic_pointer_cast<ContPacket>(p);
|
||||
|
||||
@@ -87,15 +87,15 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
|
||||
if (contPack->cid != cid) // Cont. packet of different CID
|
||||
{
|
||||
#ifdef DEBUG_MSGS
|
||||
cerr << "Invalid CID: was handling channel 0x" << hex << cid << " and received packet from channel 0x" << contPack->cid << dec << endl;
|
||||
cerr << "Invalid CID: was handling channel 0x" << hex << cid
|
||||
<< " and received packet from channel 0x" << contPack->cid << dec << endl;
|
||||
#endif
|
||||
U2FMessage::error(contPack->cid, ERR_CHANNEL_BUSY);
|
||||
currSeq = startSeq;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (contPack->seq != currSeq)
|
||||
{
|
||||
if (contPack->seq != currSeq) {
|
||||
#ifdef DEBUG_MSGS
|
||||
cerr << "Invalid packet seq. value" << endl;
|
||||
#endif
|
||||
@@ -105,15 +105,18 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
|
||||
}
|
||||
|
||||
const uint16_t remainingBytes = messageSize - dataBytes.size();
|
||||
const uint16_t copyBytes = min(static_cast<uint16_t>(contPack->data.size()), remainingBytes);
|
||||
const uint16_t copyBytes =
|
||||
min(static_cast<uint16_t>(contPack->data.size()), remainingBytes);
|
||||
|
||||
dataBytes.insert(dataBytes.end(), contPack->data.begin(), contPack->data.begin() + copyBytes);
|
||||
dataBytes.insert(dataBytes.end(), contPack->data.begin(),
|
||||
contPack->data.begin() + copyBytes);
|
||||
currSeq++;
|
||||
}
|
||||
|
||||
if (messageSize != dataBytes.size()) {
|
||||
#ifdef DEBUG_MSGS
|
||||
cerr << "Invalid message size: " << messageSize << " when received " << dataBytes.size() << endl;
|
||||
cerr << "Invalid message size: " << messageSize << " when received " << dataBytes.size()
|
||||
<< endl;
|
||||
#endif
|
||||
return {};
|
||||
}
|
||||
@@ -125,8 +128,7 @@ shared_ptr<U2FMessage> U2FMessage::readNonBlock()
|
||||
return message;
|
||||
}
|
||||
|
||||
void U2FMessage::write()
|
||||
{
|
||||
void U2FMessage::write() {
|
||||
const uint16_t bytesToWrite = this->data.size();
|
||||
uint16_t bytesWritten = 0;
|
||||
|
||||
@@ -141,7 +143,8 @@ void U2FMessage::write()
|
||||
p.bcntl = bcntl;
|
||||
|
||||
{
|
||||
uint16_t initialByteCount = min(static_cast<uint16_t>(p.data.size()), static_cast<uint16_t>(bytesToWrite - bytesWritten));
|
||||
uint16_t initialByteCount = min(static_cast<uint16_t>(p.data.size()),
|
||||
static_cast<uint16_t>(bytesToWrite - bytesWritten));
|
||||
copy(data.begin(), data.begin() + initialByteCount, p.data.begin());
|
||||
bytesWritten += initialByteCount;
|
||||
}
|
||||
@@ -151,20 +154,20 @@ void U2FMessage::write()
|
||||
|
||||
uint8_t seq = 0;
|
||||
|
||||
while (bytesWritten != bytesToWrite)
|
||||
{
|
||||
while (bytesWritten != bytesToWrite) {
|
||||
ContPacket p{};
|
||||
p.cid = cid;
|
||||
p.seq = seq;
|
||||
uint16_t newByteCount = min(static_cast<uint16_t>(p.data.size()), static_cast<uint16_t>(bytesToWrite - bytesWritten));
|
||||
copy(data.begin() + bytesWritten, data.begin() + bytesWritten + newByteCount, p.data.begin());
|
||||
uint16_t newByteCount = min(static_cast<uint16_t>(p.data.size()),
|
||||
static_cast<uint16_t>(bytesToWrite - bytesWritten));
|
||||
copy(data.begin() + bytesWritten, data.begin() + bytesWritten + newByteCount,
|
||||
p.data.begin());
|
||||
p.writePacket();
|
||||
seq++;
|
||||
bytesWritten += newByteCount;
|
||||
}
|
||||
|
||||
if (cmd == U2FHID_MSG)
|
||||
{
|
||||
if (cmd == U2FHID_MSG) {
|
||||
#ifdef DEBUG_STREAMS
|
||||
auto dAS = getDevAPDUStream().get();
|
||||
|
||||
@@ -187,22 +190,21 @@ void U2FMessage::write()
|
||||
err |= data.back();
|
||||
|
||||
#ifdef DEBUG_STREAMS
|
||||
fprintf(dAS, "</td>\n"
|
||||
fprintf(dAS,
|
||||
"</td>\n"
|
||||
"\t\t\t\t\t<td>0x%04X</td>\n"
|
||||
"\t\t\t\t</tr>\n"
|
||||
"\t\t\t</tbody>\n"
|
||||
"\t\t</table>\n"
|
||||
"\t\t<br />", err);
|
||||
"\t\t<br />",
|
||||
err);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
U2FMessage::U2FMessage(const uint32_t nCID, const uint8_t nCMD)
|
||||
: cid{ nCID }, cmd{ nCMD }
|
||||
{}
|
||||
U2FMessage::U2FMessage(const uint32_t nCID, const uint8_t nCMD) : cid{ nCID }, cmd{ nCMD } {}
|
||||
|
||||
void U2FMessage::error(const uint32_t tCID, const uint8_t tErr)
|
||||
{
|
||||
void U2FMessage::error(const uint32_t tCID, const uint8_t tErr) {
|
||||
U2FMessage msg{};
|
||||
msg.cid = tCID;
|
||||
msg.cmd = U2FHID_ERROR;
|
||||
|
||||
@@ -18,12 +18,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
struct U2FMessage
|
||||
{
|
||||
struct U2FMessage {
|
||||
public:
|
||||
uint32_t cid;
|
||||
uint8_t cmd;
|
||||
|
||||
@@ -17,28 +17,24 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "U2F_Authenticate_APDU.hpp"
|
||||
#include "Field.hpp"
|
||||
#include "U2FMessage.hpp"
|
||||
#include "u2f.hpp"
|
||||
#include "Field.tpp"
|
||||
#include "APDU.hpp"
|
||||
#include <iostream>
|
||||
#include "Field.hpp"
|
||||
#include "Field.tpp"
|
||||
#include "Signature.hpp"
|
||||
#include "U2FMessage.hpp"
|
||||
#include "micro-ecc/uECC.h"
|
||||
#include "u2f.hpp"
|
||||
#include <iostream>
|
||||
#include <mbedtls/sha256.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
U2F_Authenticate_APDU::U2F_Authenticate_APDU(const U2F_Msg_CMD& msg, const vector<uint8_t>& data)
|
||||
: U2F_Msg_CMD{ msg }
|
||||
{
|
||||
if (p2 != 0)
|
||||
{
|
||||
: U2F_Msg_CMD{ msg } {
|
||||
if (p2 != 0) {
|
||||
// Invalid U2F (APDU) parameter detected
|
||||
throw APDU_STATUS::SW_CONDITIONS_NOT_SATISFIED;
|
||||
}
|
||||
else if (data.size() < 66)
|
||||
{
|
||||
} else if (data.size() < 66) {
|
||||
// Invalid authentication request
|
||||
throw APDU_STATUS::SW_WRONG_LENGTH;
|
||||
}
|
||||
@@ -51,10 +47,8 @@ U2F_Authenticate_APDU::U2F_Authenticate_APDU(const U2F_Msg_CMD &msg, const vecto
|
||||
copy(data.begin() + 65, data.begin() + 65 + keyHLen, back_inserter(keyH));
|
||||
}
|
||||
|
||||
void U2F_Authenticate_APDU::respond(const uint32_t channelID) const
|
||||
{
|
||||
if (keyH.size() != sizeof(Storage::KeyHandle))
|
||||
{
|
||||
void U2F_Authenticate_APDU::respond(const uint32_t channelID) const {
|
||||
if (keyH.size() != sizeof(Storage::KeyHandle)) {
|
||||
// Respond with error code - key handle is of wrong size
|
||||
cerr << "Invalid key handle length" << endl;
|
||||
this->error(channelID, APDU_STATUS::SW_WRONG_DATA);
|
||||
@@ -63,8 +57,7 @@ void U2F_Authenticate_APDU::respond(const uint32_t channelID) const
|
||||
|
||||
auto keyHB = *reinterpret_cast<const Storage::KeyHandle*>(keyH.data());
|
||||
|
||||
if (Storage::appParams.find(keyHB) == Storage::appParams.end())
|
||||
{
|
||||
if (Storage::appParams.find(keyHB) == Storage::appParams.end()) {
|
||||
// Respond with error code - key handle doesn't exist in storage
|
||||
cerr << "Invalid key handle" << endl;
|
||||
this->error(channelID, SW_WRONG_DATA);
|
||||
@@ -80,8 +73,7 @@ void U2F_Authenticate_APDU::respond(const uint32_t channelID) const
|
||||
auto& response = msg.data;
|
||||
APDU_STATUS statusCode = APDU_STATUS::SW_NO_ERROR;
|
||||
|
||||
switch (p1)
|
||||
{
|
||||
switch (p1) {
|
||||
case ControlCode::CheckOnly:
|
||||
if (appMatches)
|
||||
statusCode = APDU_STATUS::SW_CONDITIONS_NOT_SATISFIED;
|
||||
@@ -117,7 +109,8 @@ void U2F_Authenticate_APDU::respond(const uint32_t channelID) const
|
||||
mbedtls_sha256_init(&shaContext);
|
||||
mbedtls_sha256_starts(&shaContext, 0);
|
||||
|
||||
mbedtls_sha256_update(&shaContext, reinterpret_cast<const uint8_t *>(appParam.data()), sizeof(appParam));
|
||||
mbedtls_sha256_update(&shaContext, reinterpret_cast<const uint8_t*>(appParam.data()),
|
||||
sizeof(appParam));
|
||||
uint8_t userPresence{ 1u };
|
||||
mbedtls_sha256_update(&shaContext, &userPresence, 1);
|
||||
const auto beCounter = beEncode(keyCount);
|
||||
|
||||
@@ -17,11 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "U2F_Msg_CMD.hpp"
|
||||
#include "Storage.hpp"
|
||||
#include "U2F_Msg_CMD.hpp"
|
||||
|
||||
struct U2F_Authenticate_APDU : U2F_Msg_CMD
|
||||
{
|
||||
struct U2F_Authenticate_APDU : U2F_Msg_CMD {
|
||||
uint8_t controlByte;
|
||||
std::array<uint8_t, 32> challengeP;
|
||||
Storage::AppParam appParam;
|
||||
@@ -32,8 +31,7 @@ struct U2F_Authenticate_APDU : U2F_Msg_CMD
|
||||
|
||||
virtual void respond(const uint32_t channelID) const override;
|
||||
|
||||
enum ControlCode
|
||||
{
|
||||
enum ControlCode {
|
||||
CheckOnly = 0x07,
|
||||
EnforcePresenceSign = 0x03,
|
||||
DontEnforcePresenceSign = 0x08
|
||||
|
||||
17
U2F_CMD.cpp
17
U2F_CMD.cpp
@@ -17,19 +17,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "U2F_CMD.hpp"
|
||||
#include "u2f.hpp"
|
||||
#include "U2F_Msg_CMD.hpp"
|
||||
#include "U2F_Init_CMD.hpp"
|
||||
#include "U2F_Msg_CMD.hpp"
|
||||
#include "U2F_Ping_CMD.hpp"
|
||||
#include "u2f.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
shared_ptr<U2F_CMD> U2F_CMD::get(const shared_ptr<U2FMessage> uMsg)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (uMsg->cmd)
|
||||
{
|
||||
shared_ptr<U2F_CMD> U2F_CMD::get(const shared_ptr<U2FMessage> uMsg) {
|
||||
try {
|
||||
switch (uMsg->cmd) {
|
||||
case U2FHID_PING:
|
||||
return make_shared<U2F_Ping_CMD>(uMsg);
|
||||
case U2FHID_MSG:
|
||||
@@ -40,9 +37,7 @@ shared_ptr<U2F_CMD> U2F_CMD::get(const shared_ptr<U2FMessage> uMsg)
|
||||
U2FMessage::error(uMsg->cid, ERR_INVALID_CMD);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
catch (runtime_error& ignored)
|
||||
{
|
||||
} catch (runtime_error& ignored) {
|
||||
U2FMessage::error(uMsg->cid, ERR_OTHER);
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -17,11 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include "U2FMessage.hpp"
|
||||
#include <memory>
|
||||
|
||||
struct U2F_CMD
|
||||
{
|
||||
struct U2F_CMD {
|
||||
protected:
|
||||
U2F_CMD() = default;
|
||||
|
||||
|
||||
@@ -17,23 +17,19 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "U2F_Init_CMD.hpp"
|
||||
#include <stdexcept>
|
||||
#include "u2f.hpp"
|
||||
#include "Field.hpp"
|
||||
#include "u2f.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
|
||||
U2F_Init_CMD::U2F_Init_CMD(const shared_ptr<U2FMessage> uMsg)
|
||||
{
|
||||
U2F_Init_CMD::U2F_Init_CMD(const shared_ptr<U2FMessage> uMsg) {
|
||||
if (uMsg->cmd != U2FHID_INIT)
|
||||
throw runtime_error{ "Failed to get U2F Init message" };
|
||||
else if (uMsg->cid != CID_BROADCAST)
|
||||
{
|
||||
else if (uMsg->cid != CID_BROADCAST) {
|
||||
U2FMessage::error(uMsg->cid, ERR_OTHER);
|
||||
throw runtime_error{ "Invalid CID for init command" };
|
||||
}
|
||||
else if (uMsg->data.size() != INIT_NONCE_SIZE)
|
||||
{
|
||||
} else if (uMsg->data.size() != INIT_NONCE_SIZE) {
|
||||
U2FMessage::error(uMsg->cid, ERR_INVALID_LEN);
|
||||
throw runtime_error{ "Init nonce is incorrect size" };
|
||||
}
|
||||
@@ -41,8 +37,7 @@ U2F_Init_CMD::U2F_Init_CMD(const shared_ptr<U2FMessage> uMsg)
|
||||
this->nonce = *reinterpret_cast<const uint64_t*>(uMsg->data.data());
|
||||
}
|
||||
|
||||
void U2F_Init_CMD::respond(const uint32_t channelID) const
|
||||
{
|
||||
void U2F_Init_CMD::respond(const uint32_t channelID) const {
|
||||
U2FMessage msg{};
|
||||
msg.cid = CID_BROADCAST;
|
||||
msg.cmd = U2FHID_INIT;
|
||||
|
||||
@@ -17,13 +17,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "U2FMessage.hpp"
|
||||
#include "U2F_CMD.hpp"
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include "U2F_CMD.hpp"
|
||||
#include "U2FMessage.hpp"
|
||||
|
||||
struct U2F_Init_CMD : U2F_CMD
|
||||
{
|
||||
struct U2F_Init_CMD : U2F_CMD {
|
||||
uint64_t nonce;
|
||||
|
||||
public:
|
||||
|
||||
@@ -18,26 +18,22 @@ 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)
|
||||
{
|
||||
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:
|
||||
@@ -55,17 +51,14 @@ uint32_t U2F_Msg_CMD::getLe(const uint32_t byteCount, vector<uint8_t> bytes)
|
||||
default:
|
||||
throw runtime_error{ "Too much data for command" };
|
||||
}
|
||||
}
|
||||
else
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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" };
|
||||
}
|
||||
@@ -75,8 +68,7 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
|
||||
|
||||
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" };
|
||||
}
|
||||
@@ -89,10 +81,8 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
|
||||
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" };
|
||||
}
|
||||
@@ -101,36 +91,26 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
|
||||
{
|
||||
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,7 +121,8 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
|
||||
#ifdef DEBUG_STREAMS
|
||||
auto hAS = getHostAPDUStream().get();
|
||||
|
||||
fprintf(hAS, "<table>\n"
|
||||
fprintf(hAS,
|
||||
"<table>\n"
|
||||
"\t\t\t<thead>\n"
|
||||
"\t\t\t\t<tr>\n"
|
||||
"\t\t\t\t\t<th>CLA</th>\n"
|
||||
@@ -160,23 +141,24 @@ shared_ptr<U2F_Msg_CMD> U2F_Msg_CMD::generate(const shared_ptr<U2FMessage> uMsg)
|
||||
"\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);
|
||||
"\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"
|
||||
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);
|
||||
"\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 shared_ptr<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 },
|
||||
const map<uint8_t, bool> U2F_Msg_CMD::usesData = { { U2F_REG, true },
|
||||
{ U2F_AUTH, true },
|
||||
{ U2F_VER, false }
|
||||
};
|
||||
{ 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));
|
||||
}
|
||||
|
||||
@@ -20,11 +20,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include "U2F_CMD.hpp"
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
struct U2F_Msg_CMD : U2F_CMD
|
||||
{
|
||||
struct U2F_Msg_CMD : U2F_CMD {
|
||||
uint8_t cla;
|
||||
uint8_t ins;
|
||||
uint8_t p1;
|
||||
@@ -43,4 +42,3 @@ struct U2F_Msg_CMD : U2F_CMD
|
||||
static void error(const uint32_t channelID, const uint16_t errCode);
|
||||
void respond(const uint32_t channelID) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -21,15 +21,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using namespace std;
|
||||
|
||||
U2F_Ping_CMD::U2F_Ping_CMD(const shared_ptr<U2FMessage> uMsg)
|
||||
: nonce{ uMsg->data }
|
||||
{
|
||||
U2F_Ping_CMD::U2F_Ping_CMD(const shared_ptr<U2FMessage> uMsg) : nonce{ uMsg->data } {
|
||||
if (uMsg->cmd != U2FHID_PING)
|
||||
throw runtime_error{ "Failed to get U2F ping message" };
|
||||
}
|
||||
|
||||
void U2F_Ping_CMD::respond(const uint32_t channelID) const
|
||||
{
|
||||
void U2F_Ping_CMD::respond(const uint32_t channelID) const {
|
||||
U2FMessage msg{};
|
||||
msg.cid = channelID;
|
||||
msg.cmd = U2FHID_PING;
|
||||
|
||||
@@ -17,13 +17,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "U2FMessage.hpp"
|
||||
#include "U2F_CMD.hpp"
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include "U2F_CMD.hpp"
|
||||
#include "U2FMessage.hpp"
|
||||
|
||||
struct U2F_Ping_CMD : U2F_CMD
|
||||
{
|
||||
struct U2F_Ping_CMD : U2F_CMD {
|
||||
std::vector<uint8_t> nonce;
|
||||
|
||||
public:
|
||||
|
||||
@@ -17,28 +17,25 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "U2F_Register_APDU.hpp"
|
||||
#include <exception>
|
||||
#include <cstring>
|
||||
#include "micro-ecc/uECC.h"
|
||||
#include "Certificates.hpp"
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <iostream>
|
||||
#include "APDU.hpp"
|
||||
#include "U2FMessage.hpp"
|
||||
#include "u2f.hpp"
|
||||
#include "Certificates.hpp"
|
||||
#include "Signature.hpp"
|
||||
#include "U2FMessage.hpp"
|
||||
#include "micro-ecc/uECC.h"
|
||||
#include "u2f.hpp"
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <mbedtls/sha256.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
U2F_Register_APDU::U2F_Register_APDU(const U2F_Msg_CMD& msg, const vector<uint8_t>& data)
|
||||
: U2F_Msg_CMD{ msg }
|
||||
{
|
||||
if (data.size() != 64)
|
||||
{
|
||||
: U2F_Msg_CMD{ msg } {
|
||||
if (data.size() != 64) {
|
||||
// Incorrect registration size
|
||||
throw APDU_STATUS::SW_WRONG_LENGTH;
|
||||
}
|
||||
else if ((p1 != 0x00 && p1 != 0x03) || p2 != 0x00) //According to spec, 0x03 not allowed here
|
||||
} else if ((p1 != 0x00 && p1 != 0x03) || p2 != 0x00) // According to spec, 0x03 not allowed here
|
||||
// However, browsers seem to do it, so...
|
||||
{
|
||||
// Invalid U2F Message (APDU) parameters detected
|
||||
@@ -64,8 +61,7 @@ U2F_Register_APDU::U2F_Register_APDU(const U2F_Msg_CMD &msg, const vector<uint8_
|
||||
Storage::keyCounts[this->keyH] = 0;
|
||||
}
|
||||
|
||||
void U2F_Register_APDU::respond(const uint32_t channelID) const
|
||||
{
|
||||
void U2F_Register_APDU::respond(const uint32_t channelID) const {
|
||||
U2FMessage m{};
|
||||
m.cid = channelID;
|
||||
m.cmd = U2FHID_MSG;
|
||||
@@ -94,13 +90,18 @@ void U2F_Register_APDU::respond(const uint32_t channelID) const
|
||||
uint8_t byteReserved = 0;
|
||||
mbedtls_sha256_update(&shaContext, reinterpret_cast<unsigned char*>(&byteReserved), 1);
|
||||
|
||||
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(appParam.data()), appParam.size());
|
||||
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(appParam.data()),
|
||||
appParam.size());
|
||||
|
||||
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(challengeP.data()), challengeP.size());
|
||||
mbedtls_sha256_update(&shaContext,
|
||||
reinterpret_cast<const unsigned char*>(challengeP.data()),
|
||||
challengeP.size());
|
||||
|
||||
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(&keyH), sizeof(keyH));
|
||||
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(&keyH),
|
||||
sizeof(keyH));
|
||||
|
||||
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(pubKey.data()), pubKey.size());
|
||||
mbedtls_sha256_update(&shaContext, reinterpret_cast<const unsigned char*>(pubKey.data()),
|
||||
pubKey.size());
|
||||
|
||||
mbedtls_sha256_finish(&shaContext, digest.data());
|
||||
mbedtls_sha256_free(&shaContext);
|
||||
|
||||
@@ -17,11 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "U2F_Msg_CMD.hpp"
|
||||
#include "Storage.hpp"
|
||||
#include "U2F_Msg_CMD.hpp"
|
||||
|
||||
struct U2F_Register_APDU : U2F_Msg_CMD
|
||||
{
|
||||
struct U2F_Register_APDU : U2F_Msg_CMD {
|
||||
std::array<uint8_t, 32> challengeP;
|
||||
Storage::AppParam appP;
|
||||
Storage::KeyHandle keyH;
|
||||
@@ -31,4 +30,3 @@ struct U2F_Register_APDU : U2F_Msg_CMD
|
||||
|
||||
void respond(const uint32_t channelID) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -17,16 +17,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "U2F_Version_APDU.hpp"
|
||||
#include <iostream>
|
||||
#include "APDU.hpp"
|
||||
#include "Field.hpp"
|
||||
#include "U2FMessage.hpp"
|
||||
#include "u2f.hpp"
|
||||
#include "Field.hpp"
|
||||
#include "APDU.hpp"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
U2F_Version_APDU::U2F_Version_APDU(const U2F_Msg_CMD &msg, const std::vector<uint8_t> &data)
|
||||
{
|
||||
U2F_Version_APDU::U2F_Version_APDU(const U2F_Msg_CMD& msg, const std::vector<uint8_t>& data) {
|
||||
// Don't actually respond yet unless invalid
|
||||
if (msg.p1 != 0 || msg.p2 != 0)
|
||||
throw APDU_STATUS::SW_INS_NOT_SUPPORTED;
|
||||
@@ -34,8 +33,7 @@ U2F_Version_APDU::U2F_Version_APDU(const U2F_Msg_CMD &msg, const std::vector<uin
|
||||
throw APDU_STATUS::SW_WRONG_LENGTH;
|
||||
}
|
||||
|
||||
void U2F_Version_APDU::respond(const uint32_t channelID) const
|
||||
{
|
||||
void U2F_Version_APDU::respond(const uint32_t channelID) const {
|
||||
char ver[]{ 'U', '2', 'F', '_', 'V', '2' };
|
||||
U2FMessage m{};
|
||||
|
||||
|
||||
@@ -19,8 +19,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#pragma once
|
||||
#include "U2F_Msg_CMD.hpp"
|
||||
|
||||
struct U2F_Version_APDU : U2F_Msg_CMD
|
||||
{
|
||||
struct U2F_Version_APDU : U2F_Msg_CMD {
|
||||
public:
|
||||
U2F_Version_APDU(const U2F_Msg_CMD& msg, const std::vector<uint8_t>& data);
|
||||
void respond(const uint32_t channelID) const override;
|
||||
|
||||
15
main.cpp
15
main.cpp
@@ -1,17 +1,15 @@
|
||||
#include "U2FDevice.hpp"
|
||||
#include "Architecture.hpp"
|
||||
#include "U2FDevice.hpp"
|
||||
#include <execinfo.h>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef DEBUG_MSGS
|
||||
// Courtesy StackOverflow answer https://stackoverflow.com/a/3356421
|
||||
void terminateHandler()
|
||||
{
|
||||
void terminateHandler() {
|
||||
void* trace_elems[20];
|
||||
int trace_elem_count(backtrace(trace_elems, 20));
|
||||
char** stack_syms(backtrace_symbols(trace_elems, trace_elem_count));
|
||||
for (int i = 0; i < trace_elem_count; ++i)
|
||||
{
|
||||
for (int i = 0; i < trace_elem_count; ++i) {
|
||||
std::cout << stack_syms[i] << "\n";
|
||||
}
|
||||
free(stack_syms);
|
||||
@@ -26,13 +24,10 @@ int main(int argc, char **argv) {
|
||||
#endif
|
||||
int retCode = handleTransactions(argv[0], argc == 2 ? argv[1] : STORAGE_PREFIX);
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
initialiseLights(argv[0]);
|
||||
deinitialiseLights(argv[0]);
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
} catch (std::exception& e) {
|
||||
std::cerr << "Exception in code: " << e.what() << std::endl;
|
||||
throw;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user