d133e805955ab8b419b60ad64c830e93242d9384
[librecmc/librecmc-fossil.git] /
1 From 752f8981bed49a98d3592ead3aa50e743318dea8 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Nguy=E1=BB=85n=20H=E1=BB=93ng=20Qu=C3=A2n?=
3  <ng.hong.quan@gmail.com>
4 Date: Fri, 5 Apr 2013 17:18:50 +0700
5 Subject: [PATCH 11/26] OpenPGP: Provide enough buffer to read pubkey from
6  Gnuk.
7
8 ---
9  src/libopensc/card-openpgp.c | 28 +++++++++++++++++++++++-----
10  1 file changed, 23 insertions(+), 5 deletions(-)
11
12 diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
13 index e7b25c0..1913eca 100644
14 --- a/src/libopensc/card-openpgp.c
15 +++ b/src/libopensc/card-openpgp.c
16 @@ -263,7 +263,12 @@ static struct do_info              pgp2_objects[] = {      /* OpenPGP card spec 2.0 */
17  
18  /* The DO holding X.509 certificate is constructed but does not contain child DO.
19   * We should notice this when building fake file system later. */
20 -#define DO_CERT                0x7f21
21 +#define DO_CERT                  0x7f21
22 +/* Maximum length for response buffer when reading pubkey. This value is calculated with
23 + * 4096-bit key length */
24 +#define MAXLEN_RESP_PUBKEY       527
25 +/* Gnuk only support 1 key length (2048 bit) */
26 +#define MAXLEN_RESP_PUBKEY_GNUK  271
27  
28  #define DRVDATA(card)        ((struct pgp_priv_data *) ((card)->drv_data))
29  struct pgp_priv_data {
30 @@ -731,6 +736,14 @@ pgp_read_blob(sc_card_t *card, struct blob *blob)
31                 u8      buffer[2048];
32                 size_t  buf_len = (card->caps & SC_CARD_CAP_APDU_EXT)
33                                   ? sizeof(buffer) : 256;
34 +
35 +               /* Buffer length for Gnuk pubkey */
36 +               if (card->type == SC_CARD_TYPE_OPENPGP_GNUK &&
37 +                   (blob->id == 0xa400 || blob->id == 0xb600 || blob->id == 0xb800
38 +                    || blob->id == 0xa401 || blob->id == 0xb601 || blob->id == 0xb801)) {
39 +                       buf_len = MAXLEN_RESP_PUBKEY_GNUK;
40 +               }
41 +
42                 int     r = blob->info->get_fn(card, blob->id, buffer, buf_len);
43  
44                 if (r < 0) {    /* an error occurred */
45 @@ -1828,6 +1841,7 @@ static int pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_in
46         u8 apdu_case;
47         u8 *apdu_data;
48         size_t apdu_le;
49 +       size_t resplen = 0;
50         int r = SC_SUCCESS;
51  
52         LOG_FUNC_CALLED(card->ctx);
53 @@ -1868,23 +1882,27 @@ static int pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_in
54                 apdu_case = SC_APDU_CASE_4_EXT;
55         }
56         else {
57 -               apdu_le = 256;
58                 apdu_case = SC_APDU_CASE_4_SHORT;
59 +               apdu_le = 256;
60 +               resplen = MAXLEN_RESP_PUBKEY;
61 +       }
62 +       if (card->type == SC_CARD_TYPE_OPENPGP_GNUK) {
63 +               resplen = MAXLEN_RESP_PUBKEY_GNUK;
64         }
65  
66         /* Prepare APDU */
67 -       sc_format_apdu(card, &apdu, apdu_case, 0x47, 0x80,  0);
68 +       sc_format_apdu(card, &apdu, apdu_case, 0x47, 0x80, 0);
69         apdu.data = apdu_data;
70         apdu.datalen = 2;  /* Data = B600 */
71         apdu.lc = 2;
72         apdu.le = apdu_le;
73  
74         /* Buffer to receive response */
75 -       apdu.resp = calloc(apdu.le, 1);
76 +       apdu.resplen = (resplen > 0) ? resplen : apdu_le;
77 +       apdu.resp = calloc(apdu.resplen, 1);
78         if (apdu.resp == NULL) {
79                 LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY);
80         }
81 -       apdu.resplen = apdu.le;
82  
83         /* Send */
84         sc_log(card->ctx, "Waiting for the card to generate key...");
85 -- 
86 2.1.3
87