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:
Pol Henarejos
2025-12-05 19:11:21 +01:00
parent 504d90a2b3
commit 90e77f7c61
4 changed files with 44 additions and 2 deletions

View File

@@ -37,6 +37,9 @@ int cmd_get_data() {
select_file(ef);
}
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 data_len = parse_do(fids, 1);
uint8_t *p = NULL;
@@ -58,8 +61,42 @@ int cmd_get_data() {
res_APDU_size -= dec;
}
}
//if (apdu.ne > data_len)
// apdu.ne = data_len;
if (is_gpg == false) {
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();
}

View File

@@ -17,6 +17,8 @@
#include "files.h"
bool is_gpg = true;
extern const uint8_t openpgp_aid[];
extern const uint8_t openpgp_aid_full[];

View File

@@ -163,4 +163,6 @@
#define EF_DEV_CONF 0x1122
extern bool is_gpg;
#endif

View File

@@ -145,6 +145,7 @@ int man_process_apdu() {
}
for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) {
if (cmd->ins == INS(apdu)) {
is_gpg = false;
int r = cmd->cmd_handler();
return r;
}