openpgp-tool: Support deleting key in Gnuk.
This commit is contained in:
parent
3b8f77882b
commit
c4bbfa6759
|
@ -40,6 +40,7 @@
|
|||
#define OPT_PRETTY 257
|
||||
#define OPT_VERIFY 258
|
||||
#define OPT_PIN 259
|
||||
#define OPT_DELKEY 260
|
||||
|
||||
/* define structures */
|
||||
struct ef_name_map {
|
||||
|
@ -76,6 +77,7 @@ static char *verifytype = NULL;
|
|||
static int opt_pin = 0;
|
||||
static char *pin = NULL;
|
||||
static int opt_erase = 0;
|
||||
static int opt_delkey = 0;
|
||||
|
||||
static const char *app_name = "openpgp-tool";
|
||||
|
||||
|
@ -95,6 +97,7 @@ static const struct option options[] = {
|
|||
{ "erase", no_argument, NULL, 'E' },
|
||||
{ "verify", required_argument, NULL, OPT_VERIFY },
|
||||
{ "pin", required_argument, NULL, OPT_PIN },
|
||||
{ "del-key", required_argument, NULL, OPT_DELKEY },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
|
@ -113,7 +116,8 @@ static const char *option_help[] = {
|
|||
/* V */ "Show version number",
|
||||
/* E */ "Erase (reset) the card",
|
||||
"Verify PIN (CHV1, CHV2, CHV3...)",
|
||||
"PIN string"
|
||||
"PIN string",
|
||||
"Delete key (1, 2, 3 or all)"
|
||||
};
|
||||
|
||||
static const struct ef_name_map openpgp_data[] = {
|
||||
|
@ -293,6 +297,14 @@ static int decode_options(int argc, char **argv)
|
|||
case 'E':
|
||||
opt_erase++;
|
||||
break;
|
||||
case OPT_DELKEY:
|
||||
opt_delkey++;
|
||||
if (strcmp(optarg, "all") != 0) /* Arg string is not 'all' */
|
||||
key_id = optarg[0] - '0';
|
||||
else /* Arg string is 'all' */
|
||||
key_id = 'a';
|
||||
actions++;
|
||||
break;
|
||||
default:
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
}
|
||||
|
@ -412,6 +424,133 @@ int do_verify(sc_card_t *card, char *type, char *pin)
|
|||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete key, for Gnuk.
|
||||
**/
|
||||
int delete_key_gnuk(sc_card_t *card, u8 key_id)
|
||||
{
|
||||
sc_context_t *ctx = card->ctx;
|
||||
int r = SC_SUCCESS;
|
||||
u8 *data = NULL;
|
||||
|
||||
/* Delete fingerprint */
|
||||
sc_log(ctx, "Delete fingerprints");
|
||||
r |= sc_put_data(card, 0xC6 + key_id, NULL, 0);
|
||||
/* Delete creation time */
|
||||
sc_log(ctx, "Delete creation time");
|
||||
r |= sc_put_data(card, 0xCD + key_id, NULL, 0);
|
||||
|
||||
/* Rewrite Extended Header List */
|
||||
sc_log(ctx, "Rewrite Extended Header List");
|
||||
|
||||
if (key_id == 1)
|
||||
data = "\x4D\x02\xB6";
|
||||
else if (key_id == 2)
|
||||
data = "\x4D\x02\xB8";
|
||||
else if (key_id == 3)
|
||||
data = "\x4D\x02\xA4";
|
||||
else
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
r |= sc_put_data(card, 0x4D, data, strlen(data) + 1);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete key, for OpenPGP card.
|
||||
* This function is not complete and is reserved for future version (> 2) of OpenPGP card.
|
||||
**/
|
||||
int delete_key_openpgp(sc_card_t *card, u8 key_id)
|
||||
{
|
||||
sc_context_t *ctx = card->ctx;
|
||||
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";
|
||||
char *del_creationtime = "00:DA:00:CD:04:00:00:00:00";
|
||||
/* We need to replace the 4th byte later */
|
||||
char *apdustring = NULL;
|
||||
u8 buf[SC_MAX_APDU_BUFFER_SIZE];
|
||||
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||
sc_apdu_t apdu;
|
||||
size_t len0;
|
||||
int i;
|
||||
int r = SC_SUCCESS;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (i == 0) /* Reset fingerprint */
|
||||
apdustring = del_fingerprint;
|
||||
else /* Reset creation time */
|
||||
apdustring = del_creationtime;
|
||||
/* Convert the string to binary array */
|
||||
len0 = sizeof(buf);
|
||||
sc_hex_to_bin(apdustring, buf, &len0);
|
||||
|
||||
/* Replace DO tag, subject to key ID */
|
||||
buf[3] = buf[3] + key_id;
|
||||
|
||||
/* Build APDU from binary array */
|
||||
r = sc_bytes2apdu(card->ctx, buf, len0, &apdu);
|
||||
if (r) {
|
||||
sc_log(ctx, "Failed to build APDU");
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
|
||||
}
|
||||
apdu.resp = rbuf;
|
||||
apdu.resplen = sizeof(rbuf);
|
||||
|
||||
/* Send APDU to card */
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
LOG_TEST_RET(ctx, r, "Transmiting APDU failed");
|
||||
}
|
||||
/* TODO: Rewrite Extended Header List.
|
||||
* Not support by OpenGPG v2 yet */
|
||||
LOG_FUNC_RETURN(ctx, r);
|
||||
}
|
||||
|
||||
int delete_key(sc_card_t *card, u8 key_id)
|
||||
{
|
||||
sc_context_t *ctx = card->ctx;
|
||||
int r;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
/* Check key ID */
|
||||
if (key_id < 1 || key_id > 3) {
|
||||
sc_log(ctx, "Invalid key ID %d", key_id);
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
}
|
||||
|
||||
if (card->type == SC_CARD_TYPE_OPENPGP_GNUK)
|
||||
r = delete_key_gnuk(card, key_id);
|
||||
else
|
||||
r = delete_key_openpgp(card, key_id);
|
||||
|
||||
LOG_FUNC_RETURN(ctx, r);
|
||||
}
|
||||
|
||||
int do_delete_key(sc_card_t *card, u8 key_id)
|
||||
{
|
||||
sc_context_t *ctx = card->ctx;
|
||||
int r = SC_SUCCESS;
|
||||
|
||||
/* Currently, only Gnuk supports deleting keys */
|
||||
if (card->type != SC_CARD_TYPE_OPENPGP_GNUK) {
|
||||
printf("Only Gnuk supports deleting keys. General OpenPGP doesn't.");
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (key_id < 1 || (key_id > 3 && key_id != 'a')) {
|
||||
printf("Error: Invalid key id %d", key_id);
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
if (key_id == 1 || key_id == 'a') {
|
||||
r |= delete_key(card, 1);
|
||||
}
|
||||
if (key_id == 2 || key_id == 'a') {
|
||||
r |= delete_key(card, 2);
|
||||
}
|
||||
if (key_id == 3 || key_id == 'a') {
|
||||
r |= delete_key(card, 3);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int do_erase(sc_card_t *card)
|
||||
{
|
||||
int r;
|
||||
|
@ -499,6 +638,9 @@ int main(int argc, char **argv)
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (opt_delkey)
|
||||
exit_status != do_delete_key(card, key_id);
|
||||
|
||||
if (opt_erase)
|
||||
exit_status != do_erase(card);
|
||||
|
||||
|
|
Loading…
Reference in New Issue