|
From 7231ee09bb628f0401939778decce818ef6e3665 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
|
|
<ng.hong.quan@gmail.com>
|
|
Date: Fri, 5 Apr 2013 17:18:50 +0700
|
|
Subject: [PATCH 11/18] OpenPGP: Provide enough buffer to read pubkey from
|
|
Gnuk.
|
|
|
|
---
|
|
src/libopensc/card-openpgp.c | 28 +++++++++++++++++++++++-----
|
|
1 file changed, 23 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
|
|
index 9b08bbb..8a1a270 100644
|
|
--- a/src/libopensc/card-openpgp.c
|
|
+++ b/src/libopensc/card-openpgp.c
|
|
@@ -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 {
|
|
@@ -729,6 +734,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 */
|
|
@@ -1830,6 +1843,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...");
|
|
--
|
|
1.9.3
|
|
|