diff --git a/src/openpgp/files.c b/src/openpgp/files.c index 072b6d7..d7495fa 100644 --- a/src/openpgp/files.c +++ b/src/openpgp/files.c @@ -129,9 +129,12 @@ file_t file_entries[] = { /* 42 */ { .fid = EF_PW1_RETRIES, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, /* 43 */ { .fid = EF_RC_RETRIES, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, /* 44 */ { .fid = EF_PW3_RETRIES, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, + /* 45 */ { .fid = EF_ALGO_PRIV1, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 46 */ { .fid = EF_ALGO_PRIV2, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 47 */ { .fid = EF_ALGO_PRIV3, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 45 */ { .fid = 0x0000, .parent = 0, .name = openpgp_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 46 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = ACL_NONE } //end + /* 48 */ { .fid = 0x0000, .parent = 0, .name = openpgp_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 49 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = ACL_NONE } //end }; const file_t *MF = &file_entries[0]; diff --git a/src/openpgp/files.h b/src/openpgp/files.h index ad2ce0e..af3ef5e 100644 --- a/src/openpgp/files.h +++ b/src/openpgp/files.h @@ -27,6 +27,9 @@ #define EF_PW1_RETRIES 0x1084 #define EF_RC_RETRIES 0x1085 #define EF_PW3_RETRIES 0x1086 +#define EF_ALGO_PRIV1 0x10c1 +#define EF_ALGO_PRIV2 0x10c2 +#define EF_ALGO_PRIV3 0x10c3 #define EF_EXT_HEADER 0x004d //C #define EF_FULL_AID 0x004f //S diff --git a/src/openpgp/openpgp.c b/src/openpgp/openpgp.c index 2c3df06..a7745d3 100644 --- a/src/openpgp/openpgp.c +++ b/src/openpgp/openpgp.c @@ -437,37 +437,47 @@ int parse_algo(const uint8_t *algo, uint16_t tag) { } int parse_algoinfo(const file_t *f, int mode) { - uint8_t *lp = NULL; uint8_t datalen = 0; if (f->fid == EF_ALGO_INFO) { res_APDU[res_APDU_size++] = EF_ALGO_INFO & 0xff; uint8_t *lp = res_APDU+res_APDU_size; res_APDU_size++; - } - if (f->fid == EF_ALGO_INFO || f->fid == EF_ALGO_SIG) { datalen += parse_algo(algorithm_attr_rsa2k, EF_ALGO_SIG); datalen += parse_algo(algorithm_attr_rsa4k, EF_ALGO_SIG); datalen += parse_algo(algorithm_attr_p256k1, EF_ALGO_SIG); datalen += parse_algo(algorithm_attr_ed25519, EF_ALGO_SIG); datalen += parse_algo(algorithm_attr_ed448, EF_ALGO_SIG); - } - if (f->fid == EF_ALGO_INFO || f->fid == EF_ALGO_DEC) { datalen += parse_algo(algorithm_attr_rsa2k, EF_ALGO_DEC); datalen += parse_algo(algorithm_attr_rsa4k, EF_ALGO_DEC); datalen += parse_algo(algorithm_attr_p256k1, EF_ALGO_DEC); datalen += parse_algo(algorithm_attr_cv25519, EF_ALGO_DEC); datalen += parse_algo(algorithm_attr_x448, EF_ALGO_DEC); - } - if (f->fid == EF_ALGO_INFO || f->fid == EF_ALGO_AUT) { datalen += parse_algo(algorithm_attr_rsa2k, EF_ALGO_AUT); datalen += parse_algo(algorithm_attr_rsa4k, EF_ALGO_AUT); datalen += parse_algo(algorithm_attr_p256k1, EF_ALGO_AUT); datalen += parse_algo(algorithm_attr_ed25519, EF_ALGO_AUT); datalen += parse_algo(algorithm_attr_ed448, EF_ALGO_AUT); - } - if (lp) *lp = res_APDU+res_APDU_size-lp-1; - return lp ? *lp+2 : datalen; + datalen = *lp; + } + else if (f->fid == EF_ALGO_SIG || f->fid == EF_ALGO_DEC || f->fid == EF_ALGO_AUT) { + uint16_t fid = 0x1000 | f->fid; + file_t *ef; + if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF)) || !ef->data) + datalen += parse_algo(algorithm_attr_rsa2k, f->fid); + else { + uint16_t len = file_read_uint16(ef->data); + if (res_APDU_size > 0) { + res_APDU[res_APDU_size++] = f->fid & 0xff; + res_APDU[res_APDU_size++] = len & 0xff; + datalen += 2; + } + memcpy(res_APDU+res_APDU_size, file_read(ef->data+2), len); + res_APDU_size += len; + datalen += len; + } + } + return datalen; } int parse_app_data(const file_t *f, int mode) { @@ -618,6 +628,8 @@ static int cmd_put_data() { file_t *ef; if (fid == EF_RESET_CODE) fid = EF_RC; + else if (fid == EF_ALGO_SIG || fid == EF_ALGO_DEC || fid == EF_ALGO_AUT) + fid |= 0x1000; if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) return SW_FILE_NOT_FOUND(); if (!authenticate_action(ef, ACL_OP_UPDATE_ERASE)) {