Changeset View
Changeset View
Standalone View
Standalone View
scd/app-openpgp.c
Context not available. | |||||
} | } | ||||
char * | |||||
openpgp_get_serialno (app_t app) | |||||
{ | |||||
if (app->card->cardtype != CARDTYPE_YUBIKEY) | |||||
return app_get_serialno (app); | |||||
else | |||||
{ | |||||
void *relptr; | |||||
unsigned char *buffer; | |||||
size_t buflen; | |||||
char *serial; | |||||
/* | |||||
* Yubikey has its own serial number at app->serialno. | |||||
* When Yubikey is used for OpenPGP card app, we get | |||||
* the serial number from AID data object. | |||||
*/ | |||||
relptr = get_one_do (app, 0x004F, &buffer, &buflen, NULL); | |||||
if (!relptr) | |||||
return NULL; | |||||
if (buflen != 16) | |||||
{ | |||||
xfree (relptr); | |||||
return NULL; | |||||
} | |||||
serial = xtrymalloc (32 + 1); | |||||
if (!serial) | |||||
return NULL; | |||||
serial[32] = 0; | |||||
bin2hex (buffer, buflen, serial); | |||||
xfree (relptr); | |||||
return serial; | |||||
} | |||||
} | |||||
/* Implement the GETATTR command. This is similar to the LEARN | /* Implement the GETATTR command. This is similar to the LEARN | ||||
command but returns just one value via the status interface. */ | command but returns just one value via the status interface. */ | ||||
static gpg_error_t | static gpg_error_t | ||||
Context not available. | |||||
/* The serial number is very special. We could have used the | /* The serial number is very special. We could have used the | ||||
AID DO to retrieve it. The AID DO is available anyway but | AID DO to retrieve it. The AID DO is available anyway but | ||||
not hex formatted. */ | not hex formatted. */ | ||||
char *serial = app_get_serialno (app); | char *serial = openpgp_get_serialno (app); | ||||
if (serial) | if (serial) | ||||
{ | { | ||||
Context not available. | |||||
} | } | ||||
if (table[idx].special == -4) | if (table[idx].special == -4) | ||||
{ | { | ||||
char *serial = app_get_serialno (app); | char *serial = openpgp_get_serialno (app); | ||||
if (serial) | if (serial) | ||||
{ | { | ||||
Context not available. | |||||
static char * | static char * | ||||
get_disp_serialno (app_t app) | get_disp_serialno (app_t app) | ||||
{ | { | ||||
char *serial = app_get_serialno (app); | char *serial = openpgp_get_serialno (app); | ||||
/* For our OpenPGP cards we do not want to show the entire serial | /* For our OpenPGP cards we do not want to show the entire serial | ||||
* number but a nicely reformatted actual serial number. */ | * number but a nicely reformatted actual serial number. */ | ||||
Context not available. | |||||
const char *s; | const char *s; | ||||
int n; | int n; | ||||
const char *fpr = NULL; | const char *fpr = NULL; | ||||
unsigned char tmp_sn[20]; /* Actually 16 bytes but also for the fpr. */ | |||||
if (r_use_auth) | if (r_use_auth) | ||||
*r_use_auth = 0; | *r_use_auth = 0; | ||||
Context not available. | |||||
return gpg_error (GPG_ERR_INV_ID); | return gpg_error (GPG_ERR_INV_ID); | ||||
else | else | ||||
{ | { | ||||
char *serial; | |||||
for (s=keyidstr, n=0; hexdigitp (s); s++, n++) | for (s=keyidstr, n=0; hexdigitp (s); s++, n++) | ||||
; | ; | ||||
Context not available. | |||||
else if (*s == '/') | else if (*s == '/') | ||||
fpr = s + 1; | fpr = s + 1; | ||||
for (s=keyidstr, n=0; n < 16; s += 2, n++) | serial = openpgp_get_serialno (app); | ||||
tmp_sn[n] = xtoi_2 (s); | if (strncmp (serial, keyidstr, 32)) | ||||
{ | |||||
xfree (serial); | |||||
return gpg_error (GPG_ERR_WRONG_CARD); | |||||
} | |||||
if (app->card->serialnolen != 16) | xfree (serial); | ||||
return gpg_error (GPG_ERR_INV_CARD); | |||||
if (memcmp (app->card->serialno, tmp_sn, 16)) | |||||
return gpg_error (GPG_ERR_WRONG_CARD); | |||||
} | } | ||||
/* If a fingerprint has been specified check it against the one on | /* If a fingerprint has been specified check it against the one on | ||||
Context not available. | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
char buf[65]; | |||||
int data = (action == KEYGRIP_ACTION_SEND_DATA); | int data = (action == KEYGRIP_ACTION_SEND_DATA); | ||||
char *serial = openpgp_get_serialno (app); | |||||
if (DIM (buf) < 2 * app->card->serialnolen + 1) | |||||
return gpg_error (GPG_ERR_BUFFER_TOO_SHORT); | |||||
bin2hex (app->card->serialno, app->card->serialnolen, buf); | |||||
if (keygrip_str == NULL) | if (keygrip_str == NULL) | ||||
{ | { | ||||
if (capability == 0) | if (capability == 0) | ||||
{ | { | ||||
for (i = 0; i < 3; i++) | for (i = 0; i < 3; i++) | ||||
send_keyinfo_if_available (app, ctrl, buf, data, i); | send_keyinfo_if_available (app, ctrl, serial, data, i); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
Context not available. | |||||
else | else | ||||
i = -1; | i = -1; | ||||
if (i >= 0) | if (i >= 0) | ||||
send_keyinfo_if_available (app, ctrl, buf, data, i); | send_keyinfo_if_available (app, ctrl, serial, data, i); | ||||
} | } | ||||
xfree (serial); | |||||
/* Return an error so that the dispatcher keeps on looping | /* Return an error so that the dispatcher keeps on looping | ||||
* over the other applications. Only for clarity we use a | * over the other applications. Only for clarity we use a | ||||
* different error code than for the not_found case. */ | * different error code than for the not_found case. */ | ||||
Context not available. | |||||
for (i = 0; i < 3; i++) | for (i = 0; i < 3; i++) | ||||
if (!strcmp (keygrip_str, app->app_local->pk[i].keygrip_str)) | if (!strcmp (keygrip_str, app->app_local->pk[i].keygrip_str)) | ||||
{ | { | ||||
send_keyinfo_if_available (app, ctrl, buf, data, i); | send_keyinfo_if_available (app, ctrl, serial, data, i); | ||||
xfree (serial); | |||||
return 0; | return 0; | ||||
} | } | ||||
xfree (serial); | |||||
} | } | ||||
} | } | ||||
Context not available. | |||||
app->appversion |= buffer[7]; | app->appversion |= buffer[7]; | ||||
manufacturer = (buffer[8]<<8 | buffer[9]); | manufacturer = (buffer[8]<<8 | buffer[9]); | ||||
xfree (app->card->serialno); | if (app->card->cardtype != CARDTYPE_YUBIKEY) | ||||
app->card->serialno = buffer; | { | ||||
app->card->serialnolen = buflen; | xfree (app->card->serialno); | ||||
app->card->serialno = buffer; | |||||
app->card->serialnolen = buflen; | |||||
} | |||||
else | |||||
xfree (buffer); | |||||
buffer = NULL; | buffer = NULL; | ||||
app->app_local = xtrycalloc (1, sizeof *app->app_local); | app->app_local = xtrycalloc (1, sizeof *app->app_local); | ||||
if (!app->app_local) | if (!app->app_local) | ||||
Context not available. |