diff --git a/APDU.hpp b/APDU.hpp index 1f7e2b7..30c785e 100644 --- a/APDU.hpp +++ b/APDU.hpp @@ -18,19 +18,13 @@ along with this program. If not, see . #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 -{ - SW_NO_ERROR = 0x9000, - SW_WRONG_LENGTH = 0x6700, +enum APDU_STATUS : uint16_t { + SW_NO_ERROR = 0x9000, + SW_WRONG_LENGTH = 0x6700, SW_CONDITIONS_NOT_SATISFIED = 0x6985, - SW_WRONG_DATA = 0x6A80, - SW_INS_NOT_SUPPORTED = 0x6D00, - SW_COMMAND_NOT_ALLOWED = 0x6E00, + SW_WRONG_DATA = 0x6A80, + SW_INS_NOT_SUPPORTED = 0x6D00, + SW_COMMAND_NOT_ALLOWED = 0x6E00, }; diff --git a/Architecture.hpp b/Architecture.hpp index 3dff097..198fe48 100644 --- a/Architecture.hpp +++ b/Architecture.hpp @@ -23,15 +23,15 @@ along with this program. If not, see . #define ARCHITECTURE ARCH_RASPBERRY_PI #if ARCHITECTURE == ARCH_RASPBERRY_PI - #define STORAGE_PREFIX "/usr/share/" - #define HID_DEV "/dev/hidg0" - #define DEBUG_STREAMS "/tmp/" +# define STORAGE_PREFIX "/usr/share/" +# define HID_DEV "/dev/hidg0" +# define DEBUG_STREAMS "/tmp/" // #define DEBUG_MSGS - #define LEDS +# define LEDS #elif ARCHITECTURE == ARCH_ANDROID - #define STORAGE_PREFIX "/sdcard/U2F/" - #define HID_DEV "/dev/hidg2" - #define DEBUG_STREAMS "/data/local/tmp/" +# define STORAGE_PREFIX "/sdcard/U2F/" +# define HID_DEV "/dev/hidg2" +# define DEBUG_STREAMS "/data/local/tmp/" // #define DEBUG_MSGS #endif diff --git a/Base64.hpp b/Base64.hpp index b26818d..ceccdfd 100644 --- a/Base64.hpp +++ b/Base64.hpp @@ -19,19 +19,21 @@ along with this program. If not, see . #pragma once template -void b64encode(const InContainer &iContainer, OutContainer &oContainer); +void b64encode(const InContainer& iContainer, OutContainer& oContainer); template -void b64decode(const InContainer &container, OutContainer &oContainer); +void b64decode(const InContainer& container, OutContainer& oContainer); template -void b64encode(const InContainer &iContainer, std::array &oArr); +void b64encode(const InContainer& iContainer, std::array& oArr); template -void b64decode(const InContainer &iContainer, std::array &oArr); +void b64decode(const InContainer& iContainer, std::array& oArr); template -void b64encode(const InContainerIter beginIter, const InContainerIter endIter, OutContainerIter oBeginIter); +void b64encode(const InContainerIter beginIter, const InContainerIter endIter, + OutContainerIter oBeginIter); template -void b64decode(const InContainerIter beginIter, const InContainerIter endIter, OutContainerIter oBeginIter); +void b64decode(const InContainerIter beginIter, const InContainerIter endIter, + OutContainerIter oBeginIter); diff --git a/Certificates.cpp b/Certificates.cpp index 116eaa7..dd2d95d 100644 --- a/Certificates.cpp +++ b/Certificates.cpp @@ -15,76 +15,60 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ - + #include "Certificates.hpp" -//You may not actually want to use these values - +// You may not actually want to use these values - // having been shared publicly, these may be vulnerable to exploits. // However, generating your own attestation certificate makes your device // uniquely identifiable across platforms / services, etc. // 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 }; diff --git a/Channel.cpp b/Channel.cpp index 3d35749..813aae4 100644 --- a/Channel.cpp +++ b/Channel.cpp @@ -17,24 +17,23 @@ along with this program. If not, see . */ #include "Channel.hpp" -#include -#include "u2f.hpp" #include "U2F_CMD.hpp" +#include "u2f.hpp" #include +#include 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 uMsg) -{ +void Channel::handle(const shared_ptr 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 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; } diff --git a/Channel.hpp b/Channel.hpp index 61c454f..4e8f207 100644 --- a/Channel.hpp +++ b/Channel.hpp @@ -17,34 +17,25 @@ along with this program. If not, see . */ #pragma once +#include "U2FMessage.hpp" #include #include -#include "U2FMessage.hpp" -enum class ChannelInitState -{ - Unitialised, - Initialised -}; - -enum class ChannelLockedState -{ - Locked, - Unlocked -}; - -class Channel -{ - protected: - uint32_t cid; - ChannelInitState initState; - ChannelLockedState lockedState; - - public: - Channel(const uint32_t channelID); - void handle(const std::shared_ptr uMsg); - - uint32_t getCID() const; - void init(const ChannelInitState newInitState); - void lock(const ChannelLockedState newLockedState); +enum class ChannelInitState { Unitialised, Initialised }; + +enum class ChannelLockedState { Locked, Unlocked }; + +class Channel { +protected: + uint32_t cid; + ChannelInitState initState; + ChannelLockedState lockedState; + +public: + Channel(const uint32_t channelID); + void handle(const std::shared_ptr uMsg); + + uint32_t getCID() const; + void init(const ChannelInitState newInitState); + void lock(const ChannelLockedState newLockedState); }; diff --git a/Controller.cpp b/Controller.cpp index 97cf7dd..1024d75 100644 --- a/Controller.cpp +++ b/Controller.cpp @@ -17,49 +17,42 @@ along with this program. If not, see . */ #include "Controller.hpp" -#include "u2f.hpp" -#include #include "IO.hpp" #include "LED.hpp" +#include "u2f.hpp" +#include 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::system_clock::now() - lastMessage) < chrono::seconds(5)) +void Controller::handleTransaction() { + try { + if (channels.size() != 0 && + chrono::duration_cast(chrono::system_clock::now() - lastMessage) < + chrono::seconds(5)) toggleACTLED(); else enableACTLED(false); - } - catch (runtime_error& ignored) - {} + } catch (runtime_error& ignored) { + } auto msg = U2FMessage::readNonBlock(); if (!msg) return; - + lastMessage = chrono::system_clock::now(); auto opChannel = msg->cid; - if (msg->cmd == U2FHID_INIT) - { + if (msg->cmd == U2FHID_INIT) { opChannel = nextChannel(); auto channel = Channel{ opChannel }; - try - { - channels.emplace(opChannel, channel); //In case of wrap-around replace existing one - } - catch (...) - { + try { + channels.emplace(opChannel, channel); // In case of wrap-around replace existing one + } 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); diff --git a/Controller.hpp b/Controller.hpp index f365ebd..4548bc4 100644 --- a/Controller.hpp +++ b/Controller.hpp @@ -17,20 +17,19 @@ along with this program. If not, see . */ #pragma once -#include -#include #include "Channel.hpp" +#include +#include -class Controller -{ - protected: - std::map channels; - uint32_t currChannel; - std::chrono::system_clock::time_point lastMessage; +class Controller { +protected: + std::map channels; + uint32_t currChannel; + std::chrono::system_clock::time_point lastMessage; - public: - Controller(const uint32_t startChannel = 1); +public: + Controller(const uint32_t startChannel = 1); - void handleTransaction(); - uint32_t nextChannel(); + void handleTransaction(); + uint32_t nextChannel(); }; diff --git a/Field.cpp b/Field.cpp index 0d67d72..a175232 100644 --- a/Field.cpp +++ b/Field.cpp @@ -20,7 +20,7 @@ along with this program. If not, see . using namespace std; -vector beEncode(const uint8_t* val, const size_t byteCount) -{ - return { reverse_iterator(val + byteCount), reverse_iterator(val) }; +vector beEncode(const uint8_t* val, const size_t byteCount) { + return { reverse_iterator(val + byteCount), + reverse_iterator(val) }; } diff --git a/Field.hpp b/Field.hpp index f9df49d..c5c94d9 100644 --- a/Field.hpp +++ b/Field.hpp @@ -17,13 +17,17 @@ along with this program. If not, see . */ #pragma once -#include #include +#include template std::vector beEncode(const Type val); std::vector beEncode(const uint8_t* val, const std::size_t byteCount); -#define FIELD(name) reinterpret_cast(&name), (reinterpret_cast(&name) + sizeof(name)) -#define FIELD_BE(name) reverse_iterator(reinterpret_cast(&name) + sizeof(name)), reverse_iterator(reinterpret_cast(&name)) +#define FIELD(name) \ + reinterpret_cast(&name), \ + (reinterpret_cast(&name) + sizeof(name)) +#define FIELD_BE(name) \ + reverse_iterator(reinterpret_cast(&name) + sizeof(name)), \ + reverse_iterator(reinterpret_cast(&name)) diff --git a/IO.cpp b/IO.cpp index 58870c5..e8eb413 100644 --- a/IO.cpp +++ b/IO.cpp @@ -21,30 +21,28 @@ along with this program. If not, see . #include #include //#include -#include -#include -#include -#include -#include -#include -#include -#include "u2f.hpp" #include "Macro.hpp" #include "U2FDevice.hpp" +#include "u2f.hpp" +#include +#include +#include +#include +#include +#include +#include using namespace std; bool bytesAvailable(const size_t count); vector& getBuffer(); -vector readNonBlock(const size_t count) -{ - if (!bytesAvailable(count)) - { +vector readNonBlock(const size_t count) { + if (!bytesAvailable(count)) { return vector{}; } - auto &buffer = getBuffer(); + auto& buffer = getBuffer(); auto buffStart = buffer.begin(), buffEnd = buffer.begin() + count; vector bytes{ buffStart, buffEnd }; buffer.erase(buffStart, buffEnd); @@ -54,32 +52,29 @@ vector 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(); + 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 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,51 +92,44 @@ bool bytesAvailable(const size_t count) return false; } -vector& bufferVar() -{ +vector& bufferVar() { static vector buffer{}; return buffer; } -vector& getBuffer() -{ - auto &buff = bufferVar(); +vector& getBuffer() { + auto& buff = bufferVar(); array bytes{}; auto hostDescriptor = *getHostDescriptor(); - while (true) - { + while (true) { auto readByteCount = read(hostDescriptor, bytes.data(), HID_RPT_SIZE); - if (readByteCount > 0 && readByteCount != HID_RPT_SIZE) - { - //Failed to copy an entire packet in, so log this packet + 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 + break; // Escape loop if blocking would occur } } diff --git a/IO.hpp b/IO.hpp index 57fadcc..9aa70b9 100644 --- a/IO.hpp +++ b/IO.hpp @@ -21,9 +21,9 @@ along with this program. If not, see . #include #include -//Returns either the number of bytes specified, -//or returns empty vector without discarding bytes from HID stream +// Returns either the number of bytes specified, +// or returns empty vector without discarding bytes from HID stream std::vector readNonBlock(const size_t count); -//Blocking write to HID stream - shouldn't block for too long +// Blocking write to HID stream - shouldn't block for too long void write(const uint8_t* bytes, const size_t count); diff --git a/LED.cpp b/LED.cpp index 68045e9..ee2d6b9 100644 --- a/LED.cpp +++ b/LED.cpp @@ -24,19 +24,16 @@ along with this program. If not, see . 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()); } diff --git a/Macro.hpp b/Macro.hpp index e187302..7c68958 100644 --- a/Macro.hpp +++ b/Macro.hpp @@ -17,7 +17,12 @@ along with this program. If not, see . */ #pragma once -#include #include +#include -#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 diff --git a/Packet.cpp b/Packet.cpp index 1f0e983..2ceb08a 100644 --- a/Packet.cpp +++ b/Packet.cpp @@ -18,24 +18,22 @@ along with this program. If not, see . #include "Packet.hpp" #include "IO.hpp" +#include "Streams.hpp" #include "u2f.hpp" #include #include #include -#include "Streams.hpp" using namespace std; -shared_ptr InitPacket::getPacket(const uint32_t rCID, const uint8_t rCMD) -{ +shared_ptr 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 bytes{}; - switch (bytesRead) - { + switch (bytesRead) { case 0: bytes = readNonBlock(1); @@ -62,7 +60,8 @@ shared_ptr 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]]; @@ -74,56 +73,56 @@ shared_ptr InitPacket::getPacket(const uint32_t rCID, const uint8_t } auto p = make_shared(); - p->cid = rCID; - p->cmd = rCMD; + p->cid = rCID; + p->cmd = rCMD; p->bcnth = bcnth; p->bcntl = bcntl; - p->data = dataBytes; + p->data = dataBytes; #ifdef DEBUG_STREAMS auto hPStream = getHostPacketStream().get(); - fprintf(hPStream, "\t\t\n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" + "\t\t\t\n" + "\t\t
CIDCMDBCNTHBCNTLDATA
0x%08X%u%u%u", p->cid, p->cmd, p->bcnth, p->bcntl); + fprintf(hPStream, + "\t\t\n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t
CIDCMDBCNTHBCNTLDATA
0x%08X%u%u%u", + p->cid, p->cmd, p->bcnth, p->bcntl); for (auto elem : dataBytes) fprintf(hPStream, "%3u ", elem); fprintf(hPStream, "
" - "\t\t
"); + "\t\t\t\t
" + "\t\t
"); #endif bytesRead = 0; return p; } -shared_ptr ContPacket::getPacket(const uint32_t rCID, const uint8_t rSeq) -{ +shared_ptr ContPacket::getPacket(const uint32_t rCID, const uint8_t rSeq) { static size_t readBytes = 0; static decltype(ContPacket::data) dataBytes; vector bytes{}; auto p = make_shared(); - if (readBytes != dataBytes.size()) - { + if (readBytes != dataBytes.size()) { dataBytes = {}; bytes = readNonBlock(dataBytes.size()); @@ -140,48 +139,48 @@ shared_ptr ContPacket::getPacket(const uint32_t rCID, const uint8_t #ifdef DEBUG_STREAMS auto hPStream = getHostPacketStream().get(); - fprintf(hPStream, "\t\t\n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" + "\t\t\t\n" + "\t\t
CIDSEQDATA
0x%08X%u", p->cid, p->seq); + fprintf(hPStream, + "\t\t\n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t
CIDSEQDATA
0x%08X%u", + p->cid, p->seq); for (auto elem : dataBytes) fprintf(hPStream, "%3u ", elem); fprintf(hPStream, "
\n" - "\t\t
"); + "\t\t\t\t
\n" + "\t\t
"); #endif readBytes = 0; return p; } -shared_ptr Packet::getPacket() -{ +shared_ptr Packet::getPacket() { static size_t bytesRead = 0; vector bytes{}; static uint32_t cid; - static uint8_t b; + static uint8_t b; shared_ptr packet{}; - switch (bytesRead) - { + switch (bytesRead) { case 0: bytes = readNonBlock(4); - + if (bytes.size() == 0) return {}; @@ -200,19 +199,16 @@ shared_ptr Packet::getPacket() [[fallthrough]]; case 5: - if (b & TYPE_MASK) - { - //Init packet + if (b & TYPE_MASK) { + // Init packet packet = InitPacket::getPacket(cid, b); if (packet) bytesRead = 0; return packet; - } - else - { - //Cont packet + } else { + // Cont packet packet = ContPacket::getPacket(cid, b); if (packet) @@ -225,97 +221,98 @@ shared_ptr Packet::getPacket() } } -void Packet::writePacket() -{ - memset(this->buf, 0, HID_RPT_SIZE); +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 - auto devStream = getComDevStream().get(); + auto devStream = getComDevStream().get(); #endif - memcpy(this->buf + 4, &cmd, 1); - memcpy(this->buf + 5, &bcnth, 1); - memcpy(this->buf + 6, &bcntl, 1); + memcpy(this->buf + 4, &cmd, 1); + memcpy(this->buf + 5, &bcnth, 1); + memcpy(this->buf + 6, &bcntl, 1); memcpy(this->buf + 7, data.data(), data.size()); - write(this->buf, sizeof(this->buf)); + write(this->buf, sizeof(this->buf)); #ifdef DEBUG_STREAMS - fwrite(this->buf, 1, sizeof(this->buf), devStream); + fwrite(this->buf, 1, sizeof(this->buf), devStream); auto dPStream = getDevPacketStream().get(); - fprintf(dPStream, "\t\t\n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" + "\t\t\t\n" + "\t\t
CIDCMDBCNTHBCNTLDATA
0x%08X%u%u%u", cid, cmd, bcnth, bcntl); + fprintf(dPStream, + "\t\t\n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t
CIDCMDBCNTHBCNTLDATA
0x%08X%u%u%u", + cid, cmd, bcnth, bcntl); for (auto elem : data) fprintf(dPStream, "%3u ", elem); fprintf(dPStream, "
" - "\t\t
"); + "\t\t\t\t
" + "\t\t
"); #endif } -void ContPacket::writePacket() -{ +void ContPacket::writePacket() { Packet::writePacket(); #ifdef DEBUG_STREAMS - auto devStream = getComDevStream().get(); + auto devStream = getComDevStream().get(); #endif - memcpy(this->buf + 4, &seq, 1); + memcpy(this->buf + 4, &seq, 1); memcpy(this->buf + 5, data.data(), data.size()); - write(this->buf, HID_RPT_SIZE); + write(this->buf, HID_RPT_SIZE); #ifdef DEBUG_STREAMS - fwrite(this->buf, HID_RPT_SIZE, 1, devStream); + fwrite(this->buf, HID_RPT_SIZE, 1, devStream); auto dPStream = getDevPacketStream().get(); - fprintf(dPStream, "\t\t\n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" + "\t\t\t\n" + "\t\t
CIDSEQDATA
0x%08X%u", cid, seq); + fprintf(dPStream, + "\t\t\n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t
CIDSEQDATA
0x%08X%u", + cid, seq); for (auto elem : data) fprintf(dPStream, "%3u ", elem); fprintf(dPStream, "
\n" - "\t\t
"); + "\t\t\t\t
\n" + "\t\t
"); #endif } diff --git a/Packet.hpp b/Packet.hpp index 517bf68..806629a 100644 --- a/Packet.hpp +++ b/Packet.hpp @@ -17,48 +17,45 @@ along with this program. If not, see . */ #pragma once +#include "u2f.hpp" +#include #include #include -#include -#include "u2f.hpp" -struct Packet -{ - public: - uint32_t cid; - uint8_t buf[HID_RPT_SIZE]; +struct Packet { +public: + uint32_t cid; + uint8_t buf[HID_RPT_SIZE]; - protected: - Packet() = default; - virtual void writePacket(); +protected: + Packet() = default; + virtual void writePacket(); - public: - static std::shared_ptr getPacket(); - virtual ~Packet() = default; +public: + static std::shared_ptr getPacket(); + virtual ~Packet() = default; }; -struct InitPacket : Packet -{ - public: - uint8_t cmd; - uint8_t bcnth; - uint8_t bcntl; - std::array data{}; +struct InitPacket : Packet { +public: + uint8_t cmd; + uint8_t bcnth; + uint8_t bcntl; + std::array data{}; - public: - InitPacket() = default; - static std::shared_ptr getPacket(const uint32_t rCID, const uint8_t rCMD); - void writePacket() override; +public: + InitPacket() = default; + static std::shared_ptr getPacket(const uint32_t rCID, const uint8_t rCMD); + void writePacket() override; }; -struct ContPacket : Packet -{ - public: - uint8_t seq; - std::array data{}; +struct ContPacket : Packet { +public: + uint8_t seq; + std::array data{}; - public: - ContPacket() = default; - static std::shared_ptr getPacket(const uint32_t rCID, const uint8_t rSeq); - void writePacket() override; +public: + ContPacket() = default; + static std::shared_ptr getPacket(const uint32_t rCID, const uint8_t rSeq); + void writePacket() override; }; diff --git a/Signature.cpp b/Signature.cpp index def6667..fb502ab 100644 --- a/Signature.cpp +++ b/Signature.cpp @@ -21,27 +21,24 @@ along with this program. If not, see . using namespace std; -//Ripped from https://github.com/pratikd650/Teensy_U2F/blob/master/Teensy_U2F.cpp -void appendSignatureAsDER(vector &response, const array &signature) -{ +// Ripped from https://github.com/pratikd650/Teensy_U2F/blob/master/Teensy_U2F.cpp +void appendSignatureAsDER(vector& response, const array& signature) { response.push_back(0x30); // Start of ASN.1 SEQUENCE - response.push_back(68); //total length from (2 * (32 + 2)) to (2 * (33 + 2)) + 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) - { + response.push_back(0x02); // header: integer + response.push_back(32); // 32 byte + 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 response[countByte]++; } - copy(offset, offset + 32, back_inserter(response)); //R or S value + copy(offset, offset + 32, back_inserter(response)); // R or S value } } diff --git a/Signature.hpp b/Signature.hpp index 889c890..55ed802 100644 --- a/Signature.hpp +++ b/Signature.hpp @@ -17,11 +17,11 @@ along with this program. If not, see . */ #pragma once -#include #include +#include -using Digest = std::array; +using Digest = std::array; using Signature = std::array; -//Ripped from https://github.com/pratikd650/Teensy_U2F/blob/master/Teensy_U2F.cpp -void appendSignatureAsDER(std::vector &response, const Signature &signature); +// Ripped from https://github.com/pratikd650/Teensy_U2F/blob/master/Teensy_U2F.cpp +void appendSignatureAsDER(std::vector& response, const Signature& signature); diff --git a/Storage.cpp b/Storage.cpp index 6c2ea05..2260196 100644 --- a/Storage.cpp +++ b/Storage.cpp @@ -17,44 +17,44 @@ along with this program. If not, see . */ #include "Storage.hpp" -#include -#include #include "Base64.tpp" +#include #include +#include using namespace std; std::string Storage::filename{}; std::map Storage::appParams{}; -std::map Storage::privKeys{}; -std::map Storage::pubKeys{}; +std::map Storage::privKeys{}; +std::map Storage::pubKeys{}; std::map 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; - ss >> keyHStr >> appStr >> privStr >> pubStr >> keyCStr; + string keyHStr, appStr, privStr, pubStr, keyCStr; + ss >> keyHStr >> appStr >> privStr >> pubStr >> keyCStr; if (!ss) throw runtime_error{ string{ "Invalid syntax of line " } + strLineNum }; - char *endP = nullptr; - Storage::KeyHandle keyH{ static_cast(strtoull(keyHStr.c_str(), &endP, 10)) }; + char* endP = nullptr; + Storage::KeyHandle keyH{ static_cast( + strtoull(keyHStr.c_str(), &endP, 10)) }; if (!endP) throw runtime_error{ "Invalid keyhandle format on line " + strLineNum }; - + endP = nullptr; - Storage::KeyCount keyC{ static_cast(strtoull(keyCStr.c_str(), &endP, 10)) }; + Storage::KeyCount keyC{ static_cast( + strtoull(keyCStr.c_str(), &endP, 10)) }; if (!endP) throw runtime_error{ "Invalid key count format on line " + strLineNum }; @@ -62,31 +62,29 @@ void Storage::init(const string &dirPrefix) Storage::AppParam appParam{}; b64decode(appStr, appParam); - Storage::PrivKey privKey{}; + Storage::PrivKey privKey{}; b64decode(privStr, privKey); - Storage::PubKey pubKey{}; + Storage::PubKey pubKey{}; b64decode(pubStr, pubKey); Storage::appParams[keyH] = appParam; - Storage::privKeys[keyH] = privKey; - Storage::pubKeys[keyH] = pubKey; + Storage::privKeys[keyH] = privKey; + Storage::pubKeys[keyH] = pubKey; Storage::keyCounts[keyH] = keyC; lineNumber++; } } -void Storage::save() -{ +void Storage::save() { ofstream file{ Storage::filename }; - for (auto &keypair : Storage::appParams) - { - const auto& keyID = keypair.first; + for (auto& keypair : Storage::appParams) { + const auto& keyID = keypair.first; const auto& appParam = keypair.second; - const auto& privKey = Storage::privKeys[keyID]; - const auto& pubKey = Storage::pubKeys[keyID]; + const auto& privKey = Storage::privKeys[keyID]; + const auto& pubKey = Storage::pubKeys[keyID]; const auto& keyCount = Storage::keyCounts[keyID]; file << keyID; diff --git a/Storage.hpp b/Storage.hpp index a0359d6..2d679dd 100644 --- a/Storage.hpp +++ b/Storage.hpp @@ -17,30 +17,29 @@ along with this program. If not, see . */ #pragma once -#include #include -#include #include +#include +#include -class Storage -{ +class Storage { public: using KeyHandle = uint32_t; - using KeyCount = uint32_t; - using AppParam = std::array; - using PrivKey = std::array; - using PubKey = std::array; + using KeyCount = uint32_t; + using AppParam = std::array; + using PrivKey = std::array; + using PubKey = std::array; - protected: - Storage() = default; +protected: + Storage() = default; - static std::string filename; + static std::string filename; - public: - static void init(const std::string &dirPrefix = ""); - static void save(); - static std::map appParams; - static std::map privKeys; - static std::map pubKeys; - static std::map keyCounts; +public: + static void init(const std::string& dirPrefix = ""); + static void save(); + static std::map appParams; + static std::map privKeys; + static std::map pubKeys; + static std::map keyCounts; }; diff --git a/Streams.cpp b/Streams.cpp index 4f51ec3..dcda8b6 100644 --- a/Streams.cpp +++ b/Streams.cpp @@ -17,27 +17,26 @@ along with this program. If not, see . */ #include "Streams.hpp" -#include -#include -#include -#include #include +#include +#include +#include +#include #include using namespace std; #ifdef DEBUG_STREAMS -FILE* initHTML(FILE *fPtr, const string &title); -void closeHTML(FILE *fPtr); +FILE* initHTML(FILE* fPtr, const string& title); +void closeHTML(FILE* fPtr); #endif -shared_ptr getHostDescriptor() -{ +shared_ptr getHostDescriptor() { static shared_ptr descriptor{}; - - descriptor.reset(new int{ open(HID_DEV, O_RDWR | O_NONBLOCK | O_APPEND) }, [](int* fd){ - close(*fd); - delete fd; + + descriptor.reset(new int{ open(HID_DEV, O_RDWR | O_NONBLOCK | O_APPEND) }, [](int* fd) { + close(*fd); + delete fd; }); if (*descriptor == -1) @@ -47,12 +46,11 @@ shared_ptr getHostDescriptor() } #ifdef DEBUG_STREAMS -shared_ptr getComHostStream() -{ - static shared_ptr stream{ fopen(DEBUG_STREAMS "comhost.txt", "wb"), [](FILE *f){ - clog << "Closing comhost stream" << endl; - fclose(f); - } }; +shared_ptr getComHostStream() { + static shared_ptr stream{ fopen(DEBUG_STREAMS "comhost.txt", "wb"), [](FILE* f) { + clog << "Closing comhost stream" << endl; + fclose(f); + } }; if (!stream) clog << "Stream is unavailable" << endl; @@ -60,12 +58,13 @@ shared_ptr getComHostStream() return stream; } -shared_ptr getHostPacketStream() -{ - static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "hostpackets.html", "wb"), "Host Packets"), [](FILE *f){ - clog << "Closing hostPackets stream" << endl; - closeHTML(f); - } }; +shared_ptr getHostPacketStream() { + static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "hostpackets.html", "wb"), + "Host Packets"), + [](FILE* f) { + clog << "Closing hostPackets stream" << endl; + closeHTML(f); + } }; if (!stream) clog << "Stream is unavailable" << endl; @@ -73,12 +72,13 @@ shared_ptr getHostPacketStream() return stream; } -shared_ptr getHostAPDUStream() -{ - static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "hostAPDU.html", "wb"), "Host APDU"), [](FILE *f){ - clog << "Closing host APDU stream" << endl; - closeHTML(f); - } }; +shared_ptr getHostAPDUStream() { + static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "hostAPDU.html", "wb"), + "Host APDU"), + [](FILE* f) { + clog << "Closing host APDU stream" << endl; + closeHTML(f); + } }; if (!stream) clog << "Stream is unavailable" << endl; @@ -86,12 +86,11 @@ shared_ptr getHostAPDUStream() return stream; } -shared_ptr getComDevStream() -{ - static shared_ptr stream{ fopen(DEBUG_STREAMS "comdev.txt", "wb"), [](FILE *f){ - clog << "Closing comdev stream" << endl; - fclose(f); - } }; +shared_ptr getComDevStream() { + static shared_ptr stream{ fopen(DEBUG_STREAMS "comdev.txt", "wb"), [](FILE* f) { + clog << "Closing comdev stream" << endl; + fclose(f); + } }; if (!stream) clog << "Stream is unavailable" << endl; @@ -99,12 +98,13 @@ shared_ptr getComDevStream() return stream; } -shared_ptr getDevPacketStream() -{ - static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "devpackets.html", "wb"), "Dev Packets"), [](FILE *f){ - clog << "Closing devPackets stream" << endl; - closeHTML(f); - } }; +shared_ptr getDevPacketStream() { + static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "devpackets.html", "wb"), + "Dev Packets"), + [](FILE* f) { + clog << "Closing devPackets stream" << endl; + closeHTML(f); + } }; if (!stream) clog << "Stream is unavailable" << endl; @@ -112,12 +112,12 @@ shared_ptr getDevPacketStream() return stream; } -shared_ptr getDevAPDUStream() -{ - static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "devAPDU.html", "wb"), "Dev APDU"), [](FILE *f){ - clog << "Closing dev APDU stream" << endl; - closeHTML(f); - } }; +shared_ptr getDevAPDUStream() { + static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "devAPDU.html", "wb"), "Dev APDU"), + [](FILE* f) { + clog << "Closing dev APDU stream" << endl; + closeHTML(f); + } }; if (!stream) clog << "Stream is unavailable" << endl; @@ -125,54 +125,54 @@ shared_ptr getDevAPDUStream() return stream; } -FILE* initHTML(FILE *fPtr, const string &title) -{ - fprintf(fPtr, "\n" - "\t\n" - "\t\t%s\n" - "\t\t\n" - "\t\n" - "\n" - "\t", title.c_str()); +FILE* initHTML(FILE* fPtr, const string& title) { + fprintf(fPtr, + "\n" + "\t\n" + "\t\t%s\n" + "\t\t\n" + "\t\n" + "\n" + "\t", + title.c_str()); return fPtr; } -void closeHTML(FILE *fPtr) -{ +void closeHTML(FILE* fPtr) { fprintf(fPtr, "\t\n" - ""); + ""); fclose(fPtr); } #endif diff --git a/Streams.hpp b/Streams.hpp index ce04bb3..7fbd4d9 100644 --- a/Streams.hpp +++ b/Streams.hpp @@ -17,11 +17,11 @@ along with this program. If not, see . */ #pragma once +#include "Architecture.hpp" #include #include -#include "Architecture.hpp" -std::shared_ptr getHostDescriptor(); +std::shared_ptr getHostDescriptor(); #ifdef DEBUG_STREAMS std::shared_ptr getComHostStream(); diff --git a/U2FDevice.cpp b/U2FDevice.cpp index fb34cd2..6e235c7 100644 --- a/U2FDevice.cpp +++ b/U2FDevice.cpp @@ -17,10 +17,10 @@ along with this program. If not, see . */ #include "Architecture.hpp" -#include -#include "Storage.hpp" #include "Controller.hpp" #include "LED.hpp" +#include "Storage.hpp" +#include #include #include @@ -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; } diff --git a/U2FDevice.hpp b/U2FDevice.hpp index 5ab1dba..79d5ecb 100644 --- a/U2FDevice.hpp +++ b/U2FDevice.hpp @@ -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); - diff --git a/U2FMessage.cpp b/U2FMessage.cpp index dd5b508..40fc03c 100644 --- a/U2FMessage.cpp +++ b/U2FMessage.cpp @@ -17,37 +17,34 @@ along with this program. If not, see . */ #include "U2FMessage.hpp" +#include "IO.hpp" #include "Packet.hpp" -#include -#include -#include #include "Streams.hpp" #include "u2f.hpp" -#include "IO.hpp" +#include +#include +#include using namespace std; -shared_ptr U2FMessage::readNonBlock() -{ - const static size_t startSeq = (size_t)-1ull; - static size_t currSeq = startSeq; - static uint16_t messageSize; - static uint32_t cid; - static uint8_t cmd; +shared_ptr U2FMessage::readNonBlock() { + const static size_t startSeq = (size_t)-1ull; + static size_t currSeq = startSeq; + static uint16_t messageSize; + static uint32_t cid; + static uint8_t cmd; static vector dataBytes; shared_ptr p{}; - if (currSeq == startSeq) - { + if (currSeq == startSeq) { cid = 0; cmd = 0; messageSize = 0; dataBytes = {}; - + shared_ptr initPack{}; - do - { + do { p = Packet::getPacket(); if (!p) @@ -59,43 +56,46 @@ shared_ptr U2FMessage::readNonBlock() if (!initPack) cerr << "Spurious cont. packet" << endl; #endif - } while (!initPack); //Spurious cont. packet - spec states ignore + } while (!initPack); // Spurious cont. packet - spec states ignore messageSize = ((static_cast(initPack->bcnth) << 8u) + initPack->bcntl); - const uint16_t copyByteCount = min(static_cast(initPack->data.size()), messageSize); + const uint16_t copyByteCount = + min(static_cast(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(p = Packet::getPacket())) //While there is a packet + while (messageSize > dataBytes.size() && + static_cast(p = Packet::getPacket())) // While there is a packet { auto contPack = dynamic_pointer_cast(p); - if (!contPack) //Spurious init. packet + if (!contPack) // Spurious init. packet { #ifdef DEBUG_MSGS cerr << "Spurious init. packet" << endl; #endif - currSeq = startSeq; //Reset + currSeq = startSeq; // Reset return {}; } - if (contPack->cid != cid) //Cont. packet of different CID + 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::readNonBlock() } const uint16_t remainingBytes = messageSize - dataBytes.size(); - const uint16_t copyBytes = min(static_cast(contPack->data.size()), remainingBytes); + const uint16_t copyBytes = + min(static_cast(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::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(p.data.size()), static_cast(bytesToWrite - bytesWritten)); + uint16_t initialByteCount = min(static_cast(p.data.size()), + static_cast(bytesToWrite - bytesWritten)); copy(data.begin(), data.begin() + initialByteCount, p.data.begin()); bytesWritten += initialByteCount; } @@ -151,58 +154,57 @@ 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(p.data.size()), static_cast(bytesToWrite - bytesWritten)); - copy(data.begin() + bytesWritten, data.begin() + bytesWritten + newByteCount, p.data.begin()); + uint16_t newByteCount = min(static_cast(p.data.size()), + static_cast(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(); - + fprintf(dAS, "\n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t
DATAERR
"); - + "\t\t\t
DATAERR
"); + for (size_t i = 0; i < data.size() - 2; i++) fprintf(dAS, "%3u ", data[i]); #endif - + uint16_t err = data[data.size() - 2] << 8; err |= data.back(); - + #ifdef DEBUG_STREAMS - fprintf(dAS, "0x%04X
\n" - "\t\t
", err); + fprintf(dAS, + "\n" + "\t\t\t\t\t0x%04X\n" + "\t\t\t\t\n" + "\t\t\t\n" + "\t\t\n" + "\t\t
", + 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; diff --git a/U2FMessage.hpp b/U2FMessage.hpp index 5a2286d..1283df2 100644 --- a/U2FMessage.hpp +++ b/U2FMessage.hpp @@ -18,21 +18,19 @@ along with this program. If not, see . #pragma once #include -#include #include -#include +#include -struct U2FMessage -{ - public: - uint32_t cid; - uint8_t cmd; - std::vector data; +struct U2FMessage { +public: + uint32_t cid; + uint8_t cmd; + std::vector data; - public: - U2FMessage() = default; - U2FMessage(const uint32_t nCID, const uint8_t nCMD); - static std::shared_ptr readNonBlock(); - void write(); - static void error(const uint32_t tCID, const uint8_t tErr); +public: + U2FMessage() = default; + U2FMessage(const uint32_t nCID, const uint8_t nCMD); + static std::shared_ptr readNonBlock(); + void write(); + static void error(const uint32_t tCID, const uint8_t tErr); }; diff --git a/U2F_Authenticate_APDU.cpp b/U2F_Authenticate_APDU.cpp index 2ae2233..4a6d3fa 100644 --- a/U2F_Authenticate_APDU.cpp +++ b/U2F_Authenticate_APDU.cpp @@ -17,33 +17,29 @@ along with this program. If not, see . */ #include "U2F_Authenticate_APDU.hpp" -#include "Field.hpp" -#include "U2FMessage.hpp" -#include "u2f.hpp" -#include "Field.tpp" #include "APDU.hpp" -#include +#include "Field.hpp" +#include "Field.tpp" #include "Signature.hpp" +#include "U2FMessage.hpp" #include "micro-ecc/uECC.h" +#include "u2f.hpp" +#include #include using namespace std; -U2F_Authenticate_APDU::U2F_Authenticate_APDU(const U2F_Msg_CMD &msg, const vector &data) - : U2F_Msg_CMD{ msg } -{ - if (p2 != 0) - { - //Invalid U2F (APDU) parameter detected +U2F_Authenticate_APDU::U2F_Authenticate_APDU(const U2F_Msg_CMD& msg, const vector& data) + : U2F_Msg_CMD{ msg } { + if (p2 != 0) { + // Invalid U2F (APDU) parameter detected throw APDU_STATUS::SW_CONDITIONS_NOT_SATISFIED; - } - else if (data.size() < 66) - { - //Invalid authentication request + } else if (data.size() < 66) { + // Invalid authentication request throw APDU_STATUS::SW_WRONG_LENGTH; } - copy(data.begin() + 0, data.begin() + 32, challengeP.begin()); + copy(data.begin() + 0, data.begin() + 32, challengeP.begin()); copy(data.begin() + 32, data.begin() + 64, appParam.begin()); uint8_t keyHLen = data[64]; @@ -51,21 +47,18 @@ 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)) - { - //Respond with error code - key handle is of wrong size +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); return; } auto keyHB = *reinterpret_cast(keyH.data()); - - if (Storage::appParams.find(keyHB) == Storage::appParams.end()) - { - //Respond with error code - key handle doesn't exist in storage + + 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); return; @@ -77,11 +70,10 @@ void U2F_Authenticate_APDU::respond(const uint32_t channelID) const msg.cid = channelID; msg.cmd = U2FHID_MSG; - auto &response = msg.data; + 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; @@ -92,9 +84,9 @@ void U2F_Authenticate_APDU::respond(const uint32_t channelID) const msg.write(); return; case ControlCode::EnforcePresenceSign: - //Continue processing + // Continue processing case ControlCode::DontEnforcePresenceSign: - //Continue processing + // Continue processing break; default: @@ -104,7 +96,7 @@ void U2F_Authenticate_APDU::respond(const uint32_t channelID) const } const auto& privKey = Storage::privKeys[keyHB]; - auto& keyCount = Storage::keyCounts[keyHB]; + auto& keyCount = Storage::keyCounts[keyHB]; keyCount++; response.push_back(0x01); @@ -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(appParam.data()), sizeof(appParam)); + mbedtls_sha256_update(&shaContext, reinterpret_cast(appParam.data()), + sizeof(appParam)); uint8_t userPresence{ 1u }; mbedtls_sha256_update(&shaContext, &userPresence, 1); const auto beCounter = beEncode(keyCount); diff --git a/U2F_Authenticate_APDU.hpp b/U2F_Authenticate_APDU.hpp index 8b669c0..e540682 100644 --- a/U2F_Authenticate_APDU.hpp +++ b/U2F_Authenticate_APDU.hpp @@ -17,23 +17,21 @@ along with this program. If not, see . */ #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 challengeP; - Storage::AppParam appParam; - std::vector keyH; + Storage::AppParam appParam; + std::vector keyH; - public: - U2F_Authenticate_APDU(const U2F_Msg_CMD &msg, const std::vector &data); +public: + U2F_Authenticate_APDU(const U2F_Msg_CMD& msg, const std::vector& data); - virtual void respond(const uint32_t channelID) const override; + virtual void respond(const uint32_t channelID) const override; - enum ControlCode - { + enum ControlCode { CheckOnly = 0x07, EnforcePresenceSign = 0x03, DontEnforcePresenceSign = 0x08 diff --git a/U2F_CMD.cpp b/U2F_CMD.cpp index 7cdaf43..b3ee67a 100644 --- a/U2F_CMD.cpp +++ b/U2F_CMD.cpp @@ -17,19 +17,16 @@ along with this program. If not, see . */ #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::get(const shared_ptr uMsg) -{ - try - { - switch (uMsg->cmd) - { +shared_ptr U2F_CMD::get(const shared_ptr uMsg) { + try { + switch (uMsg->cmd) { case U2FHID_PING: return make_shared(uMsg); case U2FHID_MSG: @@ -40,9 +37,7 @@ shared_ptr U2F_CMD::get(const shared_ptr uMsg) U2FMessage::error(uMsg->cid, ERR_INVALID_CMD); return {}; } - } - catch (runtime_error& ignored) - { + } catch (runtime_error& ignored) { U2FMessage::error(uMsg->cid, ERR_OTHER); return {}; } diff --git a/U2F_CMD.hpp b/U2F_CMD.hpp index 2533992..75d3a1e 100644 --- a/U2F_CMD.hpp +++ b/U2F_CMD.hpp @@ -17,16 +17,15 @@ along with this program. If not, see . */ #pragma once -#include #include "U2FMessage.hpp" +#include -struct U2F_CMD -{ - protected: - U2F_CMD() = default; +struct U2F_CMD { +protected: + U2F_CMD() = default; - public: - virtual ~U2F_CMD() = default; - static std::shared_ptr get(const std::shared_ptr uMsg); - virtual void respond(const uint32_t channelID) const = 0; -}; //For polymorphic type casting +public: + virtual ~U2F_CMD() = default; + static std::shared_ptr get(const std::shared_ptr uMsg); + virtual void respond(const uint32_t channelID) const = 0; +}; // For polymorphic type casting diff --git a/U2F_Init_CMD.cpp b/U2F_Init_CMD.cpp index b35f643..c43bb98 100644 --- a/U2F_Init_CMD.cpp +++ b/U2F_Init_CMD.cpp @@ -17,23 +17,19 @@ along with this program. If not, see . */ #include "U2F_Init_CMD.hpp" -#include -#include "u2f.hpp" #include "Field.hpp" +#include "u2f.hpp" +#include using namespace std; -U2F_Init_CMD::U2F_Init_CMD(const shared_ptr uMsg) -{ +U2F_Init_CMD::U2F_Init_CMD(const shared_ptr 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,19 +37,18 @@ U2F_Init_CMD::U2F_Init_CMD(const shared_ptr uMsg) this->nonce = *reinterpret_cast(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; msg.data.insert(msg.data.end(), FIELD(this->nonce)); msg.data.insert(msg.data.end(), FIELD(channelID)); - msg.data.push_back(2); //Protocol version - msg.data.push_back(1); //Major device version - msg.data.push_back(0); //Minor device version - msg.data.push_back(1); //Build device version - msg.data.push_back(CAPFLAG_WINK); //Wink capability + msg.data.push_back(2); // Protocol version + msg.data.push_back(1); // Major device version + msg.data.push_back(0); // Minor device version + msg.data.push_back(1); // Build device version + msg.data.push_back(CAPFLAG_WINK); // Wink capability msg.write(); } diff --git a/U2F_Init_CMD.hpp b/U2F_Init_CMD.hpp index acdfcdc..9780826 100644 --- a/U2F_Init_CMD.hpp +++ b/U2F_Init_CMD.hpp @@ -17,16 +17,15 @@ along with this program. If not, see . */ #pragma once +#include "U2FMessage.hpp" +#include "U2F_CMD.hpp" #include #include -#include "U2F_CMD.hpp" -#include "U2FMessage.hpp" -struct U2F_Init_CMD : U2F_CMD -{ +struct U2F_Init_CMD : U2F_CMD { uint64_t nonce; - public: - U2F_Init_CMD(const std::shared_ptr uMsg); - virtual void respond(const uint32_t channelID) const override; +public: + U2F_Init_CMD(const std::shared_ptr uMsg); + virtual void respond(const uint32_t channelID) const override; }; diff --git a/U2F_Msg_CMD.cpp b/U2F_Msg_CMD.cpp index b78d0b2..71ddfeb 100644 --- a/U2F_Msg_CMD.cpp +++ b/U2F_Msg_CMD.cpp @@ -18,119 +18,99 @@ along with this program. If not, see . #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 -#include "Streams.hpp" -#include "Field.hpp" using namespace std; -uint32_t U2F_Msg_CMD::getLe(const uint32_t byteCount, vector bytes) -{ - if (byteCount != 0) - { - //Le must be length of data in bytes - - switch (byteCount) - { +uint32_t U2F_Msg_CMD::getLe(const uint32_t byteCount, vector bytes) { + if (byteCount != 0) { + // Le must be length of data in bytes + + 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::generate(const shared_ptr uMsg) -{ +shared_ptr U2F_Msg_CMD::generate(const shared_ptr 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 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(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::generate(const shared_ptr uMsg) #ifdef DEBUG_STREAMS auto hAS = getHostAPDUStream().get(); - fprintf(hAS, "\n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\n" + "\t\t
CLAINSP1P2LcDataLe
0x%02X0x%02X%u%u%3u", cmd.cla, cmd.ins, cmd.p1, cmd.p2, cmd.lc); - + fprintf(hAS, + "\n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" + "\t\t\t\t\t\n" - "\t\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t
CLAINSP1P2LcDataLe
0x%02X0x%02X%u%u%3u", + cmd.cla, cmd.ins, cmd.p1, cmd.p2, cmd.lc); + for (auto b : dBytes) fprintf(hAS, "%3u ", b); - fprintf(hAS, "%5u
\n" - "\t\t
", cmd.le); + fprintf(hAS, + "
%5u
\n" + "\t\t
", + cmd.le); #endif - try - { - switch (cmd.ins) - { + try { + switch (cmd.ins) { case APDU::U2F_REG: return make_shared(cmd, dBytes); case APDU::U2F_AUTH: @@ -187,17 +169,14 @@ shared_ptr U2F_Msg_CMD::generate(const shared_ptr 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 U2F_Msg_CMD::usesData = { - { U2F_REG, true }, - { U2F_AUTH, true }, - { U2F_VER, false } -}; +const map 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(APDU_STATUS::SW_INS_NOT_SUPPORTED)); } diff --git a/U2F_Msg_CMD.hpp b/U2F_Msg_CMD.hpp index 5a7f69a..010982b 100644 --- a/U2F_Msg_CMD.hpp +++ b/U2F_Msg_CMD.hpp @@ -20,27 +20,25 @@ along with this program. If not, see . #include "U2F_CMD.hpp" #include #include -#include #include +#include -struct U2F_Msg_CMD : U2F_CMD -{ - uint8_t cla; - uint8_t ins; - uint8_t p1; - uint8_t p2; +struct U2F_Msg_CMD : U2F_CMD { + uint8_t cla; + uint8_t ins; + uint8_t p1; + uint8_t p2; uint32_t lc; uint32_t le; const static std::map usesData; - protected: - static uint32_t getLe(const uint32_t byteCount, std::vector bytes); - U2F_Msg_CMD() = default; +protected: + static uint32_t getLe(const uint32_t byteCount, std::vector bytes); + U2F_Msg_CMD() = default; - public: - static std::shared_ptr generate(const std::shared_ptr uMsg); - static void error(const uint32_t channelID, const uint16_t errCode); - void respond(const uint32_t channelID) const; +public: + static std::shared_ptr generate(const std::shared_ptr uMsg); + static void error(const uint32_t channelID, const uint16_t errCode); + void respond(const uint32_t channelID) const; }; - diff --git a/U2F_Ping_CMD.cpp b/U2F_Ping_CMD.cpp index 57f1f71..e3777c5 100644 --- a/U2F_Ping_CMD.cpp +++ b/U2F_Ping_CMD.cpp @@ -21,15 +21,12 @@ along with this program. If not, see . using namespace std; -U2F_Ping_CMD::U2F_Ping_CMD(const shared_ptr uMsg) - : nonce{ uMsg->data } -{ +U2F_Ping_CMD::U2F_Ping_CMD(const shared_ptr 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; diff --git a/U2F_Ping_CMD.hpp b/U2F_Ping_CMD.hpp index c7e8c5c..c32c8a8 100644 --- a/U2F_Ping_CMD.hpp +++ b/U2F_Ping_CMD.hpp @@ -17,16 +17,15 @@ along with this program. If not, see . */ #pragma once +#include "U2FMessage.hpp" +#include "U2F_CMD.hpp" #include #include -#include "U2F_CMD.hpp" -#include "U2FMessage.hpp" -struct U2F_Ping_CMD : U2F_CMD -{ +struct U2F_Ping_CMD : U2F_CMD { std::vector nonce; - public: - U2F_Ping_CMD(const std::shared_ptr uMsg); - virtual void respond(const uint32_t channelID) const override; +public: + U2F_Ping_CMD(const std::shared_ptr uMsg); + virtual void respond(const uint32_t channelID) const override; }; diff --git a/U2F_Register_APDU.cpp b/U2F_Register_APDU.cpp index ef5bba1..e5cc62b 100644 --- a/U2F_Register_APDU.cpp +++ b/U2F_Register_APDU.cpp @@ -17,73 +17,69 @@ along with this program. If not, see . */ #include "U2F_Register_APDU.hpp" -#include -#include -#include "micro-ecc/uECC.h" -#include "Certificates.hpp" -#include -#include #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 +#include +#include +#include using namespace std; -U2F_Register_APDU::U2F_Register_APDU(const U2F_Msg_CMD &msg, const vector &data) - : U2F_Msg_CMD{ msg } -{ - if (data.size() != 64) - { - //Incorrect registration size +U2F_Register_APDU::U2F_Register_APDU(const U2F_Msg_CMD& msg, const vector& data) + : 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 - //However, browsers seem to do it, so... + } 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 + // Invalid U2F Message (APDU) parameters detected throw APDU_STATUS::SW_INS_NOT_SUPPORTED; } - copy(data.data() + 0, data.data() + 32, challengeP.begin()); + copy(data.data() + 0, data.data() + 32, challengeP.begin()); copy(data.data() + 32, data.data() + 64, appP.begin()); - //Use crypto lib to generate keypair + // Use crypto lib to generate keypair Storage::PrivKey privKey{}; Storage::PubKey pubKey{}; - - //First byte must be 0x04 for some reason + + // First byte must be 0x04 for some reason pubKey[0] = 0x04; uECC_make_key(pubKey.data() + 1, privKey.data(), uECC_secp256r1()); - this->keyH = Storage::appParams.size(); //To increment the key handle + this->keyH = Storage::appParams.size(); // To increment the key handle Storage::appParams[this->keyH] = appP; - Storage::privKeys[this->keyH] = privKey; - Storage::pubKeys[this->keyH] = pubKey; + Storage::privKeys[this->keyH] = privKey; + Storage::pubKeys[this->keyH] = pubKey; 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; auto& response = m.data; const auto appParam = Storage::appParams[this->keyH]; - const auto pubKey = Storage::pubKeys[this->keyH]; + const auto pubKey = Storage::pubKeys[this->keyH]; response.push_back(0x05); copy(pubKey.begin(), pubKey.end(), back_inserter(response)); response.push_back(sizeof(this->keyH)); - auto fakeKeyHBytes = reinterpret_cast(&this->keyH); + auto fakeKeyHBytes = reinterpret_cast(&this->keyH); copy(fakeKeyHBytes, fakeKeyHBytes + sizeof(this->keyH), back_inserter(response)); copy(attestCert, end(attestCert), back_inserter(response)); - //Gen signature + // Gen signature Digest digest; { mbedtls_sha256_context shaContext; @@ -94,13 +90,18 @@ void U2F_Register_APDU::respond(const uint32_t channelID) const uint8_t byteReserved = 0; mbedtls_sha256_update(&shaContext, reinterpret_cast(&byteReserved), 1); - mbedtls_sha256_update(&shaContext, reinterpret_cast(appParam.data()), appParam.size()); + mbedtls_sha256_update(&shaContext, reinterpret_cast(appParam.data()), + appParam.size()); - mbedtls_sha256_update(&shaContext, reinterpret_cast(challengeP.data()), challengeP.size()); + mbedtls_sha256_update(&shaContext, + reinterpret_cast(challengeP.data()), + challengeP.size()); - mbedtls_sha256_update(&shaContext, reinterpret_cast(&keyH), sizeof(keyH)); + mbedtls_sha256_update(&shaContext, reinterpret_cast(&keyH), + sizeof(keyH)); - mbedtls_sha256_update(&shaContext, reinterpret_cast(pubKey.data()), pubKey.size()); + mbedtls_sha256_update(&shaContext, reinterpret_cast(pubKey.data()), + pubKey.size()); mbedtls_sha256_finish(&shaContext, digest.data()); mbedtls_sha256_free(&shaContext); @@ -109,7 +110,7 @@ void U2F_Register_APDU::respond(const uint32_t channelID) const Signature signature; uECC_sign(attestPrivKey, digest.data(), digest.size(), signature.data(), uECC_secp256r1()); - //Append signature as DER + // Append signature as DER appendSignatureAsDER(response, signature); response.push_back(static_cast(APDU_STATUS::SW_NO_ERROR) >> 8); diff --git a/U2F_Register_APDU.hpp b/U2F_Register_APDU.hpp index fb58f79..db6ca39 100644 --- a/U2F_Register_APDU.hpp +++ b/U2F_Register_APDU.hpp @@ -17,18 +17,16 @@ along with this program. If not, see . */ #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 challengeP; - Storage::AppParam appP; - Storage::KeyHandle keyH; + Storage::AppParam appP; + Storage::KeyHandle keyH; - public: - U2F_Register_APDU(const U2F_Msg_CMD &msg, const std::vector &data); +public: + U2F_Register_APDU(const U2F_Msg_CMD& msg, const std::vector& data); - void respond(const uint32_t channelID) const override; + void respond(const uint32_t channelID) const override; }; - diff --git a/U2F_Version_APDU.cpp b/U2F_Version_APDU.cpp index 8e057da..0d087bc 100644 --- a/U2F_Version_APDU.cpp +++ b/U2F_Version_APDU.cpp @@ -17,25 +17,23 @@ along with this program. If not, see . */ #include "U2F_Version_APDU.hpp" -#include +#include "APDU.hpp" +#include "Field.hpp" #include "U2FMessage.hpp" #include "u2f.hpp" -#include "Field.hpp" -#include "APDU.hpp" +#include using namespace std; -U2F_Version_APDU::U2F_Version_APDU(const U2F_Msg_CMD &msg, const std::vector &data) -{ - //Don't actually respond yet unless invalid +U2F_Version_APDU::U2F_Version_APDU(const U2F_Msg_CMD& msg, const std::vector& data) { + // Don't actually respond yet unless invalid if (msg.p1 != 0 || msg.p2 != 0) throw APDU_STATUS::SW_INS_NOT_SUPPORTED; else if (data.size() != 0) 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{}; diff --git a/U2F_Version_APDU.hpp b/U2F_Version_APDU.hpp index d566ced..eb907d5 100644 --- a/U2F_Version_APDU.hpp +++ b/U2F_Version_APDU.hpp @@ -19,9 +19,8 @@ along with this program. If not, see . #pragma once #include "U2F_Msg_CMD.hpp" -struct U2F_Version_APDU : U2F_Msg_CMD -{ - public: - U2F_Version_APDU(const U2F_Msg_CMD &msg, const std::vector &data); - void respond(const uint32_t channelID) const override; +struct U2F_Version_APDU : U2F_Msg_CMD { +public: + U2F_Version_APDU(const U2F_Msg_CMD& msg, const std::vector& data); + void respond(const uint32_t channelID) const override; }; diff --git a/main.cpp b/main.cpp index ac35b6f..aa63e84 100644 --- a/main.cpp +++ b/main.cpp @@ -1,38 +1,33 @@ -#include "U2FDevice.hpp" #include "Architecture.hpp" +#include "U2FDevice.hpp" #include #include #ifdef DEBUG_MSGS -//Courtesy StackOverflow answer https://stackoverflow.com/a/3356421 -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) - { - std::cout << stack_syms[i] << "\n"; - } - free(stack_syms); +// Courtesy StackOverflow answer https://stackoverflow.com/a/3356421 +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) { + std::cout << stack_syms[i] << "\n"; + } + free(stack_syms); - exit(1); + exit(1); } #endif -int main(int argc, char **argv) { +int main(int argc, char** argv) { #ifdef DEBUG_MSGS std::set_terminate(terminateHandler); #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; } diff --git a/u2f.hpp b/u2f.hpp index 97744d9..8aab9f0 100644 --- a/u2f.hpp +++ b/u2f.hpp @@ -5,123 +5,122 @@ #ifndef __U2FHID_H_INCLUDED__ #define __U2FHID_H_INCLUDED__ -#ifdef _MSC_VER // Windows -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; +#ifdef _MSC_VER // Windows +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; typedef unsigned long int uint64_t; #else -#include +# include #endif #ifdef __cplusplus extern "C" { #endif -// Size of HID reports +// Size of HID reports + +#define HID_RPT_SIZE 64 // Default size of raw HID report -#define HID_RPT_SIZE 64 // Default size of raw HID report - // Frame layout - command- and continuation frames -#define CID_BROADCAST 0xffffffff // Broadcast channel id +#define CID_BROADCAST 0xffffffff // Broadcast channel id -#define TYPE_MASK 0x80 // Frame type mask -#define TYPE_INIT 0x80 // Initial frame identifier -#define TYPE_CONT 0x00 // Continuation frame identifier +#define TYPE_MASK 0x80 // Frame type mask +#define TYPE_INIT 0x80 // Initial frame identifier +#define TYPE_CONT 0x00 // Continuation frame identifier typedef struct { - uint32_t cid; // Channel identifier - union { - uint8_t type; // Frame type - b7 defines type - struct { - uint8_t cmd; // Command - b7 set - uint8_t bcnth; // Message byte count - high part - uint8_t bcntl; // Message byte count - low part - uint8_t data[HID_RPT_SIZE - 7]; // Data payload - } init; - struct { - uint8_t seq; // Sequence number - b7 cleared - uint8_t data[HID_RPT_SIZE - 5]; // Data payload - } cont; - }; + uint32_t cid; // Channel identifier + union { + uint8_t type; // Frame type - b7 defines type + struct { + uint8_t cmd; // Command - b7 set + uint8_t bcnth; // Message byte count - high part + uint8_t bcntl; // Message byte count - low part + uint8_t data[HID_RPT_SIZE - 7]; // Data payload + } init; + struct { + uint8_t seq; // Sequence number - b7 cleared + uint8_t data[HID_RPT_SIZE - 5]; // Data payload + } cont; + }; } U2FHID_FRAME; #define FRAME_TYPE(f) ((f).type & TYPE_MASK) -#define FRAME_CMD(f) ((f).init.cmd & ~TYPE_MASK) -#define MSG_LEN(f) ((f).init.bcnth*256 + (f).init.bcntl) -#define FRAME_SEQ(f) ((f).cont.seq & ~TYPE_MASK) +#define FRAME_CMD(f) ((f).init.cmd & ~TYPE_MASK) +#define MSG_LEN(f) ((f).init.bcnth * 256 + (f).init.bcntl) +#define FRAME_SEQ(f) ((f).cont.seq & ~TYPE_MASK) // HID usage- and usage-page definitions -#define FIDO_USAGE_PAGE 0xf1d0 // FIDO alliance HID usage page -#define FIDO_USAGE_U2FHID 0x01 // U2FHID usage for top-level collection -#define FIDO_USAGE_DATA_IN 0x20 // Raw IN data report -#define FIDO_USAGE_DATA_OUT 0x21 // Raw OUT data report - -// General constants +#define FIDO_USAGE_PAGE 0xf1d0 // FIDO alliance HID usage page +#define FIDO_USAGE_U2FHID 0x01 // U2FHID usage for top-level collection +#define FIDO_USAGE_DATA_IN 0x20 // Raw IN data report +#define FIDO_USAGE_DATA_OUT 0x21 // Raw OUT data report -#define U2FHID_IF_VERSION 2 // Current interface implementation version -#define U2FHID_TRANS_TIMEOUT 3000 // Default message timeout in ms +// General constants + +#define U2FHID_IF_VERSION 2 // Current interface implementation version +#define U2FHID_TRANS_TIMEOUT 3000 // Default message timeout in ms // U2FHID native commands -#define U2FHID_PING (TYPE_INIT | 0x01) // Echo data through local processor only -#define U2FHID_MSG (TYPE_INIT | 0x03) // Send U2F message frame -#define U2FHID_LOCK (TYPE_INIT | 0x04) // Send lock channel command -#define U2FHID_INIT (TYPE_INIT | 0x06) // Channel initialization -#define U2FHID_WINK (TYPE_INIT | 0x08) // Send device identification wink -#define U2FHID_SYNC (TYPE_INIT | 0x3c) // Protocol resync command -#define U2FHID_ERROR (TYPE_INIT | 0x3f) // Error response +#define U2FHID_PING (TYPE_INIT | 0x01) // Echo data through local processor only +#define U2FHID_MSG (TYPE_INIT | 0x03) // Send U2F message frame +#define U2FHID_LOCK (TYPE_INIT | 0x04) // Send lock channel command +#define U2FHID_INIT (TYPE_INIT | 0x06) // Channel initialization +#define U2FHID_WINK (TYPE_INIT | 0x08) // Send device identification wink +#define U2FHID_SYNC (TYPE_INIT | 0x3c) // Protocol resync command +#define U2FHID_ERROR (TYPE_INIT | 0x3f) // Error response + +#define U2FHID_VENDOR_FIRST (TYPE_INIT | 0x40) // First vendor defined command +#define U2FHID_VENDOR_LAST (TYPE_INIT | 0x7f) // Last vendor defined command -#define U2FHID_VENDOR_FIRST (TYPE_INIT | 0x40) // First vendor defined command -#define U2FHID_VENDOR_LAST (TYPE_INIT | 0x7f) // Last vendor defined command - // U2FHID_INIT command defines -#define INIT_NONCE_SIZE 8 // Size of channel initialization challenge -#define CAPFLAG_WINK 0x01 // Device supports WINK command +#define INIT_NONCE_SIZE 8 // Size of channel initialization challenge +#define CAPFLAG_WINK 0x01 // Device supports WINK command typedef struct { - uint8_t nonce[INIT_NONCE_SIZE]; // Client application nonce + uint8_t nonce[INIT_NONCE_SIZE]; // Client application nonce } U2FHID_INIT_REQ; typedef struct { - uint8_t nonce[INIT_NONCE_SIZE]; // Client application nonce - uint32_t cid; // Channel identifier - uint8_t versionInterface; // Interface version - uint8_t versionMajor; // Major version number - uint8_t versionMinor; // Minor version number - uint8_t versionBuild; // Build version number - uint8_t capFlags; // Capabilities flags + uint8_t nonce[INIT_NONCE_SIZE]; // Client application nonce + uint32_t cid; // Channel identifier + uint8_t versionInterface; // Interface version + uint8_t versionMajor; // Major version number + uint8_t versionMinor; // Minor version number + uint8_t versionBuild; // Build version number + uint8_t capFlags; // Capabilities flags } U2FHID_INIT_RESP; // U2FHID_SYNC command defines typedef struct { - uint8_t nonce; // Client application nonce + uint8_t nonce; // Client application nonce } U2FHID_SYNC_REQ; typedef struct { - uint8_t nonce; // Client application nonce + uint8_t nonce; // Client application nonce } U2FHID_SYNC_RESP; // Low-level error codes. Return as negatives. -#define ERR_NONE 0x00 // No error -#define ERR_INVALID_CMD 0x01 // Invalid command -#define ERR_INVALID_PAR 0x02 // Invalid parameter -#define ERR_INVALID_LEN 0x03 // Invalid message length -#define ERR_INVALID_SEQ 0x04 // Invalid message sequencing -#define ERR_MSG_TIMEOUT 0x05 // Message has timed out -#define ERR_CHANNEL_BUSY 0x06 // Channel busy -#define ERR_LOCK_REQUIRED 0x0a // Command requires channel lock -#define ERR_SYNC_FAIL 0x0b // SYNC command failed -#define ERR_OTHER 0x7f // Other unspecified error +#define ERR_NONE 0x00 // No error +#define ERR_INVALID_CMD 0x01 // Invalid command +#define ERR_INVALID_PAR 0x02 // Invalid parameter +#define ERR_INVALID_LEN 0x03 // Invalid message length +#define ERR_INVALID_SEQ 0x04 // Invalid message sequencing +#define ERR_MSG_TIMEOUT 0x05 // Message has timed out +#define ERR_CHANNEL_BUSY 0x06 // Channel busy +#define ERR_LOCK_REQUIRED 0x0a // Command requires channel lock +#define ERR_SYNC_FAIL 0x0b // SYNC command failed +#define ERR_OTHER 0x7f // Other unspecified error #ifdef __cplusplus } #endif -#endif // __U2FHID_H_INCLUDED__ - +#endif // __U2FHID_H_INCLUDED__