Merge pull request #840 from cjkoenig/update_liburcu
[feed/packages.git] / utils / opensc / patches / 0006-openpgp-tool-Support-deleting-key-in-Gnuk.patch
1 From 469b6567d9adc4af6f49fa65534162673060454d 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: Mon, 4 Mar 2013 18:13:03 +0700
5 Subject: [PATCH 06/26] openpgp-tool: Support deleting key in Gnuk.
6
7 ---
8 src/tools/openpgp-tool.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++
9 1 file changed, 142 insertions(+)
10
11 diff --git a/src/tools/openpgp-tool.c b/src/tools/openpgp-tool.c
12 index de1c9d4..374819a 100644
13 --- a/src/tools/openpgp-tool.c
14 +++ b/src/tools/openpgp-tool.c
15 @@ -41,6 +41,7 @@
16 #define OPT_PRETTY 257
17 #define OPT_VERIFY 258
18 #define OPT_PIN 259
19 +#define OPT_DELKEY 260
20
21 /* define structures */
22 struct ef_name_map {
23 @@ -79,6 +80,7 @@ static char *pin = NULL;
24 static int opt_dump_do = 0;
25 static u8 do_dump_idx;
26 static int opt_erase = 0;
27 +static int opt_delkey = 0;
28
29 static const char *app_name = "openpgp-tool";
30
31 @@ -98,6 +100,7 @@ static const struct option options[] = {
32 { "erase", no_argument, NULL, 'E' },
33 { "verify", required_argument, NULL, OPT_VERIFY },
34 { "pin", required_argument, NULL, OPT_PIN },
35 + { "del-key", required_argument, NULL, OPT_DELKEY },
36 { "do", required_argument, NULL, 'd' },
37 { NULL, 0, NULL, 0 }
38 };
39 @@ -118,6 +121,7 @@ static const char *option_help[] = {
40 /* E */ "Erase (reset) the card",
41 "Verify PIN (CHV1, CHV2, CHV3...)",
42 "PIN string",
43 + "Delete key (1, 2, 3 or all)",
44 /* d */ "Dump private data object number <arg> (i.e. PRIVATE-DO-<arg>)"
45 };
46
47 @@ -302,6 +306,14 @@ static int decode_options(int argc, char **argv)
48 case 'E':
49 opt_erase++;
50 break;
51 + case OPT_DELKEY:
52 + opt_delkey++;
53 + if (strcmp(optarg, "all") != 0) /* Arg string is not 'all' */
54 + key_id = optarg[0] - '0';
55 + else /* Arg string is 'all' */
56 + key_id = 'a';
57 + actions++;
58 + break;
59 default:
60 util_print_usage_and_die(app_name, options, option_help, NULL);
61 }
62 @@ -457,6 +469,133 @@ int do_verify(sc_card_t *card, char *type, char *pin)
63 return r;
64 }
65
66 +/**
67 + * Delete key, for Gnuk.
68 + **/
69 +int delete_key_gnuk(sc_card_t *card, u8 key_id)
70 +{
71 + sc_context_t *ctx = card->ctx;
72 + int r = SC_SUCCESS;
73 + u8 *data = NULL;
74 +
75 + /* Delete fingerprint */
76 + sc_log(ctx, "Delete fingerprints");
77 + r |= sc_put_data(card, 0xC6 + key_id, NULL, 0);
78 + /* Delete creation time */
79 + sc_log(ctx, "Delete creation time");
80 + r |= sc_put_data(card, 0xCD + key_id, NULL, 0);
81 +
82 + /* Rewrite Extended Header List */
83 + sc_log(ctx, "Rewrite Extended Header List");
84 +
85 + if (key_id == 1)
86 + data = "\x4D\x02\xB6";
87 + else if (key_id == 2)
88 + data = "\x4D\x02\xB8";
89 + else if (key_id == 3)
90 + data = "\x4D\x02\xA4";
91 + else
92 + return SC_ERROR_INVALID_ARGUMENTS;
93 +
94 + r |= sc_put_data(card, 0x4D, data, strlen(data) + 1);
95 + return r;
96 +}
97 +
98 +/**
99 + * Delete key, for OpenPGP card.
100 + * This function is not complete and is reserved for future version (> 2) of OpenPGP card.
101 + **/
102 +int delete_key_openpgp(sc_card_t *card, u8 key_id)
103 +{
104 + sc_context_t *ctx = card->ctx;
105 + char *del_fingerprint = "00:DA:00:C6:14:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00";
106 + char *del_creationtime = "00:DA:00:CD:04:00:00:00:00";
107 + /* We need to replace the 4th byte later */
108 + char *apdustring = NULL;
109 + u8 buf[SC_MAX_APDU_BUFFER_SIZE];
110 + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
111 + sc_apdu_t apdu;
112 + size_t len0;
113 + int i;
114 + int r = SC_SUCCESS;
115 +
116 + for (i = 0; i < 2; i++) {
117 + if (i == 0) /* Reset fingerprint */
118 + apdustring = del_fingerprint;
119 + else /* Reset creation time */
120 + apdustring = del_creationtime;
121 + /* Convert the string to binary array */
122 + len0 = sizeof(buf);
123 + sc_hex_to_bin(apdustring, buf, &len0);
124 +
125 + /* Replace DO tag, subject to key ID */
126 + buf[3] = buf[3] + key_id;
127 +
128 + /* Build APDU from binary array */
129 + r = sc_bytes2apdu(card->ctx, buf, len0, &apdu);
130 + if (r) {
131 + sc_log(ctx, "Failed to build APDU");
132 + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
133 + }
134 + apdu.resp = rbuf;
135 + apdu.resplen = sizeof(rbuf);
136 +
137 + /* Send APDU to card */
138 + r = sc_transmit_apdu(card, &apdu);
139 + LOG_TEST_RET(ctx, r, "Transmiting APDU failed");
140 + }
141 + /* TODO: Rewrite Extended Header List.
142 + * Not support by OpenGPG v2 yet */
143 + LOG_FUNC_RETURN(ctx, r);
144 +}
145 +
146 +int delete_key(sc_card_t *card, u8 key_id)
147 +{
148 + sc_context_t *ctx = card->ctx;
149 + int r;
150 +
151 + LOG_FUNC_CALLED(ctx);
152 + /* Check key ID */
153 + if (key_id < 1 || key_id > 3) {
154 + sc_log(ctx, "Invalid key ID %d", key_id);
155 + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
156 + }
157 +
158 + if (card->type == SC_CARD_TYPE_OPENPGP_GNUK)
159 + r = delete_key_gnuk(card, key_id);
160 + else
161 + r = delete_key_openpgp(card, key_id);
162 +
163 + LOG_FUNC_RETURN(ctx, r);
164 +}
165 +
166 +int do_delete_key(sc_card_t *card, u8 key_id)
167 +{
168 + sc_context_t *ctx = card->ctx;
169 + int r = SC_SUCCESS;
170 +
171 + /* Currently, only Gnuk supports deleting keys */
172 + if (card->type != SC_CARD_TYPE_OPENPGP_GNUK) {
173 + printf("Only Gnuk supports deleting keys. General OpenPGP doesn't.");
174 + return SC_ERROR_NOT_SUPPORTED;
175 + }
176 +
177 + if (key_id < 1 || (key_id > 3 && key_id != 'a')) {
178 + printf("Error: Invalid key id %d", key_id);
179 + return SC_ERROR_INVALID_ARGUMENTS;
180 + }
181 + if (key_id == 1 || key_id == 'a') {
182 + r |= delete_key(card, 1);
183 + }
184 + if (key_id == 2 || key_id == 'a') {
185 + r |= delete_key(card, 2);
186 + }
187 + if (key_id == 3 || key_id == 'a') {
188 + r |= delete_key(card, 3);
189 + }
190 + return r;
191 +}
192 +
193 int do_erase(sc_card_t *card)
194 {
195 int r;
196 @@ -548,6 +687,9 @@ int main(int argc, char **argv)
197 exit(EXIT_FAILURE);
198 }
199
200 + if (opt_delkey)
201 + exit_status != do_delete_key(card, key_id);
202 +
203 if (opt_erase)
204 exit_status != do_erase(card);
205
206 --
207 2.1.3
208