Enable enterprise attestation through VendorConfig.
Add a subcommand to enable through pico-tool. Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -38,8 +38,8 @@ int cbor_config(const uint8_t *data, size_t len) {
|
|||||||
CborParser parser;
|
CborParser parser;
|
||||||
CborValue map;
|
CborValue map;
|
||||||
CborError error = CborNoError;
|
CborError error = CborNoError;
|
||||||
uint64_t subcommand = 0, pinUvAuthProtocol = 0, vendorCommandId = 0, newMinPinLength = 0, vendorParam = 0;
|
uint64_t subcommand = 0, pinUvAuthProtocol = 0, vendorCommandId = 0, newMinPinLength = 0, vendorParamInt = 0;
|
||||||
CborByteString pinUvAuthParam = { 0 }, vendorAutCt = { 0 };
|
CborByteString pinUvAuthParam = { 0 }, vendorParamByteString = { 0 };
|
||||||
CborCharString minPinLengthRPIDs[32] = { 0 };
|
CborCharString minPinLengthRPIDs[32] = { 0 };
|
||||||
size_t resp_size = 0, raw_subpara_len = 0, minPinLengthRPIDs_len = 0;
|
size_t resp_size = 0, raw_subpara_len = 0, minPinLengthRPIDs_len = 0;
|
||||||
CborEncoder encoder;
|
CborEncoder encoder;
|
||||||
@@ -74,10 +74,10 @@ int cbor_config(const uint8_t *data, size_t len) {
|
|||||||
CBOR_FIELD_GET_UINT(vendorCommandId, 2);
|
CBOR_FIELD_GET_UINT(vendorCommandId, 2);
|
||||||
}
|
}
|
||||||
else if (subpara == 0x02) {
|
else if (subpara == 0x02) {
|
||||||
CBOR_FIELD_GET_BYTES(vendorAutCt, 2);
|
CBOR_FIELD_GET_BYTES(vendorParamByteString, 2);
|
||||||
}
|
}
|
||||||
else if (subpara == 0x03) {
|
else if (subpara == 0x03) {
|
||||||
CBOR_FIELD_GET_UINT(vendorParam, 2);
|
CBOR_FIELD_GET_UINT(vendorParamInt, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (subcommand == 0x03) { // Extensions
|
else if (subcommand == 0x03) { // Extensions
|
||||||
@@ -147,8 +147,7 @@ int cbor_config(const uint8_t *data, size_t len) {
|
|||||||
vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS ||
|
vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS ||
|
||||||
vendorCommandId == CTAP_CONFIG_PHY_OPTS);
|
vendorCommandId == CTAP_CONFIG_PHY_OPTS);
|
||||||
#endif
|
#endif
|
||||||
if (vendorCommandId == CTAP_CONFIG_AUT_DISABLE)
|
if (vendorCommandId == CTAP_CONFIG_AUT_DISABLE){
|
||||||
{
|
|
||||||
if (!file_has_data(ef_keydev_enc)) {
|
if (!file_has_data(ef_keydev_enc)) {
|
||||||
CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED);
|
CBOR_ERROR(CTAP2_ERR_NOT_ALLOWED);
|
||||||
}
|
}
|
||||||
@@ -169,7 +168,7 @@ int cbor_config(const uint8_t *data, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mbedtls_chachapoly_context chatx;
|
mbedtls_chachapoly_context chatx;
|
||||||
int ret = mse_decrypt_ct(vendorAutCt.data, vendorAutCt.len);
|
int ret = mse_decrypt_ct(vendorParamByteString.data, vendorParamByteString.len);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
|
CBOR_ERROR(CTAP1_ERR_INVALID_PARAMETER);
|
||||||
}
|
}
|
||||||
@@ -177,7 +176,7 @@ int cbor_config(const uint8_t *data, size_t len) {
|
|||||||
uint8_t key_dev_enc[12 + 32 + 16];
|
uint8_t key_dev_enc[12 + 32 + 16];
|
||||||
random_gen(NULL, key_dev_enc, 12);
|
random_gen(NULL, key_dev_enc, 12);
|
||||||
mbedtls_chachapoly_init(&chatx);
|
mbedtls_chachapoly_init(&chatx);
|
||||||
mbedtls_chachapoly_setkey(&chatx, vendorAutCt.data);
|
mbedtls_chachapoly_setkey(&chatx, vendorParamByteString.data);
|
||||||
ret = mbedtls_chachapoly_encrypt_and_tag(&chatx, file_get_size(ef_keydev), key_dev_enc, NULL, 0, file_get_data(ef_keydev), key_dev_enc + 12, key_dev_enc + 12 + file_get_size(ef_keydev));
|
ret = mbedtls_chachapoly_encrypt_and_tag(&chatx, file_get_size(ef_keydev), key_dev_enc, NULL, 0, file_get_data(ef_keydev), key_dev_enc + 12, key_dev_enc + 12 + file_get_size(ef_keydev));
|
||||||
mbedtls_chachapoly_free(&chatx);
|
mbedtls_chachapoly_free(&chatx);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@@ -193,20 +192,20 @@ int cbor_config(const uint8_t *data, size_t len) {
|
|||||||
|
|
||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
else if (vendorCommandId == CTAP_CONFIG_PHY_VIDPID) {
|
else if (vendorCommandId == CTAP_CONFIG_PHY_VIDPID) {
|
||||||
phy_data.vid = (vendorParam >> 16) & 0xFFFF;
|
phy_data.vid = (vendorParamInt >> 16) & 0xFFFF;
|
||||||
phy_data.pid = vendorParam & 0xFFFF;
|
phy_data.pid = vendorParamInt & 0xFFFF;
|
||||||
phy_data.vidpid_present = true;
|
phy_data.vidpid_present = true;
|
||||||
}
|
}
|
||||||
else if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO) {
|
else if (vendorCommandId == CTAP_CONFIG_PHY_LED_GPIO) {
|
||||||
phy_data.led_gpio = (uint8_t)vendorParam;
|
phy_data.led_gpio = (uint8_t)vendorParamInt;
|
||||||
phy_data.led_gpio_present = true;
|
phy_data.led_gpio_present = true;
|
||||||
}
|
}
|
||||||
else if (vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) {
|
else if (vendorCommandId == CTAP_CONFIG_PHY_LED_BTNESS) {
|
||||||
phy_data.led_brightness = (uint8_t)vendorParam;
|
phy_data.led_brightness = (uint8_t)vendorParamInt;
|
||||||
phy_data.led_brightness_present = true;
|
phy_data.led_brightness_present = true;
|
||||||
}
|
}
|
||||||
else if (vendorCommandId == CTAP_CONFIG_PHY_OPTS) {
|
else if (vendorCommandId == CTAP_CONFIG_PHY_OPTS) {
|
||||||
phy_data.opts = (uint16_t)vendorParam;
|
phy_data.opts = (uint16_t)vendorParamInt;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION);
|
CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION);
|
||||||
@@ -215,6 +214,16 @@ int cbor_config(const uint8_t *data, size_t len) {
|
|||||||
CBOR_ERROR(CTAP2_ERR_PROCESSING);
|
CBOR_ERROR(CTAP2_ERR_PROCESSING);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if (vendorCommandId == CTAP_CONFIG_EA_UPLOAD) {
|
||||||
|
if (vendorParamByteString.present == false) {
|
||||||
|
CBOR_ERROR(CTAP2_ERR_MISSING_PARAMETER);
|
||||||
|
}
|
||||||
|
file_t *ef_ee_ea = search_by_fid(EF_EE_DEV_EA, NULL, SPECIFY_EF);
|
||||||
|
if (ef_ee_ea) {
|
||||||
|
file_put_data(ef_ee_ea, vendorParamByteString.data, (uint16_t)vendorParamByteString.len);
|
||||||
|
}
|
||||||
|
low_flash_available();
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
CBOR_ERROR(CTAP2_ERR_INVALID_SUBCOMMAND);
|
CBOR_ERROR(CTAP2_ERR_INVALID_SUBCOMMAND);
|
||||||
}
|
}
|
||||||
@@ -265,7 +274,7 @@ int cbor_config(const uint8_t *data, size_t len) {
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
CBOR_FREE_BYTE_STRING(pinUvAuthParam);
|
CBOR_FREE_BYTE_STRING(pinUvAuthParam);
|
||||||
CBOR_FREE_BYTE_STRING(vendorAutCt);
|
CBOR_FREE_BYTE_STRING(vendorParamByteString);
|
||||||
for (size_t i = 0; i < minPinLengthRPIDs_len; i++) {
|
for (size_t i = 0; i < minPinLengthRPIDs_len; i++) {
|
||||||
CBOR_FREE_BYTE_STRING(minPinLengthRPIDs[i]);
|
CBOR_FREE_BYTE_STRING(minPinLengthRPIDs[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ typedef struct {
|
|||||||
|
|
||||||
#define CTAP_CONFIG_AUT_ENABLE 0x03e43f56b34285e2
|
#define CTAP_CONFIG_AUT_ENABLE 0x03e43f56b34285e2
|
||||||
#define CTAP_CONFIG_AUT_DISABLE 0x1831a40f04a25ed9
|
#define CTAP_CONFIG_AUT_DISABLE 0x1831a40f04a25ed9
|
||||||
|
#define CTAP_CONFIG_EA_UPLOAD 0x66f2a674c29a8dcf
|
||||||
#ifndef ENABLE_EMULATION
|
#ifndef ENABLE_EMULATION
|
||||||
#define CTAP_CONFIG_PHY_VIDPID 0x6fcb19b0cbe3acfa
|
#define CTAP_CONFIG_PHY_VIDPID 0x6fcb19b0cbe3acfa
|
||||||
#define CTAP_CONFIG_PHY_LED_BTNESS 0x76a85945985d02fd
|
#define CTAP_CONFIG_PHY_LED_BTNESS 0x76a85945985d02fd
|
||||||
|
|||||||
@@ -75,16 +75,17 @@ def get_pki_data(url, data=None, method='GET'):
|
|||||||
class VendorConfig(Config):
|
class VendorConfig(Config):
|
||||||
class PARAM(IntEnum):
|
class PARAM(IntEnum):
|
||||||
VENDOR_COMMAND_ID = 0x01
|
VENDOR_COMMAND_ID = 0x01
|
||||||
VENDOR_AUT_CT = 0x02
|
VENDOR_PARAM_BYTESTRING = 0x02
|
||||||
VENDOR_PARAM = 0x03
|
VENDOR_PARAM_INT = 0x03
|
||||||
|
|
||||||
class CMD(IntEnum):
|
class CMD(IntEnum):
|
||||||
CONFIG_AUT_ENABLE = 0x03e43f56b34285e2
|
CONFIG_AUT_ENABLE = 0x03e43f56b34285e2
|
||||||
CONFIG_AUT_DISABLE = 0x1831a40f04a25ed9
|
CONFIG_AUT_DISABLE = 0x1831a40f04a25ed9
|
||||||
|
CONFIG_EA_UPLOAD = 0x66f2a674c29a8dcf
|
||||||
CONFIG_PHY_VIDPID = 0x6fcb19b0cbe3acfa
|
CONFIG_PHY_VIDPID = 0x6fcb19b0cbe3acfa
|
||||||
CONFIG_PHY_OPTS = 0x969f3b09eceb805f
|
|
||||||
CONFIG_PHY_LED_GPIO = 0x7b392a394de9f948
|
|
||||||
CONFIG_PHY_LED_BTNESS = 0x76a85945985d02fd
|
CONFIG_PHY_LED_BTNESS = 0x76a85945985d02fd
|
||||||
|
CONFIG_PHY_LED_GPIO = 0x7b392a394de9f948
|
||||||
|
CONFIG_PHY_OPTS = 0x969f3b09eceb805f
|
||||||
|
|
||||||
class RESP(IntEnum):
|
class RESP(IntEnum):
|
||||||
KEY_AGREEMENT = 0x01
|
KEY_AGREEMENT = 0x01
|
||||||
@@ -97,7 +98,7 @@ class VendorConfig(Config):
|
|||||||
Config.CMD.VENDOR_PROTOTYPE,
|
Config.CMD.VENDOR_PROTOTYPE,
|
||||||
{
|
{
|
||||||
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_AUT_ENABLE,
|
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_AUT_ENABLE,
|
||||||
VendorConfig.PARAM.VENDOR_AUT_CT: ct
|
VendorConfig.PARAM.VENDOR_PARAM_BYTESTRING: ct
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -114,7 +115,7 @@ class VendorConfig(Config):
|
|||||||
Config.CMD.VENDOR_PROTOTYPE,
|
Config.CMD.VENDOR_PROTOTYPE,
|
||||||
{
|
{
|
||||||
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_VIDPID,
|
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_VIDPID,
|
||||||
VendorConfig.PARAM.VENDOR_PARAM: (vid & 0xFFFF) << 16 | pid
|
VendorConfig.PARAM.VENDOR_PARAM_INT: (vid & 0xFFFF) << 16 | pid
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -123,7 +124,7 @@ class VendorConfig(Config):
|
|||||||
Config.CMD.VENDOR_PROTOTYPE,
|
Config.CMD.VENDOR_PROTOTYPE,
|
||||||
{
|
{
|
||||||
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_LED_GPIO,
|
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_LED_GPIO,
|
||||||
VendorConfig.PARAM.VENDOR_PARAM: gpio
|
VendorConfig.PARAM.VENDOR_PARAM_INT: gpio
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -132,7 +133,7 @@ class VendorConfig(Config):
|
|||||||
Config.CMD.VENDOR_PROTOTYPE,
|
Config.CMD.VENDOR_PROTOTYPE,
|
||||||
{
|
{
|
||||||
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_LED_BTNESS,
|
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_LED_BTNESS,
|
||||||
VendorConfig.PARAM.VENDOR_PARAM: brightness
|
VendorConfig.PARAM.VENDOR_PARAM_INT: brightness
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -141,7 +142,16 @@ class VendorConfig(Config):
|
|||||||
Config.CMD.VENDOR_PROTOTYPE,
|
Config.CMD.VENDOR_PROTOTYPE,
|
||||||
{
|
{
|
||||||
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_OPTS,
|
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_PHY_OPTS,
|
||||||
VendorConfig.PARAM.VENDOR_PARAM: opts
|
VendorConfig.PARAM.VENDOR_PARAM_INT: opts
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
def upload_ea(self, der):
|
||||||
|
self._call(
|
||||||
|
Config.CMD.VENDOR_PROTOTYPE,
|
||||||
|
{
|
||||||
|
VendorConfig.PARAM.VENDOR_COMMAND_ID: VendorConfig.CMD.CONFIG_EA_UPLOAD,
|
||||||
|
VendorConfig.PARAM.VENDOR_PARAM_BYTESTRING: der
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -242,7 +252,6 @@ class Vendor:
|
|||||||
DISABLE = 0x02
|
DISABLE = 0x02
|
||||||
KEY_AGREEMENT = 0x01
|
KEY_AGREEMENT = 0x01
|
||||||
EA_CSR = 0x01
|
EA_CSR = 0x01
|
||||||
EA_UPLOAD = 0x02
|
|
||||||
|
|
||||||
class RESP(IntEnum):
|
class RESP(IntEnum):
|
||||||
PARAM = 0x01
|
PARAM = 0x01
|
||||||
@@ -430,13 +439,7 @@ class Vendor:
|
|||||||
)[Vendor.RESP.PARAM]
|
)[Vendor.RESP.PARAM]
|
||||||
|
|
||||||
def upload_ea(self, der):
|
def upload_ea(self, der):
|
||||||
self._call(
|
self.vcfg.upload_ea(der)
|
||||||
Vendor.CMD.VENDOR_EA,
|
|
||||||
Vendor.SUBCMD.EA_UPLOAD,
|
|
||||||
{
|
|
||||||
Vendor.PARAM.PARAM: der
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
def vidpid(self, vid, pid):
|
def vidpid(self, vid, pid):
|
||||||
return self.vcfg.vidpid(vid, pid)
|
return self.vcfg.vidpid(vid, pid)
|
||||||
@@ -480,6 +483,9 @@ class Vendor:
|
|||||||
)
|
)
|
||||||
return { 'free': resp[1], 'used': resp[2], 'total': resp[3], 'files': resp[4], 'size': resp[5] }
|
return { 'free': resp[1], 'used': resp[2], 'total': resp[3], 'files': resp[4], 'size': resp[5] }
|
||||||
|
|
||||||
|
def enable_enterprise_attestation(self):
|
||||||
|
self.vcfg.enable_enterprise_attestation()
|
||||||
|
|
||||||
def parse_args():
|
def parse_args():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
subparser = parser.add_subparsers(title="commands", dest="command")
|
subparser = parser.add_subparsers(title="commands", dest="command")
|
||||||
@@ -492,7 +498,7 @@ def parse_args():
|
|||||||
parser_backup.add_argument('filename', help='File to save or load the backup.')
|
parser_backup.add_argument('filename', help='File to save or load the backup.')
|
||||||
|
|
||||||
parser_attestation = subparser.add_parser('attestation', help='Manages Enterprise Attestation')
|
parser_attestation = subparser.add_parser('attestation', help='Manages Enterprise Attestation')
|
||||||
parser_attestation.add_argument('subcommand', choices=['csr'])
|
parser_attestation.add_argument('subcommand', choices=['csr','enable'])
|
||||||
parser_attestation.add_argument('--filename', help='Uploads the certificate filename to the device as enterprise attestation certificate. If not provided, it will generate an enterprise attestation certificate automatically.')
|
parser_attestation.add_argument('--filename', help='Uploads the certificate filename to the device as enterprise attestation certificate. If not provided, it will generate an enterprise attestation certificate automatically.')
|
||||||
|
|
||||||
parser_phy = subparser.add_parser('phy', help='Set PHY options.')
|
parser_phy = subparser.add_parser('phy', help='Set PHY options.')
|
||||||
@@ -513,7 +519,7 @@ def parse_args():
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
return args
|
return args
|
||||||
|
|
||||||
def secure(vdr, args):
|
def secure(vdr: Vendor, args):
|
||||||
if (args.subcommand == 'enable'):
|
if (args.subcommand == 'enable'):
|
||||||
vdr.enable_device_aut()
|
vdr.enable_device_aut()
|
||||||
elif (args.subcommand == 'unlock'):
|
elif (args.subcommand == 'unlock'):
|
||||||
@@ -521,13 +527,13 @@ def secure(vdr, args):
|
|||||||
elif (args.subcommand == 'disable'):
|
elif (args.subcommand == 'disable'):
|
||||||
vdr.disable_device_aut()
|
vdr.disable_device_aut()
|
||||||
|
|
||||||
def backup(vdr, args):
|
def backup(vdr: Vendor, args):
|
||||||
if (args.subcommand == 'save'):
|
if (args.subcommand == 'save'):
|
||||||
vdr.backup_save(args.filename)
|
vdr.backup_save(args.filename)
|
||||||
elif (args.subcommand == 'load'):
|
elif (args.subcommand == 'load'):
|
||||||
vdr.backup_load(args.filename)
|
vdr.backup_load(args.filename)
|
||||||
|
|
||||||
def attestation(vdr, args):
|
def attestation(vdr: Vendor, args):
|
||||||
if (args.subcommand == 'csr'):
|
if (args.subcommand == 'csr'):
|
||||||
if (args.filename is None):
|
if (args.filename is None):
|
||||||
csr = x509.load_der_x509_csr(vdr.csr())
|
csr = x509.load_der_x509_csr(vdr.csr())
|
||||||
@@ -542,8 +548,10 @@ def attestation(vdr, args):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
cert = x509.load_pem_x509_certificate(dataf)
|
cert = x509.load_pem_x509_certificate(dataf)
|
||||||
vdr.upload_ea(cert.public_bytes(Encoding.DER))
|
vdr.upload_ea(cert.public_bytes(Encoding.DER))
|
||||||
|
elif (args.subcommand == 'enable'):
|
||||||
|
vdr.enable_enterprise_attestation()
|
||||||
|
|
||||||
def phy(vdr, args):
|
def phy(vdr: Vendor, args):
|
||||||
val = args.value if 'value' in args else None
|
val = args.value if 'value' in args else None
|
||||||
if (val):
|
if (val):
|
||||||
if (args.subcommand == 'vidpid'):
|
if (args.subcommand == 'vidpid'):
|
||||||
@@ -567,7 +575,7 @@ def phy(vdr, args):
|
|||||||
else:
|
else:
|
||||||
print('Command executed successfully. Please, restart your Pico Key.')
|
print('Command executed successfully. Please, restart your Pico Key.')
|
||||||
|
|
||||||
def memory(vdr, args):
|
def memory(vdr: Vendor, args):
|
||||||
mem = vdr.memory()
|
mem = vdr.memory()
|
||||||
print(f'Memory usage:')
|
print(f'Memory usage:')
|
||||||
print(f'\tFree: {mem["free"]/1024:.2f} kilobytes ({mem["free"]*100/mem["total"]:.2f}%)')
|
print(f'\tFree: {mem["free"]/1024:.2f} kilobytes ({mem["free"]*100/mem["total"]:.2f}%)')
|
||||||
|
|||||||
Reference in New Issue
Block a user