From f48becc6dc8d1470579f764215ddf7e9ee03e9af Mon Sep 17 00:00:00 2001 From: Conor Patrick Date: Thu, 14 Feb 2019 15:15:58 -0500 Subject: [PATCH] bridge extension to fido2 interface --- fido2/ctap.c | 13 ++++++++++++- fido2/extensions/extensions.c | 23 ++++++++++++++++++++--- fido2/extensions/extensions.h | 4 ++++ fido2/extensions/solo.c | 16 +++++++--------- fido2/extensions/solo.h | 2 +- 5 files changed, 44 insertions(+), 14 deletions(-) diff --git a/fido2/ctap.c b/fido2/ctap.c index 3f323d9..4e88dd6 100644 --- a/fido2/ctap.c +++ b/fido2/ctap.c @@ -21,6 +21,7 @@ #include "device.h" #include APP_CONFIG #include "wallet.h" +#include "extensions.h" #include "device.h" @@ -856,6 +857,7 @@ uint8_t ctap_end_get_assertion(CborEncoder * map, CTAP_credentialDescriptor * cr int ret; uint8_t sigbuf[64]; uint8_t sigder[72]; + int sigder_sz; if (add_user) { @@ -869,7 +871,16 @@ uint8_t ctap_end_get_assertion(CborEncoder * map, CTAP_credentialDescriptor * cr crypto_ecc256_load_key((uint8_t*)&cred->credential.id, sizeof(CredentialId), NULL, 0); - int sigder_sz = ctap_calculate_signature(auth_data_buf, sizeof(CTAP_authDataHeader), clientDataHash, auth_data_buf, sigbuf, sigder); +#ifdef ENABLE_U2F_EXTENSIONS + if ( extend_fido2(&cred->credential.id, sigder) ) + { + sigder_sz = 72; + } + else +#endif + { + sigder_sz = ctap_calculate_signature(auth_data_buf, sizeof(CTAP_authDataHeader), clientDataHash, auth_data_buf, sigbuf, sigder); + } { ret = cbor_encode_int(map, RESP_signature); diff --git a/fido2/extensions/extensions.c b/fido2/extensions/extensions.c index cc56d51..97bbe0a 100644 --- a/fido2/extensions/extensions.c +++ b/fido2/extensions/extensions.c @@ -8,6 +8,7 @@ #include #include "extensions.h" #include "u2f.h" +#include "ctap.h" #include "wallet.h" #include "solo.h" #include "device.h" @@ -57,7 +58,8 @@ int16_t bridge_u2f_to_extensions(uint8_t * _chal, uint8_t * _appid, uint8_t klen #elif defined(WALLET_EXTENSION) ret = bridge_u2f_to_wallet(_chal, _appid, klen, keyh); #else - ret = bridge_u2f_to_solo(_chal, _appid, klen, keyh); + ret = bridge_u2f_to_solo(sig, keyh, klen); + u2f_response_writeback(sig,72); #endif if (ret != 0) @@ -74,6 +76,21 @@ int16_t bridge_u2f_to_extensions(uint8_t * _chal, uint8_t * _appid, uint8_t klen return U2F_SW_NO_ERROR; } +// Returns 1 if this is a extension request. +// Else 0 if nothing is done. +int16_t extend_fido2(CredentialId * credid, uint8_t * output) +{ + if (is_extension_request((uint8_t*)credid, sizeof(CredentialId))) + { + bridge_u2f_to_solo(output, (uint8_t*)credid, sizeof(CredentialId)); + return 1; + } + else + { + return 0; + } +} + int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len) { @@ -93,7 +110,7 @@ int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len) { rcode = U2F_SW_WRONG_DATA; } - printf1(TAG_EXT,"Ignoring U2F request\n"); + printf1(TAG_EXT,"Ignoring U2F check request\n"); dump_hex1(TAG_EXT, (uint8_t *) &auth->kh, auth->khl); goto end; } @@ -102,7 +119,7 @@ int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len) if ( ! is_extension_request((uint8_t *) &auth->kh, auth->khl)) // Pin requests { rcode = U2F_SW_WRONG_PAYLOAD; - printf1(TAG_EXT, "Ignoring U2F request\n"); + printf1(TAG_EXT, "Ignoring U2F auth request\n"); dump_hex1(TAG_EXT, (uint8_t *) &auth->kh, auth->khl); goto end; } diff --git a/fido2/extensions/extensions.h b/fido2/extensions/extensions.h index 86a0f54..ea871a5 100644 --- a/fido2/extensions/extensions.h +++ b/fido2/extensions/extensions.h @@ -10,6 +10,10 @@ int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len); +int16_t extend_fido2(CredentialId * credid, uint8_t * output); + int bootloader_bridge(int klen, uint8_t * keyh); +int is_extension_request(uint8_t * kh, int len); + #endif /* EXTENSIONS_H_ */ diff --git a/fido2/extensions/solo.c b/fido2/extensions/solo.c index eff6eef..4637b89 100644 --- a/fido2/extensions/solo.c +++ b/fido2/extensions/solo.c @@ -31,27 +31,26 @@ #include "log.h" #include APP_CONFIG -int16_t bridge_u2f_to_solo(uint8_t * _chal, uint8_t * _appid, uint8_t klen, uint8_t * keyh) +// output must be at least 72 bytes +int16_t bridge_u2f_to_solo(uint8_t * output, uint8_t * keyh, int keylen) { - static uint8_t msg_buf[72]; int8_t ret = 0; wallet_request * req = (wallet_request *) keyh; - printf1(TAG_WALLET, "u2f-solo [%d]: ", klen); dump_hex1(TAG_WALLET, keyh, klen); + printf1(TAG_WALLET, "u2f-solo [%d]: ", keylen); dump_hex1(TAG_WALLET, keyh, keylen); switch(req->operation) { case WalletVersion: - msg_buf[0] = SOLO_VERSION_MAJ; - msg_buf[1] = SOLO_VERSION_MIN; - msg_buf[2] = SOLO_VERSION_PATCH; - u2f_response_writeback(msg_buf, 3); + output[0] = SOLO_VERSION_MAJ; + output[1] = SOLO_VERSION_MIN; + output[2] = SOLO_VERSION_PATCH; break; case WalletRng: printf1(TAG_WALLET,"SoloRng\n"); - ret = ctap_generate_rng(msg_buf, 72); + ret = ctap_generate_rng(output, 72); if (ret != 1) { printf1(TAG_WALLET,"Rng failed\n"); @@ -60,7 +59,6 @@ int16_t bridge_u2f_to_solo(uint8_t * _chal, uint8_t * _appid, uint8_t klen, uint } ret = 0; - u2f_response_writeback((uint8_t *)msg_buf,72); break; default: diff --git a/fido2/extensions/solo.h b/fido2/extensions/solo.h index 04e9d8d..ae6574f 100644 --- a/fido2/extensions/solo.h +++ b/fido2/extensions/solo.h @@ -22,6 +22,6 @@ #ifndef SOLO_H_ #define SOLO_H_ -int16_t bridge_u2f_to_solo(uint8_t * _chal, uint8_t * _appid, uint8_t klen, uint8_t * keyh); +int16_t bridge_u2f_to_solo(uint8_t * output, uint8_t * keyh, int keylen); #endif