OpenPGP: Provide enough buffer to read pubkey from Gnuk.

This commit is contained in:
Nguyễn Hồng Quân 2013-04-05 17:18:50 +07:00
parent 9a2a6e6dc0
commit ebbebb4fa6
1 changed files with 23 additions and 5 deletions

View File

@ -263,7 +263,12 @@ static struct do_info pgp2_objects[] = { /* OpenPGP card spec 2.0 */
/* The DO holding X.509 certificate is constructed but does not contain child DO.
* We should notice this when building fake file system later. */
#define DO_CERT 0x7f21
#define DO_CERT 0x7f21
/* Maximum length for response buffer when reading pubkey. This value is calculated with
* 4096-bit key length */
#define MAXLEN_RESP_PUBKEY 527
/* Gnuk only support 1 key length (2048 bit) */
#define MAXLEN_RESP_PUBKEY_GNUK 271
#define DRVDATA(card) ((struct pgp_priv_data *) ((card)->drv_data))
struct pgp_priv_data {
@ -731,6 +736,14 @@ pgp_read_blob(sc_card_t *card, struct blob *blob)
u8 buffer[2048];
size_t buf_len = (card->caps & SC_CARD_CAP_APDU_EXT)
? sizeof(buffer) : 256;
/* Buffer length for Gnuk pubkey */
if (card->type == SC_CARD_TYPE_OPENPGP_GNUK &&
(blob->id == 0xa400 || blob->id == 0xb600 || blob->id == 0xb800
|| blob->id == 0xa401 || blob->id == 0xb601 || blob->id == 0xb801)) {
buf_len = MAXLEN_RESP_PUBKEY_GNUK;
}
int r = blob->info->get_fn(card, blob->id, buffer, buf_len);
if (r < 0) { /* an error occurred */
@ -1828,6 +1841,7 @@ static int pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_in
u8 apdu_case;
u8 *apdu_data;
size_t apdu_le;
size_t resplen = 0;
int r = SC_SUCCESS;
LOG_FUNC_CALLED(card->ctx);
@ -1868,23 +1882,27 @@ static int pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_in
apdu_case = SC_APDU_CASE_4_EXT;
}
else {
apdu_le = 256;
apdu_case = SC_APDU_CASE_4_SHORT;
apdu_le = 256;
resplen = MAXLEN_RESP_PUBKEY;
}
if (card->type == SC_CARD_TYPE_OPENPGP_GNUK) {
resplen = MAXLEN_RESP_PUBKEY_GNUK;
}
/* Prepare APDU */
sc_format_apdu(card, &apdu, apdu_case, 0x47, 0x80, 0);
sc_format_apdu(card, &apdu, apdu_case, 0x47, 0x80, 0);
apdu.data = apdu_data;
apdu.datalen = 2; /* Data = B600 */
apdu.lc = 2;
apdu.le = apdu_le;
/* Buffer to receive response */
apdu.resp = calloc(apdu.le, 1);
apdu.resplen = (resplen > 0) ? resplen : apdu_le;
apdu.resp = calloc(apdu.resplen, 1);
if (apdu.resp == NULL) {
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY);
}
apdu.resplen = apdu.le;
/* Send */
sc_log(card->ctx, "Waiting for the card to generate key...");