Compare commits

...

7 Commits

Author SHA1 Message Date
Conor Patrick
5b2d85bbbf bugfix hid cancel 2019-12-01 17:55:17 -05:00
Conor Patrick
522a18a687 update metadata statements 2019-12-01 17:26:15 -05:00
Conor Patrick
4370c9145e pin fido2 dependency 2019-12-01 17:19:21 -05:00
Conor Patrick
e2c34fd53d adjust default impl 2019-12-01 16:59:12 -05:00
Conor Patrick
f35d79ad03 support different aaguid's in cert for different solo models 2019-12-01 16:38:37 -05:00
Conor Patrick
f70c856998 overwrite x509 fields for tap or somu 2019-12-01 15:17:33 -05:00
Conor Patrick
2170036672 update solo_cert to include aaguid field 2019-12-01 14:32:10 -05:00
13 changed files with 194 additions and 46 deletions

View File

@ -69,6 +69,8 @@ uint8_t ctap_get_info(CborEncoder * encoder)
CborEncoder map;
CborEncoder options;
CborEncoder pins;
uint8_t aaguid[16];
device_read_aaguid(aaguid);
ret = cbor_encoder_create_map(encoder, &map, 6);
check_ret(ret);
@ -105,7 +107,7 @@ uint8_t ctap_get_info(CborEncoder * encoder)
ret = cbor_encode_uint(&map, RESP_aaguid);
check_ret(ret);
{
ret = cbor_encode_byte_string(&map, CTAP_AAGUID, 16);
ret = cbor_encode_byte_string(&map, aaguid, 16);
check_ret(ret);
}
@ -505,7 +507,7 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au
cbor_encoder_init(&cose_key, cose_key_buf, *len - sizeof(CTAP_authData), 0);
memmove(authData->attest.aaguid, CTAP_AAGUID, 16);
device_read_aaguid(authData->attest.aaguid);
authData->attest.credLenL = sizeof(CredentialId) & 0x00FF;
authData->attest.credLenH = (sizeof(CredentialId) & 0xFF00) >> 8;
@ -630,11 +632,17 @@ int ctap_calculate_signature(uint8_t * data, int datalen, uint8_t * clientDataHa
uint8_t ctap_add_attest_statement(CborEncoder * map, uint8_t * sigder, int len)
{
int ret;
uint8_t cert[1024];
uint16_t cert_size = device_attestation_cert_der_get_size();
if (cert_size > sizeof(cert)){
printf2(TAG_ERR,"Certificate is too large for CTAP2 buffer\r\n");
return CTAP2_ERR_PROCESSING;
}
device_attestation_read_cert_der(cert);
CborEncoder stmtmap;
CborEncoder x5carr;
ret = cbor_encode_int(map,RESP_attStmt);
check_ret(ret);
ret = cbor_encoder_create_map(map, &stmtmap, 3);
@ -657,7 +665,7 @@ uint8_t ctap_add_attest_statement(CborEncoder * map, uint8_t * sigder, int len)
ret = cbor_encoder_create_array(&stmtmap, &x5carr, 1);
check_ret(ret);
{
ret = cbor_encode_byte_string(&x5carr, attestation_cert_der, device_attestation_cert_der_get_size());
ret = cbor_encode_byte_string(&x5carr, cert, device_attestation_cert_der_get_size());
check_ret(ret);
ret = cbor_encoder_close_container(&stmtmap, &x5carr);
check_ret(ret);

View File

@ -19,9 +19,6 @@
#define CTAP_VENDOR_FIRST 0x40
#define CTAP_VENDOR_LAST 0xBF
// AAGUID For Solo
#define CTAP_AAGUID ((uint8_t*)"\x88\x76\x63\x1b\xd4\xa0\x42\x7f\x57\x73\x0e\xc7\x1c\x9e\x02\x79")
#define MC_clientDataHash 0x01
#define MC_rp 0x02
#define MC_user 0x03

View File

@ -635,6 +635,9 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
status = ctap_request(ctap_buffer, len, &ctap_resp);
wb.bcnt = (ctap_resp.length+1);
wb.cid = cid;
wb.cmd = cmd;
timestamp();
@ -665,6 +668,9 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
u2f_request((struct u2f_request_apdu*)ctap_buffer, &ctap_resp);
wb.bcnt = (ctap_resp.length);
wb.cid = cid;
wb.cmd = cmd;
ctaphid_write(&wb, ctap_resp.data, ctap_resp.length);
ctaphid_write(&wb, NULL, 0);

View File

@ -59,7 +59,10 @@ static uint8_t _attestation_cert_der[] =
"\x06\xf1\xe3\xab\x16\x21\x8e\xd8\xc0\x14\xaf\x09\x4f\x5b\x73\xef\x5e\x9e\x4b\xe7"
"\x35\xeb\xdd\x9b\x6d\x8f\x7d\xf3\xc4\x3a\xd7";
__attribute__((weak)) const uint8_t * attestation_cert_der = _attestation_cert_der;
__attribute__((weak)) void device_attestation_read_cert_der(uint8_t * dst){
memmove(dst, _attestation_cert_der, device_attestation_cert_der_get_size());
}
__attribute__((weak)) uint8_t * device_get_attestation_key(){
static uint8_t attestation_key[] =
@ -199,3 +202,8 @@ __attribute__((weak)) void ctap_overwrite_rk(int index, CTAP_residentKey * rk)
}
}
__attribute__((weak)) void device_read_aaguid(uint8_t * dst){
uint8_t * aaguid = (uint8_t *)"\x00\x76\x63\x1b\xd4\xa0\x42\x7f\x57\x73\x0e\xc7\x1c\x9e\x02\x79";
memmove(dst, aaguid, 16);
}

View File

@ -199,13 +199,21 @@ int device_is_nfc();
*/
uint8_t * device_get_attestation_key();
/** Pointer to a ASN.1/DER encoded byte array of the attestation certificate.
/** Read the device's attestation certificate into buffer @dst.
* @param dst the destination to write the certificate.
*
* The size of the certificate can be retrieved using `device_attestation_cert_der_get_size()`.
*/
extern const uint8_t * attestation_cert_der;
void device_attestation_read_cert_der(uint8_t * dst);
/** Returns the size in bytes of attestation_cert_der.
* @return number of bytes in attestation_cert_der, not including any C string null byte.
*/
uint16_t device_attestation_cert_der_get_size();
/** Read the device's 16 byte AAGUID into a buffer.
* @param dst buffer to write 16 byte AAGUID into.
* */
void device_read_aaguid(uint8_t * dst);
#endif

View File

@ -299,7 +299,7 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
static int16_t u2f_register(struct u2f_register_request * req)
{
uint8_t i[] = {0x0,U2F_EC_FMT_UNCOMPRESSED};
uint8_t cert[1024];
struct u2f_key_handle key_handle;
uint8_t pubkey[64];
uint8_t hash[32];
@ -308,6 +308,11 @@ static int16_t u2f_register(struct u2f_register_request * req)
const uint16_t attest_size = device_attestation_cert_der_get_size();
if (attest_size > sizeof(cert)){
printf2(TAG_ERR,"Certificate is too large for buffer\r\n");
return U2F_SW_INSUFFICIENT_MEMORY;
}
if ( ! ctap_user_presence_test(750))
{
return U2F_SW_CONDITIONS_NOT_SATISFIED;
@ -341,7 +346,8 @@ static int16_t u2f_register(struct u2f_register_request * req)
u2f_response_writeback(i,1);
u2f_response_writeback((uint8_t*)&key_handle,U2F_KEY_HANDLE_SIZE);
u2f_response_writeback(attestation_cert_der,attest_size);
device_attestation_read_cert_der(cert);
u2f_response_writeback(cert,attest_size);
dump_signature_der(sig);

View File

@ -15,8 +15,7 @@
"authenticationAlgorithm": 1,
"publicKeyAlgAndEncoding": 260,
"attestationTypes": [
15879,
15880
15879
],
"userVerificationDetails": [
[

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5,12 +5,16 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdint.h>
#include <string.h>
#include "crypto.h"
#include "memory_layout.h"
#include "device.h"
#include "sense.h"
#include "log.h"
const uint8_t attestation_solo_cert_der[] =
"\x30\x82\x02\xe1\x30\x82\x02\x88\xa0\x03\x02\x01\x02\x02\x01\x01\x30\x0a\x06\x08"
"\x30\x82\x03\x03\x30\x82\x02\xaa\xa0\x03\x02\x01\x02\x02\x01\x01\x30\x0a\x06\x08"
"\x2a\x86\x48\xce\x3d\x04\x03\x02\x30\x81\x80\x31\x0b\x30\x09\x06\x03\x55\x04\x06"
"\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4d\x61\x72\x79\x6c"
"\x61\x6e\x64\x31\x12\x30\x10\x06\x03\x55\x04\x0a\x0c\x09\x53\x6f\x6c\x6f\x20\x4b"
@ -18,36 +22,37 @@ const uint8_t attestation_solo_cert_der[] =
"\x41\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0c\x0c\x73\x6f\x6c\x6f\x6b\x65\x79\x73"
"\x2e\x63\x6f\x6d\x31\x21\x30\x1f\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16"
"\x12\x68\x65\x6c\x6c\x6f\x40\x73\x6f\x6c\x6f\x6b\x65\x79\x73\x2e\x63\x6f\x6d\x30"
"\x20\x17\x0d\x31\x38\x31\x31\x31\x31\x31\x32\x35\x32\x30\x30\x5a\x18\x0f\x32\x30"
"\x36\x38\x31\x30\x32\x39\x31\x32\x35\x32\x30\x30\x5a\x30\x81\x92\x31\x0b\x30\x09"
"\x20\x17\x0d\x31\x39\x31\x32\x30\x31\x31\x39\x32\x33\x34\x39\x5a\x18\x0f\x32\x30"
"\x36\x39\x31\x31\x31\x38\x31\x39\x32\x33\x34\x39\x5a\x30\x81\x91\x31\x0b\x30\x09"
"\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08"
"\x4d\x61\x72\x79\x6c\x61\x6e\x64\x31\x12\x30\x10\x06\x03\x55\x04\x0a\x0c\x09\x53"
"\x6f\x6c\x6f\x20\x4b\x65\x79\x73\x31\x22\x30\x20\x06\x03\x55\x04\x0b\x0c\x19\x41"
"\x75\x74\x68\x65\x6e\x74\x69\x63\x61\x74\x6f\x72\x20\x41\x74\x74\x65\x73\x74\x61"
"\x74\x69\x6f\x6e\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0c\x0c\x73\x6f\x6c\x6f\x6b"
"\x65\x79\x73\x2e\x63\x6f\x6d\x31\x21\x30\x1f\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01"
"\x09\x01\x16\x12\x68\x65\x6c\x6c\x6f\x40\x73\x6f\x6c\x6f\x6b\x65\x79\x73\x2e\x63"
"\x6f\x6d\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x22\xfe\x0f\xb5\x2a\x78\xbe\xc6\x45\x37\x1a"
"\x28\xa7\x57\x43\x49\xa4\x6f\x85\x4d\xca\x4e\x25\x1c\x9f\x75\x30\x3d\xbf\x10\xd5"
"\xd2\xd2\x0b\xb9\x69\x2c\xdd\xb2\x5c\x14\xd8\x39\x85\x12\xf6\x23\xee\x91\xba\xc6"
"\xac\xff\x4a\x1a\x27\xef\xe0\xc1\x54\x3f\xd4\xd9\xc5\xa3\x81\xdc\x30\x81\xd9\x30"
"\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x3b\xe6\xd2\xc0\x6f\xf2\xe7\xb0\x7c\x9d"
"\x9e\x28\xc0\x20\xb0\x0d\x07\xc8\x15\xc8\x30\x81\x9f\x06\x03\x55\x1d\x23\x04\x81"
"\x97\x30\x81\x94\xa1\x81\x86\xa4\x81\x83\x30\x81\x80\x31\x0b\x30\x09\x06\x03\x55"
"\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4d\x61\x72"
"\x79\x6c\x61\x6e\x64\x31\x12\x30\x10\x06\x03\x55\x04\x0a\x0c\x09\x53\x6f\x6c\x6f"
"\x20\x4b\x65\x79\x73\x31\x10\x30\x0e\x06\x03\x55\x04\x0b\x0c\x07\x52\x6f\x6f\x74"
"\x20\x43\x41\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0c\x0c\x73\x6f\x6c\x6f\x6b\x65"
"\x4d\x61\x72\x79\x6c\x61\x6e\x64\x31\x11\x30\x0f\x06\x03\x55\x04\x0a\x0c\x08\x53"
"\x6f\x6c\x6f\x4b\x65\x79\x73\x31\x22\x30\x20\x06\x03\x55\x04\x0b\x0c\x19\x41\x75"
"\x74\x68\x65\x6e\x74\x69\x63\x61\x74\x6f\x72\x20\x41\x74\x74\x65\x73\x74\x61\x74"
"\x69\x6f\x6e\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0c\x0c\x73\x6f\x6c\x6f\x6b\x65"
"\x79\x73\x2e\x63\x6f\x6d\x31\x21\x30\x1f\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09"
"\x01\x16\x12\x68\x65\x6c\x6c\x6f\x40\x73\x6f\x6c\x6f\x6b\x65\x79\x73\x2e\x63\x6f"
"\x6d\x82\x09\x00\xc4\x47\x63\x92\x8f\xf4\xbe\x8c\x30\x09\x06\x03\x55\x1d\x13\x04"
"\x02\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04\x04\x03\x02\x04\xf0\x30\x0a\x06\x08"
"\x2a\x86\x48\xce\x3d\x04\x03\x02\x03\x47\x00\x30\x44\x02\x20\x71\x10\x46\x2c\xf5"
"\x16\x18\x97\x55\xca\x64\x50\x3b\x69\xb2\xdf\x17\x71\xab\xad\x8e\xc0\xd6\xa6\x07"
"\x3d\x66\x8a\x3b\xbb\xfe\x61\x02\x20\x1e\x82\xef\xeb\x5e\x4e\x3a\x00\x84\x64\xd2"
"\xf8\x84\xc3\x78\x35\x93\x63\x81\x2e\xbe\xa6\x12\x32\x6e\x29\x90\xc8\x91\x4b\x71"
"\x52"
"\x6d\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce"
"\x3d\x03\x01\x07\x03\x42\x00\x04\x22\xfe\x0f\xb5\x2a\x78\xbe\xc6\x45\x37\x1a\x28"
"\xa7\x57\x43\x49\xa4\x6f\x85\x4d\xca\x4e\x25\x1c\x9f\x75\x30\x3d\xbf\x10\xd5\xd2"
"\xd2\x0b\xb9\x69\x2c\xdd\xb2\x5c\x14\xd8\x39\x85\x12\xf6\x23\xee\x91\xba\xc6\xac"
"\xff\x4a\x1a\x27\xef\xe0\xc1\x54\x3f\xd4\xd9\xc5\xa3\x81\xff\x30\x81\xfc\x30\x1d"
"\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x3b\xe6\xd2\xc0\x6f\xf2\xe7\xb0\x7c\x9d\x9e"
"\x28\xc0\x20\xb0\x0d\x07\xc8\x15\xc8\x30\x81\x9f\x06\x03\x55\x1d\x23\x04\x81\x97"
"\x30\x81\x94\xa1\x81\x86\xa4\x81\x83\x30\x81\x80\x31\x0b\x30\x09\x06\x03\x55\x04"
"\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4d\x61\x72\x79"
"\x6c\x61\x6e\x64\x31\x12\x30\x10\x06\x03\x55\x04\x0a\x0c\x09\x53\x6f\x6c\x6f\x20"
"\x4b\x65\x79\x73\x31\x10\x30\x0e\x06\x03\x55\x04\x0b\x0c\x07\x52\x6f\x6f\x74\x20"
"\x43\x41\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0c\x0c\x73\x6f\x6c\x6f\x6b\x65\x79"
"\x73\x2e\x63\x6f\x6d\x31\x21\x30\x1f\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01"
"\x16\x12\x68\x65\x6c\x6c\x6f\x40\x73\x6f\x6c\x6f\x6b\x65\x79\x73\x2e\x63\x6f\x6d"
"\x82\x09\x00\xc4\x47\x63\x92\x8f\xf4\xbe\x8c\x30\x09\x06\x03\x55\x1d\x13\x04\x02"
"\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04\x04\x03\x02\x04\xf0\x30\x21\x06\x0b\x2b"
"\x06\x01\x04\x01\x82\xe5\x1c\x01\x01\x04\x04\x12\x04\x10\x88\x76\x63\x1b\xd4\xa0"
"\x42\x7f\x57\x73\x0e\xc7\x1c\x9e\x02\x79\x30\x0a\x06\x08\x2a\x86\x48\xce\x3d\x04"
"\x03\x02\x03\x47\x00\x30\x44\x02\x20\x4d\xea\x09\x15\x6c\x86\x48\x57\x2a\xa8\x8d"
"\x87\xc3\xfa\xb6\x6b\x29\x9b\xfb\x8b\x4d\x4d\x29\x77\x5b\xa1\x04\x4c\x7f\x12\x8d"
"\x71\x02\x20\x47\x4c\x3d\xb2\xa1\x74\xe3\x9c\xfe\xe1\x23\xbf\xec\x47\x96\xf4\xe5"
"\x9b\x65\x76\xac\xc8\x69\x1d\xe2\x74\xff\x4e\xa4\xcf\x02\x6d"
;
const uint8_t attestation_hacker_cert_der[] =
@ -95,7 +100,6 @@ const uint8_t attestation_hacker_cert_der[] =
const uint16_t attestation_solo_cert_der_size = sizeof(attestation_solo_cert_der)-1;
const uint16_t attestation_hacker_cert_der_size = sizeof(attestation_hacker_cert_der)-1;
const uint8_t * attestation_cert_der = ((flash_attestation_page *)ATTESTATION_PAGE_ADDR)->attestation_cert;
uint8_t * device_get_attestation_key(){
flash_attestation_page * page =(flash_attestation_page *)ATTESTATION_PAGE_ADDR;
@ -106,3 +110,22 @@ uint16_t device_attestation_cert_der_get_size(){
uint16_t sz = (uint16_t)((flash_attestation_page *)ATTESTATION_PAGE_ADDR)->attestation_cert_size;
return sz;
}
void device_attestation_read_cert_der(uint8_t * dst){
const uint8_t * der = ((flash_attestation_page *)ATTESTATION_PAGE_ADDR)->attestation_cert;
uint16_t sz = device_attestation_cert_der_get_size();
memmove(dst, der, sz);
// Overwrite respective x509 fields if Tap or Somu.
if (memcmp(dst + 0x2c6, "\xea\x09\x15\x6c\x86\x48\x57\x2a\xa8\x8d", 10) == 0){
if (device_is_nfc()){
dst[0x2a2] = 0x89;//tap aaguid byte
memmove(dst + 0xac, "\x34\x33\x38\x5a\x18\x0f\x32\x30\x36\x39\x31\x31\x31\x38\x31\x39\x32\x34\x33\x38", 20);//tap-id
memmove(dst + 0x2c5, "\x6d\x7b\x41\x2b\xff\x57\xf0\x03\xbd\x5b\x39\x4a\xf7\xa9\x2d\x6d\xcb\x9e\x2d\x88\xbf\xb3\x93\xc5\x66\x3b\xd1\xbc\x34\xfa\x5c\x4c\x02\x20\x59\x01\x49\x39\x1b\xb7\xa9\x1c\xed\x49\x78\x4f\x92\xa9\x61\x14\xa5\x6e\x96\x3f\x29\x02\x93\xe0\x5d\xe2\x75\xd0\x60\xd9\x74\xc2", 66);//tap-sig
} else if (tsc_sensor_exists()) {
dst[0x2a2] = 0x98;//somu aaguid byte
memmove(dst + 0xac, "\x35\x30\x32\x5a\x18\x0f\x32\x30\x36\x39\x31\x31\x31\x38\x31\x39\x32\x35\x30\x32", 20);//somu-id
memmove(dst + 0x2c5, "\x4d\x08\xc8\x9d\xc4\x50\x49\x70\x48\x4d\xd0\x12\xd9\x7c\x62\x5e\x6b\xd3\x84\xd5\x36\x42\xfe\x86\x8e\x7a\x23\x59\xa0\x20\xf0\xc5\x02\x20\x5f\x70\x93\x61\x5a\xe4\x20\xcf\xb9\x8a\xf5\xdd\x87\xd0\x48\x6d\x7d\x59\xef\x9e\x0e\x11\xa3\x8e\xf7\xe3\xe2\xf5\x35\x37\x99\x1a", 66);//somu-sig
}
}
}

View File

@ -859,6 +859,17 @@ void boot_solo_bootloader(void)
}
void device_read_aaguid(uint8_t * dst){
uint8_t * aaguid = (uint8_t *)"\x88\x76\x63\x1b\xd4\xa0\x42\x7f\x57\x73\x0e\xc7\x1c\x9e\x02\x79";
memmove(dst, aaguid, 16);
if (device_is_nfc()){
dst[0] = 0x89;
}
else if (tsc_sensor_exists()){
dst[0] = 0x98;
}
dump_hex1(TAG_GREEN,dst, 16);
}
void _Error_Handler(char *file, int line)

View File

@ -67,7 +67,7 @@ typedef struct flash_memory_st flash_memory_st;
#include <assert.h>
static_assert(sizeof(flash_memory_st) == 256*1024, "Data structure doesn't match flash size");
#define ATTESTATION_CONFIGURED_TAG 0xaa551e78
#define ATTESTATION_CONFIGURED_TAG 0xaa551e79
struct flash_attestation_page{
uint8_t attestation_key[32];

View File

@ -1,5 +1,5 @@
ecdsa
fido2
fido2==0.7.3
intelhex
pyserial
solo-python