Yubico and GnuPG interpretate the standard in different ways. While Yubico follows strictly the spec and expects the TAG encapsulating the output of GET_DATA, GnuPG expects consecutive DO in the response.
A possible workaround is to detect whether sub-DO are called (GnuPG) or management AID is called (Yubico). Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -37,6 +37,9 @@ int cmd_get_data() {
|
|||||||
select_file(ef);
|
select_file(ef);
|
||||||
}
|
}
|
||||||
if (ef->data) {
|
if (ef->data) {
|
||||||
|
if (fid == EF_PW_STATUS || fid == EF_HIST_BYTES || fid == EF_FULL_AID || fid == EF_SEC_TPL) {
|
||||||
|
is_gpg = true;
|
||||||
|
}
|
||||||
uint16_t fids[] = { 1, fid };
|
uint16_t fids[] = { 1, fid };
|
||||||
uint16_t data_len = parse_do(fids, 1);
|
uint16_t data_len = parse_do(fids, 1);
|
||||||
uint8_t *p = NULL;
|
uint8_t *p = NULL;
|
||||||
@@ -58,8 +61,42 @@ int cmd_get_data() {
|
|||||||
res_APDU_size -= dec;
|
res_APDU_size -= dec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if (apdu.ne > data_len)
|
if (is_gpg == false) {
|
||||||
// apdu.ne = data_len;
|
uint8_t off = 2;
|
||||||
|
if (P1(apdu) > 0x0) {
|
||||||
|
off++;
|
||||||
|
}
|
||||||
|
if (data_len >= 128) {
|
||||||
|
off++;
|
||||||
|
}
|
||||||
|
if (data_len >= 256) {
|
||||||
|
off++;
|
||||||
|
}
|
||||||
|
memmove(res_APDU + off, res_APDU, data_len);
|
||||||
|
off = 0;
|
||||||
|
if (P1(apdu) > 0x0) {
|
||||||
|
res_APDU[off++] = P1(apdu);
|
||||||
|
res_APDU[off++] = P2(apdu);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res_APDU[off++] = P2(apdu);
|
||||||
|
}
|
||||||
|
if (data_len >= 256) {
|
||||||
|
res_APDU[off++] = 0x82;
|
||||||
|
res_APDU[off++] = (data_len >> 8) & 0xff;
|
||||||
|
res_APDU[off++] = data_len & 0xff;
|
||||||
|
}
|
||||||
|
else if (data_len >= 128) {
|
||||||
|
res_APDU[off++] = 0x81;
|
||||||
|
res_APDU[off++] = data_len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res_APDU[off++] = data_len;
|
||||||
|
}
|
||||||
|
res_APDU_size += off;
|
||||||
|
}
|
||||||
|
// if (apdu.ne > data_len)
|
||||||
|
// apdu.ne = data_len;
|
||||||
}
|
}
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
|
|
||||||
|
bool is_gpg = true;
|
||||||
|
|
||||||
extern const uint8_t openpgp_aid[];
|
extern const uint8_t openpgp_aid[];
|
||||||
extern const uint8_t openpgp_aid_full[];
|
extern const uint8_t openpgp_aid_full[];
|
||||||
|
|
||||||
|
|||||||
@@ -163,4 +163,6 @@
|
|||||||
|
|
||||||
#define EF_DEV_CONF 0x1122
|
#define EF_DEV_CONF 0x1122
|
||||||
|
|
||||||
|
extern bool is_gpg;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ int man_process_apdu() {
|
|||||||
}
|
}
|
||||||
for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) {
|
for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) {
|
||||||
if (cmd->ins == INS(apdu)) {
|
if (cmd->ins == INS(apdu)) {
|
||||||
|
is_gpg = false;
|
||||||
int r = cmd->cmd_handler();
|
int r = cmd->cmd_handler();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user