Support for GnuK token is included in this release, remove patches. Signed-off-by: Daniel Golle <daniel@makrotopia.org>lilik-openwrt-22.03
@ -1,255 +0,0 @@ | |||||
From 471b40173b73f213ee72bf05735abf3357658197 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: Wed, 20 Feb 2013 11:54:30 +0700 | |||||
Subject: [PATCH 01/26] OpenPGP: Detect and support Gnuk Token. | |||||
http://www.fsij.org/gnuk/ | |||||
--- | |||||
src/libopensc/card-openpgp.c | 61 ++++++++++++++++++++++++++++++++++---------- | |||||
src/libopensc/cards.h | 1 + | |||||
src/tools/openpgp-tool.c | 7 ++++- | |||||
3 files changed, 55 insertions(+), 14 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -45,6 +45,7 @@ | |||||
static struct sc_atr_table pgp_atrs[] = { | |||||
{ "3b:fa:13:00:ff:81:31:80:45:00:31:c1:73:c0:01:00:00:90:00:b1", NULL, "OpenPGP card v1.0/1.1", SC_CARD_TYPE_OPENPGP_V1, 0, NULL }, | |||||
{ "3b:da:18:ff:81:b1:fe:75:1f:03:00:31:c5:73:c0:01:40:00:90:00:0c", NULL, "CryptoStick v1.2 (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_V2, 0, NULL }, | |||||
+ { "3b:da:11:ff:81:b1:fe:55:1f:03:00:31:84:73:80:01:80:00:90:00:e4", NULL, "Gnuk v1.0.x (OpenPGP v2.0)", SC_CARD_TYPE_OPENPGP_GNUK, 0, NULL }, | |||||
{ NULL, NULL, NULL, 0, 0, NULL } | |||||
}; | |||||
@@ -309,6 +310,8 @@ pgp_init(sc_card_t *card) | |||||
int r; | |||||
struct blob *child = NULL; | |||||
+ LOG_FUNC_CALLED(card->ctx); | |||||
+ | |||||
priv = calloc (1, sizeof *priv); | |||||
if (!priv) | |||||
return SC_ERROR_OUT_OF_MEMORY; | |||||
@@ -317,11 +320,11 @@ pgp_init(sc_card_t *card) | |||||
card->cla = 0x00; | |||||
/* set pointer to correct list of card objects */ | |||||
- priv->pgp_objects = (card->type == SC_CARD_TYPE_OPENPGP_V2) | |||||
+ priv->pgp_objects = (card->type == SC_CARD_TYPE_OPENPGP_V2 || card->type == SC_CARD_TYPE_OPENPGP_GNUK) | |||||
? pgp2_objects : pgp1_objects; | |||||
/* set detailed card version */ | |||||
- priv->bcd_version = (card->type == SC_CARD_TYPE_OPENPGP_V2) | |||||
+ priv->bcd_version = (card->type == SC_CARD_TYPE_OPENPGP_V2 || card->type == SC_CARD_TYPE_OPENPGP_GNUK) | |||||
? OPENPGP_CARD_2_0 : OPENPGP_CARD_1_1; | |||||
/* select application "OpenPGP" */ | |||||
@@ -436,7 +439,8 @@ pgp_get_card_features(sc_card_t *card) | |||||
if ((pgp_get_blob(card, blob73, 0x00c0, &blob) >= 0) && | |||||
(blob->data != NULL) && (blob->len > 0)) { | |||||
/* in v2.0 bit 0x04 in first byte means "algorithm attributes changeable */ | |||||
- if ((blob->data[0] & 0x04) && (card->type == SC_CARD_TYPE_OPENPGP_V2)) | |||||
+ if ((blob->data[0] & 0x04) && | |||||
+ (card->type == SC_CARD_TYPE_OPENPGP_V2 || card->type == SC_CARD_TYPE_OPENPGP_GNUK)) | |||||
priv->ext_caps |= EXT_CAP_ALG_ATTR_CHANGEABLE; | |||||
/* bit 0x08 in first byte means "support for private use DOs" */ | |||||
if (blob->data[0] & 0x08) | |||||
@@ -453,7 +457,8 @@ pgp_get_card_features(sc_card_t *card) | |||||
priv->ext_caps |= EXT_CAP_GET_CHALLENGE; | |||||
} | |||||
/* in v2.0 bit 0x80 in first byte means "support Secure Messaging" */ | |||||
- if ((blob->data[0] & 0x80) && (card->type == SC_CARD_TYPE_OPENPGP_V2)) | |||||
+ if ((blob->data[0] & 0x80) && | |||||
+ (card->type == SC_CARD_TYPE_OPENPGP_V2 || card->type == SC_CARD_TYPE_OPENPGP_GNUK)) | |||||
priv->ext_caps |= EXT_CAP_SM; | |||||
if ((priv->bcd_version >= OPENPGP_CARD_2_0) && (blob->len >= 10)) { | |||||
@@ -1065,12 +1070,18 @@ static int | |||||
pgp_get_pubkey(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) | |||||
{ | |||||
sc_apdu_t apdu; | |||||
+ u8 apdu_case = SC_APDU_CASE_4; | |||||
u8 idbuf[2]; | |||||
int r; | |||||
sc_log(card->ctx, "called, tag=%04x\n", tag); | |||||
- sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x47, 0x81, 0); | |||||
+ /* With Gnuk token, force to use short APDU */ | |||||
+ if (card->type == SC_CARD_TYPE_OPENPGP_GNUK) { | |||||
+ apdu_case = SC_APDU_CASE_4_SHORT; | |||||
+ } | |||||
+ | |||||
+ sc_format_apdu(card, &apdu, apdu_case, 0x47, 0x81, 0); | |||||
apdu.lc = 2; | |||||
apdu.data = ushort2bebytes(idbuf, tag); | |||||
apdu.datalen = 2; | |||||
@@ -1162,6 +1173,7 @@ pgp_put_data(sc_card_t *card, unsigned i | |||||
u8 ins = 0xDA; | |||||
u8 p1 = tag >> 8; | |||||
u8 p2 = tag & 0xFF; | |||||
+ u8 apdu_case = SC_APDU_CASE_3; | |||||
int r; | |||||
LOG_FUNC_CALLED(card->ctx); | |||||
@@ -1203,13 +1215,17 @@ pgp_put_data(sc_card_t *card, unsigned i | |||||
/* Build APDU */ | |||||
if (buf != NULL && buf_len > 0) { | |||||
- sc_format_apdu(card, &apdu, SC_APDU_CASE_3, ins, p1, p2); | |||||
+ /* Force short APDU for Gnuk */ | |||||
+ if (card->type == SC_CARD_TYPE_OPENPGP_GNUK) { | |||||
+ apdu_case = SC_APDU_CASE_3_SHORT; | |||||
+ } | |||||
+ sc_format_apdu(card, &apdu, apdu_case, ins, p1, p2); | |||||
/* if card/reader does not support extended APDUs, but chaining, then set it */ | |||||
if (((card->caps & SC_CARD_CAP_APDU_EXT) == 0) && (priv->ext_caps & EXT_CAP_CHAINING)) | |||||
apdu.flags |= SC_APDU_FLAGS_CHAINING; | |||||
- apdu.data = buf; | |||||
+ apdu.data = (u8 *)buf; | |||||
apdu.datalen = buf_len; | |||||
apdu.lc = buf_len; | |||||
} | |||||
@@ -1336,6 +1352,7 @@ pgp_compute_signature(sc_card_t *card, c | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
sc_security_env_t *env = &priv->sec_env; | |||||
sc_apdu_t apdu; | |||||
+ u8 apdu_case = SC_APDU_CASE_4; | |||||
int r; | |||||
LOG_FUNC_CALLED(card->ctx); | |||||
@@ -1344,14 +1361,19 @@ pgp_compute_signature(sc_card_t *card, c | |||||
LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, | |||||
"invalid operation"); | |||||
+ /* Force short APDU for Gnuk Token */ | |||||
+ if (card->type == SC_CARD_TYPE_OPENPGP_GNUK) { | |||||
+ apdu_case = SC_APDU_CASE_4_SHORT; | |||||
+ } | |||||
+ | |||||
switch (env->key_ref[0]) { | |||||
case 0x00: /* signature key */ | |||||
/* PSO SIGNATURE */ | |||||
- sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x9E, 0x9A); | |||||
+ sc_format_apdu(card, &apdu, apdu_case, 0x2A, 0x9E, 0x9A); | |||||
break; | |||||
case 0x02: /* authentication key */ | |||||
/* INTERNAL AUTHENTICATE */ | |||||
- sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x88, 0, 0); | |||||
+ sc_format_apdu(card, &apdu, apdu_case, 0x88, 0, 0); | |||||
break; | |||||
case 0x01: | |||||
default: | |||||
@@ -1360,7 +1382,7 @@ pgp_compute_signature(sc_card_t *card, c | |||||
} | |||||
apdu.lc = data_len; | |||||
- apdu.data = data; | |||||
+ apdu.data = (u8 *)data; | |||||
apdu.datalen = data_len; | |||||
apdu.le = ((outlen >= 256) && !(card->caps & SC_CARD_CAP_APDU_EXT)) ? 256 : outlen; | |||||
apdu.resp = out; | |||||
@@ -1384,6 +1406,7 @@ pgp_decipher(sc_card_t *card, const u8 * | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
sc_security_env_t *env = &priv->sec_env; | |||||
sc_apdu_t apdu; | |||||
+ u8 apdu_case = SC_APDU_CASE_4; | |||||
u8 *temp = NULL; | |||||
int r; | |||||
@@ -1408,7 +1431,7 @@ pgp_decipher(sc_card_t *card, const u8 * | |||||
case 0x01: /* Decryption key */ | |||||
case 0x02: /* authentication key */ | |||||
/* PSO DECIPHER */ | |||||
- sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x80, 0x86); | |||||
+ sc_format_apdu(card, &apdu, apdu_case, 0x2A, 0x80, 0x86); | |||||
break; | |||||
case 0x00: /* signature key */ | |||||
default: | |||||
@@ -1417,8 +1440,13 @@ pgp_decipher(sc_card_t *card, const u8 * | |||||
"invalid key reference"); | |||||
} | |||||
+ /* Gnuk only supports short APDU, so we need to use command chaining */ | |||||
+ if (card->type == SC_CARD_TYPE_OPENPGP_GNUK) { | |||||
+ apdu.flags |= SC_APDU_FLAGS_CHAINING; | |||||
+ } | |||||
+ | |||||
apdu.lc = inlen; | |||||
- apdu.data = in; | |||||
+ apdu.data = (u8 *)in; | |||||
apdu.datalen = inlen; | |||||
apdu.le = ((outlen >= 256) && !(card->caps & SC_CARD_CAP_APDU_EXT)) ? 256 : outlen; | |||||
apdu.resp = out; | |||||
@@ -1802,6 +1830,11 @@ static int pgp_gen_key(sc_card_t *card, | |||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); | |||||
} | |||||
+ if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && key_info->modulus_len != 2048) { | |||||
+ sc_log(card->ctx, "Gnuk does not support other key length than 2048."); | |||||
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); | |||||
+ } | |||||
+ | |||||
/* Set attributes for new-generated key */ | |||||
r = pgp_update_new_algo_attr(card, key_info); | |||||
LOG_TEST_RET(card->ctx, r, "Cannot set attributes for new-generated key"); | |||||
@@ -1809,7 +1842,9 @@ static int pgp_gen_key(sc_card_t *card, | |||||
/* Test whether we will need extended APDU. 1900 is an | |||||
* arbitrary modulus length which for sure fits into a short APDU. | |||||
* This idea is borrowed from GnuPG code. */ | |||||
- if (card->caps & SC_CARD_CAP_APDU_EXT && key_info->modulus_len > 1900) { | |||||
+ if (card->caps & SC_CARD_CAP_APDU_EXT | |||||
+ && key_info->modulus_len > 1900 | |||||
+ && card->type != SC_CARD_TYPE_OPENPGP_GNUK) { | |||||
/* We won't store to apdu variable yet, because it will be reset in | |||||
* sc_format_apdu() */ | |||||
apdu_le = card->max_recv_size; | |||||
Index: opensc-20150513/src/libopensc/cards.h | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/cards.h | |||||
+++ opensc-20150513/src/libopensc/cards.h | |||||
@@ -105,6 +105,7 @@ enum { | |||||
SC_CARD_TYPE_OPENPGP_BASE = 9000, | |||||
SC_CARD_TYPE_OPENPGP_V1, | |||||
SC_CARD_TYPE_OPENPGP_V2, | |||||
+ SC_CARD_TYPE_OPENPGP_GNUK, | |||||
/* jcop driver */ | |||||
SC_CARD_TYPE_JCOP_BASE = 10000, | |||||
Index: opensc-20150513/src/tools/openpgp-tool.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/tools/openpgp-tool.c | |||||
+++ opensc-20150513/src/tools/openpgp-tool.c | |||||
@@ -33,6 +33,7 @@ | |||||
#include "libopensc/cards.h" | |||||
#include "libopensc/cardctl.h" | |||||
#include "libopensc/errors.h" | |||||
+#include "libopensc/log.h" | |||||
#include "util.h" | |||||
#include "libopensc/log.h" | |||||
@@ -396,6 +397,8 @@ int do_genkey(sc_card_t *card, u8 key_id | |||||
sc_path_t path; | |||||
sc_file_t *file; | |||||
+ LOG_FUNC_CALLED(card->ctx); | |||||
+ | |||||
if (key_id < 1 || key_id > 3) { | |||||
printf("Unknown key ID %d.\n", key_id); | |||||
return 1; | |||||
@@ -487,8 +490,10 @@ int main(int argc, char **argv) | |||||
/* check card type */ | |||||
if ((card->type != SC_CARD_TYPE_OPENPGP_V1) && | |||||
- (card->type != SC_CARD_TYPE_OPENPGP_V2)) { | |||||
+ (card->type != SC_CARD_TYPE_OPENPGP_V2) && | |||||
+ (card->type != SC_CARD_TYPE_OPENPGP_GNUK)) { | |||||
util_error("not an OpenPGP card"); | |||||
+ sc_log(card->ctx, "Card type %X", card->type); | |||||
exit_status = EXIT_FAILURE; | |||||
goto out; | |||||
} |
@ -1,47 +0,0 @@ | |||||
From 00a2c08c9125103ee0bff9af9e7ff42c5cdc14fe 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, 12 Apr 2013 17:24:00 +0700 | |||||
Subject: [PATCH 02/26] OpenPGP: Add Gnuk in pkcs15 emulation layer. | |||||
--- | |||||
src/libopensc/pkcs15-openpgp.c | 6 ++++-- | |||||
src/libopensc/pkcs15-syn.c | 1 + | |||||
2 files changed, 5 insertions(+), 2 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/pkcs15-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/pkcs15-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/pkcs15-openpgp.c | |||||
@@ -153,7 +153,8 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card | |||||
u8 c4data[10]; | |||||
u8 c5data[70]; | |||||
int r, i; | |||||
- const pgp_pin_cfg_t *pin_cfg = (card->type == SC_CARD_TYPE_OPENPGP_V2) ? pin_cfg_v2 : pin_cfg_v1; | |||||
+ const pgp_pin_cfg_t *pin_cfg = (card->type == SC_CARD_TYPE_OPENPGP_V2 || card->type == SC_CARD_TYPE_OPENPGP_GNUK) | |||||
+ ? pin_cfg_v2 : pin_cfg_v1; | |||||
sc_path_t path; | |||||
sc_file_t *file; | |||||
@@ -365,7 +366,8 @@ failed: sc_debug(card->ctx, SC_LOG_DEBUG | |||||
static int openpgp_detect_card(sc_pkcs15_card_t *p15card) | |||||
{ | |||||
- if (p15card->card->type == SC_CARD_TYPE_OPENPGP_V1 || p15card->card->type == SC_CARD_TYPE_OPENPGP_V2) | |||||
+ if (p15card->card->type == SC_CARD_TYPE_OPENPGP_V1 || p15card->card->type == SC_CARD_TYPE_OPENPGP_V2 | |||||
+ || p15card->card->type == SC_CARD_TYPE_OPENPGP_GNUK) | |||||
return SC_SUCCESS; | |||||
else | |||||
return SC_ERROR_WRONG_CARD; | |||||
Index: opensc-20150513/src/libopensc/pkcs15-syn.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/pkcs15-syn.c | |||||
+++ opensc-20150513/src/libopensc/pkcs15-syn.c | |||||
@@ -117,6 +117,7 @@ int sc_pkcs15_is_emulation_only(sc_card_ | |||||
case SC_CARD_TYPE_GEMSAFEV1_PTEID: | |||||
case SC_CARD_TYPE_OPENPGP_V1: | |||||
case SC_CARD_TYPE_OPENPGP_V2: | |||||
+ case SC_CARD_TYPE_OPENPGP_GNUK: | |||||
case SC_CARD_TYPE_SC_HSM: | |||||
case SC_CARD_TYPE_DNIE_BASE: | |||||
case SC_CARD_TYPE_DNIE_BLANK: |
@ -1,27 +0,0 @@ | |||||
From 2d348b60ab8c22791b56f291600954abd716a791 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, 22 Mar 2013 17:37:16 +0700 | |||||
Subject: [PATCH 03/26] OpenPGP: Include private DO to filesystem at driver | |||||
initialization. | |||||
In old implementation, the DOs which their access is restricted by | |||||
PIN (like DOs 0101 -> 0104) were excluded from the fake filesystem, | |||||
leading to that we cannot read their data later, even if we verified PIN. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 2 +- | |||||
1 file changed, 1 insertion(+), 1 deletion(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -365,7 +365,7 @@ pgp_init(sc_card_t *card) | |||||
/* Populate MF - add matching blobs listed in the pgp_objects table. */ | |||||
for (info = priv->pgp_objects; (info != NULL) && (info->id > 0); info++) { | |||||
- if (((info->access & READ_MASK) == READ_ALWAYS) && | |||||
+ if (((info->access & READ_MASK) != READ_NEVER) && | |||||
(info->get_fn != NULL)) { | |||||
child = pgp_new_blob(card, priv->mf, info->id, sc_file_new()); | |||||
@ -1,79 +0,0 @@ | |||||
From fda9b6dd088e734de372fc85c091f88e8607bc2e 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: Tue, 26 Feb 2013 17:37:16 +0700 | |||||
Subject: [PATCH 04/26] PKCS15-OpenPGP: Declare DATA objects. | |||||
Begin to support read/write DATA object for PKCS-OpenPGP binding. | |||||
This object is used by TrueCrypt. | |||||
--- | |||||
src/libopensc/pkcs15-openpgp.c | 35 +++++++++++++++++++++++++++++++++++ | |||||
1 file changed, 35 insertions(+) | |||||
Index: opensc-20150513/src/libopensc/pkcs15-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/pkcs15-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/pkcs15-openpgp.c | |||||
@@ -34,6 +34,7 @@ | |||||
#include "log.h" | |||||
int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); | |||||
+static int sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *); | |||||
#define PGP_USER_PIN_FLAGS (SC_PKCS15_PIN_FLAG_CASE_SENSITIVE \ | |||||
@@ -43,6 +44,8 @@ int sc_pkcs15emu_openpgp_init_ex(sc_pkcs | |||||
| SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED \ | |||||
| SC_PKCS15_PIN_FLAG_SO_PIN) | |||||
+#define PGP_NUM_PRIVDO 4 | |||||
+ | |||||
typedef struct _pgp_pin_cfg { | |||||
const char *label; | |||||
int reference; | |||||
@@ -357,6 +360,9 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card | |||||
goto failed; | |||||
} | |||||
+ /* PKCS#15 DATA object from OpenPGP private DOs */ | |||||
+ r = sc_pkcs15emu_openpgp_add_data(p15card); | |||||
+ | |||||
return 0; | |||||
failed: sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Failed to initialize OpenPGP emulation: %s\n", | |||||
@@ -364,6 +370,35 @@ failed: sc_debug(card->ctx, SC_LOG_DEBUG | |||||
return r; | |||||
} | |||||
+static int | |||||
+sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *p15card) | |||||
+{ | |||||
+ sc_context_t *ctx = p15card->card->ctx; | |||||
+ int i, r; | |||||
+ | |||||
+ LOG_FUNC_CALLED(ctx); | |||||
+ /* There is 4 private DO from 0101 to 0104 */ | |||||
+ for (i = 1; i <= PGP_NUM_PRIVDO; i++) { | |||||
+ sc_pkcs15_data_info_t dat_info; | |||||
+ sc_pkcs15_object_t dat_obj; | |||||
+ char name[8]; | |||||
+ char path[9]; | |||||
+ memset(&dat_info, 0, sizeof(dat_info)); | |||||
+ memset(&dat_obj, 0, sizeof(dat_obj)); | |||||
+ | |||||
+ sprintf(name, "PrivDO%d", i); | |||||
+ sprintf(path, "3F00010%d", i); | |||||
+ | |||||
+ sc_format_path(path, &dat_info.path); | |||||
+ strlcpy(dat_obj.label, name, sizeof(dat_obj.label)); | |||||
+ strlcpy(dat_info.app_label, name, sizeof(dat_info.app_label)); | |||||
+ | |||||
+ sc_log(ctx, "Add %s data object", name); | |||||
+ r = sc_pkcs15emu_add_data_object(p15card, &dat_obj, &dat_info); | |||||
+ } | |||||
+ LOG_FUNC_RETURN(ctx, r); | |||||
+} | |||||
+ | |||||
static int openpgp_detect_card(sc_pkcs15_card_t *p15card) | |||||
{ | |||||
if (p15card->card->type == SC_CARD_TYPE_OPENPGP_V1 || p15card->card->type == SC_CARD_TYPE_OPENPGP_V2 |
@ -1,169 +0,0 @@ | |||||
From 6d138f0199575516bfaad18cbbafcfa2ee61e58f 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: Mon, 4 Mar 2013 11:28:08 +0700 | |||||
Subject: [PATCH 05/26] OpenPGP: Support erasing (reset) card. | |||||
Command: openpgp-tool --erase | |||||
--- | |||||
src/libopensc/card-openpgp.c | 64 ++++++++++++++++++++++++++++++++++++++++++++ | |||||
src/tools/openpgp-tool.c | 22 ++++++++++++++- | |||||
2 files changed, 85 insertions(+), 1 deletion(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -2206,6 +2206,66 @@ out: | |||||
#endif /* ENABLE_OPENSSL */ | |||||
+/** | |||||
+ * Erase card | |||||
+ **/ | |||||
+static int pgp_erase_card(sc_card_t *card) | |||||
+{ | |||||
+ sc_context_t *ctx = card->ctx; | |||||
+ u8 *apdustring[10] = { | |||||
+ "00:20:00:81:08:40:40:40:40:40:40:40:40", | |||||
+ "00:20:00:81:08:40:40:40:40:40:40:40:40", | |||||
+ "00:20:00:81:08:40:40:40:40:40:40:40:40", | |||||
+ "00:20:00:81:08:40:40:40:40:40:40:40:40", | |||||
+ "00:20:00:83:08:40:40:40:40:40:40:40:40", | |||||
+ "00:20:00:83:08:40:40:40:40:40:40:40:40", | |||||
+ "00:20:00:83:08:40:40:40:40:40:40:40:40", | |||||
+ "00:20:00:83:08:40:40:40:40:40:40:40:40", | |||||
+ "00:e6:00:00", | |||||
+ "00:44:00:00" | |||||
+ }; | |||||
+ u8 buf[SC_MAX_APDU_BUFFER_SIZE]; | |||||
+ u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; | |||||
+ sc_apdu_t apdu; | |||||
+ size_t len0; | |||||
+ int commandsnum = 10; | |||||
+ int i, r; | |||||
+ | |||||
+ LOG_FUNC_CALLED(ctx); | |||||
+ | |||||
+ /* Check card version */ | |||||
+ if (card->type != SC_CARD_TYPE_OPENPGP_V2) { | |||||
+ sc_log(ctx, "Card is not OpenPGP v2"); | |||||
+ LOG_FUNC_RETURN(ctx, SC_ERROR_NO_CARD_SUPPORT); | |||||
+ } | |||||
+ sc_log(ctx, "Card is OpenPGP v2. Erase card."); | |||||
+ | |||||
+ /* Iterate over 10 commands above */ | |||||
+ for (i = 0; i < commandsnum; i++) { | |||||
+ /* Convert the string to binary array */ | |||||
+ len0 = sizeof(buf); | |||||
+ sc_hex_to_bin(apdustring[i], buf, &len0); | |||||
+ printf("Sending: "); | |||||
+ for (r = 0; r < len0; r++) | |||||
+ printf("%02X ", buf[r]); | |||||
+ printf("\n"); | |||||
+ | |||||
+ /* 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"); | |||||
+ } | |||||
+ LOG_FUNC_RETURN(ctx, r); | |||||
+} | |||||
+ | |||||
/* ABI: card ctl: perform special card-specific operations */ | |||||
static int pgp_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) | |||||
{ | |||||
@@ -2232,6 +2292,10 @@ static int pgp_card_ctl(sc_card_t *card, | |||||
LOG_FUNC_RETURN(card->ctx, r); | |||||
break; | |||||
#endif /* ENABLE_OPENSSL */ | |||||
+ case SC_CARDCTL_ERASE_CARD: | |||||
+ r = pgp_erase_card(card); | |||||
+ LOG_FUNC_RETURN(card->ctx, r); | |||||
+ break; | |||||
} | |||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); | |||||
Index: opensc-20150513/src/tools/openpgp-tool.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/tools/openpgp-tool.c | |||||
+++ opensc-20150513/src/tools/openpgp-tool.c | |||||
@@ -78,6 +78,7 @@ static int opt_pin = 0; | |||||
static const char *pin = NULL; | |||||
static int opt_dump_do = 0; | |||||
static u8 do_dump_idx; | |||||
+static int opt_erase = 0; | |||||
static const char *app_name = "openpgp-tool"; | |||||
@@ -94,6 +95,7 @@ static const struct option options[] = { | |||||
{ "help", no_argument, NULL, 'h' }, | |||||
{ "verbose", no_argument, NULL, 'v' }, | |||||
{ "version", no_argument, NULL, 'V' }, | |||||
+ { "erase", no_argument, NULL, 'E' }, | |||||
{ "verify", required_argument, NULL, OPT_VERIFY }, | |||||
{ "pin", required_argument, NULL, OPT_PIN }, | |||||
{ "do", required_argument, NULL, 'd' }, | |||||
@@ -113,6 +115,7 @@ static const char *option_help[] = { | |||||
/* h */ "Print this help message", | |||||
/* v */ "Verbose operation. Use several times to enable debug output.", | |||||
/* V */ "Show version number", | |||||
+/* E */ "Erase (reset) the card", | |||||
"Verify PIN (CHV1, CHV2, CHV3...)", | |||||
"PIN string", | |||||
/* d */ "Dump private data object number <arg> (i.e. PRIVATE-DO-<arg>)" | |||||
@@ -232,7 +235,7 @@ static int decode_options(int argc, char | |||||
{ | |||||
int c; | |||||
- while ((c = getopt_long(argc, argv,"r:x:CUG:L:hwvVd:", options, (int *) 0)) != EOF) { | |||||
+ while ((c = getopt_long(argc, argv,"r:x:CUG:L:hwvVd:E", options, (int *) 0)) != EOF) { | |||||
switch (c) { | |||||
case 'r': | |||||
opt_reader = optarg; | |||||
@@ -294,6 +297,8 @@ static int decode_options(int argc, char | |||||
do_dump_idx = optarg[0] - '0'; | |||||
opt_dump_do++; | |||||
actions++; | |||||
+ case 'E': | |||||
+ opt_erase++; | |||||
break; | |||||
default: | |||||
util_print_usage_and_die(app_name, options, option_help, NULL); | |||||
@@ -452,6 +457,18 @@ int do_verify(sc_card_t *card, char *typ | |||||
return r; | |||||
} | |||||
+int do_erase(sc_card_t *card) | |||||
+{ | |||||
+ int r; | |||||
+ /* Check card version */ | |||||
+ if (card->type != SC_CARD_TYPE_OPENPGP_V2) { | |||||
+ printf("Do not erase card which is not OpenPGP v2\n"); | |||||
+ } | |||||
+ printf("Erase card\n"); | |||||
+ r = sc_card_ctl(card, SC_CARDCTL_ERASE_CARD, NULL); | |||||
+ return r; | |||||
+} | |||||
+ | |||||
int main(int argc, char **argv) | |||||
{ | |||||
sc_context_t *ctx = NULL; | |||||
@@ -531,6 +548,9 @@ int main(int argc, char **argv) | |||||
exit(EXIT_FAILURE); | |||||
} | |||||
+ if (opt_erase) | |||||
+ exit_status != do_erase(card); | |||||
+ | |||||
out: | |||||
sc_unlock(card); | |||||
sc_disconnect_card(card); |
@ -1,205 +0,0 @@ | |||||
From 469b6567d9adc4af6f49fa65534162673060454d 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: Mon, 4 Mar 2013 18:13:03 +0700 | |||||
Subject: [PATCH 06/26] openpgp-tool: Support deleting key in Gnuk. | |||||
--- | |||||
src/tools/openpgp-tool.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++ | |||||
1 file changed, 142 insertions(+) | |||||
Index: opensc-20150513/src/tools/openpgp-tool.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/tools/openpgp-tool.c | |||||
+++ opensc-20150513/src/tools/openpgp-tool.c | |||||
@@ -41,6 +41,7 @@ | |||||
#define OPT_PRETTY 257 | |||||
#define OPT_VERIFY 258 | |||||
#define OPT_PIN 259 | |||||
+#define OPT_DELKEY 260 | |||||
/* define structures */ | |||||
struct ef_name_map { | |||||
@@ -79,6 +80,7 @@ static const char *pin = NULL; | |||||
static int opt_dump_do = 0; | |||||
static u8 do_dump_idx; | |||||
static int opt_erase = 0; | |||||
+static int opt_delkey = 0; | |||||
static const char *app_name = "openpgp-tool"; | |||||
@@ -98,6 +100,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 }, | |||||
{ "do", required_argument, NULL, 'd' }, | |||||
{ NULL, 0, NULL, 0 } | |||||
}; | |||||
@@ -118,6 +121,7 @@ static const char *option_help[] = { | |||||
/* E */ "Erase (reset) the card", | |||||
"Verify PIN (CHV1, CHV2, CHV3...)", | |||||
"PIN string", | |||||
+ "Delete key (1, 2, 3 or all)", | |||||
/* d */ "Dump private data object number <arg> (i.e. PRIVATE-DO-<arg>)" | |||||
}; | |||||
@@ -300,6 +304,14 @@ static int decode_options(int argc, char | |||||
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); | |||||
} | |||||
@@ -457,6 +469,133 @@ int do_verify(sc_card_t *card, char *typ | |||||
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; | |||||
@@ -548,6 +687,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); | |||||
@ -1,24 +0,0 @@ | |||||
From d210faa377bcec63876f84b82540b110ede16e57 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: Mon, 4 Mar 2013 18:14:51 +0700 | |||||
Subject: [PATCH 07/26] OpenPGP: Correct building Extended Header List when | |||||
importing keys. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 2 +- | |||||
1 file changed, 1 insertion(+), 1 deletion(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -1988,7 +1988,7 @@ pgp_build_extended_header_list(sc_card_t | |||||
u8 *p = NULL; | |||||
u8 *components[] = {key_info->e, key_info->p, key_info->q, key_info->n}; | |||||
size_t componentlens[] = {key_info->e_len, key_info->p_len, key_info->q_len, key_info->n_len}; | |||||
- unsigned int componenttags[] = {0x91, 0x92, 0x93, 0x95}; | |||||
+ unsigned int componenttags[] = {0x91, 0x92, 0x93, 0x97}; | |||||
char *componentnames[] = { | |||||
"public exponent", | |||||
"prime p", |
@ -1,55 +0,0 @@ | |||||
From df98874784a77c96a7a1be54412a02a53fdd3a3e 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: Mon, 25 Mar 2013 11:58:38 +0700 | |||||
Subject: [PATCH 08/26] OpenPGP: Read some empty DOs from Gnuk. | |||||
In Gnuk, some empty DOs are returned as not exist, instead of existing with empty value. | |||||
So, we will consider them exist in driver. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 25 +++++++++++++++++++++++++ | |||||
1 file changed, 25 insertions(+) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -823,6 +823,23 @@ pgp_get_blob(sc_card_t *card, struct blo | |||||
} | |||||
} | |||||
+ /* This part is for "NOT FOUND" cases */ | |||||
+ | |||||
+ /* Special case: | |||||
+ * Gnuk does not have default value for children of DO 65 (DOs 5B, 5F2D, 5F35) | |||||
+ * So, if these blob was not found, we create it. */ | |||||
+ if (blob->id == 0x65 && (id == 0x5B || id == 0x5F2D || id == 0x5F35)) { | |||||
+ sc_log(card->ctx, "Create blob %X under %X", id, blob->id); | |||||
+ child = pgp_new_blob(card, blob, id, sc_file_new()); | |||||
+ if (child) { | |||||
+ pgp_set_blob(child, NULL, 0); | |||||
+ *ret = child; | |||||
+ return SC_SUCCESS; | |||||
+ } | |||||
+ else | |||||
+ sc_log(card->ctx, "Not enough memory to create blob for DO %X"); | |||||
+ } | |||||
+ | |||||
return SC_ERROR_FILE_NOT_FOUND; | |||||
} | |||||
@@ -1157,6 +1174,14 @@ pgp_get_data(sc_card_t *card, unsigned i | |||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); | |||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2); | |||||
+ | |||||
+ /* For Gnuk card, if there is no certificate, it returns error instead of empty data. | |||||
+ * So, for this case, we ignore error and consider success */ | |||||
+ if (r == SC_ERROR_DATA_OBJECT_NOT_FOUND && card->type == SC_CARD_TYPE_OPENPGP_GNUK | |||||
+ && (tag == DO_CERT || tag == 0x0101 || tag == 0x0102 || tag == 0x0103 || tag == 0x0104)) { | |||||
+ r = SC_SUCCESS; | |||||
+ apdu.resplen = 0; | |||||
+ } | |||||
LOG_TEST_RET(card->ctx, r, "Card returned error"); | |||||
LOG_FUNC_RETURN(card->ctx, apdu.resplen); |
@ -1,50 +0,0 @@ | |||||
From 42adc35954e18e24f253f710b16d850d1872bce5 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: Wed, 27 Mar 2013 11:38:42 +0700 | |||||
Subject: [PATCH 09/26] PKCS15-OpenPGP: Do not show empty DO in pkcs15 | |||||
emu_init. | |||||
--- | |||||
src/libopensc/pkcs15-openpgp.c | 18 ++++++++++++++++++ | |||||
1 file changed, 18 insertions(+) | |||||
Index: opensc-20150513/src/libopensc/pkcs15-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/pkcs15-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/pkcs15-openpgp.c | |||||
@@ -383,16 +383,34 @@ sc_pkcs15emu_openpgp_add_data(sc_pkcs15_ | |||||
sc_pkcs15_object_t dat_obj; | |||||
char name[8]; | |||||
char path[9]; | |||||
+ u8 content[254]; | |||||
memset(&dat_info, 0, sizeof(dat_info)); | |||||
memset(&dat_obj, 0, sizeof(dat_obj)); | |||||
sprintf(name, "PrivDO%d", i); | |||||
sprintf(path, "3F00010%d", i); | |||||
+ /* Check if the DO can be read. | |||||
+ * We won't expose pkcs15 DATA object if DO is empty. | |||||
+ */ | |||||
+ r = read_file(p15card->card, path, content, sizeof(content)); | |||||
+ if (r <= 0 ) { | |||||
+ sc_log(ctx, "Cannot read DO 010%d or there is no data in it", i); | |||||
+ /* Skip */ | |||||
+ continue; | |||||
+ } | |||||
sc_format_path(path, &dat_info.path); | |||||
strlcpy(dat_obj.label, name, sizeof(dat_obj.label)); | |||||
strlcpy(dat_info.app_label, name, sizeof(dat_info.app_label)); | |||||
+ /* Add DATA object to slot protected by PIN2 (PW1 with Ref 0x82) */ | |||||
+ dat_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE | SC_PKCS15_CO_FLAG_MODIFIABLE; | |||||
+ dat_obj.auth_id.len = 1; | |||||
+ if (i == 1 || i == 3) | |||||
+ dat_obj.auth_id.value[0] = 2; | |||||
+ else | |||||
+ dat_obj.auth_id.value[0] = 3; | |||||
+ | |||||
sc_log(ctx, "Add %s data object", name); | |||||
r = sc_pkcs15emu_add_data_object(p15card, &dat_obj, &dat_info); | |||||
} |
@ -1,88 +0,0 @@ | |||||
From f085e6a5f386875b5b071ef3bf115e4d9bb33bdb 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: Wed, 27 Mar 2013 11:39:33 +0700 | |||||
Subject: [PATCH 10/26] PKCS15-OpenPGP: Allow to store data to pkcs15 data | |||||
object. | |||||
Only one DO is supported now. | |||||
--- | |||||
src/libopensc/pkcs15-openpgp.c | 2 +- | |||||
src/pkcs15init/pkcs15-openpgp.c | 38 +++++++++++++++++++++++++++++++++++++- | |||||
2 files changed, 38 insertions(+), 2 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/pkcs15-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/pkcs15-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/pkcs15-openpgp.c | |||||
@@ -395,7 +395,7 @@ sc_pkcs15emu_openpgp_add_data(sc_pkcs15_ | |||||
*/ | |||||
r = read_file(p15card->card, path, content, sizeof(content)); | |||||
if (r <= 0 ) { | |||||
- sc_log(ctx, "Cannot read DO 010%d or there is no data in it", i); | |||||
+ sc_log(ctx, "No data get from DO 010%d", i); | |||||
/* Skip */ | |||||
continue; | |||||
} | |||||
Index: opensc-20150513/src/pkcs15init/pkcs15-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/pkcs15init/pkcs15-openpgp.c | |||||
+++ opensc-20150513/src/pkcs15init/pkcs15-openpgp.c | |||||
@@ -236,13 +236,16 @@ static int openpgp_emu_update_tokeninfo( | |||||
} | |||||
static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile *profile, | |||||
- struct sc_pkcs15_object *obj, struct sc_pkcs15_der *content, | |||||
+ struct sc_pkcs15_object *obj, struct sc_pkcs15_der *content, | |||||
struct sc_path *path) | |||||
{ | |||||
sc_card_t *card = p15card->card; | |||||
+ sc_context_t *ctx = card->ctx; | |||||
sc_file_t *file; | |||||
sc_pkcs15_cert_info_t *cinfo; | |||||
sc_pkcs15_id_t *cid; | |||||
+ sc_pkcs15_data_info_t *dinfo; | |||||
+ u8 buf[254]; | |||||
int r; | |||||
LOG_FUNC_CALLED(card->ctx); | |||||
@@ -282,6 +285,39 @@ static int openpgp_store_data(struct sc_ | |||||
content->len, 0); | |||||
break; | |||||
+ case SC_PKCS15_TYPE_DATA_OBJECT: | |||||
+ dinfo = (sc_pkcs15_data_info_t *) obj->data; | |||||
+ /* dinfo->app_label contains filename */ | |||||
+ sc_log(ctx, "===== App label %s", dinfo->app_label); | |||||
+ /* Currently, we only support DO 0101. The reason is that when initializing this | |||||
+ * pkcs15 emulation, PIN authentication is not applied and we can expose only this DO, | |||||
+ * which is "read always". | |||||
+ * If we support other DOs, they will not be exposed, and not helpful to user. | |||||
+ * I haven't found a way to refresh the list of exposed DOs after verifying PIN yet. | |||||
+ * http://sourceforge.net/mailarchive/message.php?msg_id=30646373 | |||||
+ **/ | |||||
+ sc_log(ctx, "About to write to DO 0101"); | |||||
+ sc_format_path("0101", path); | |||||
+ r = sc_select_file(card, path, &file); | |||||
+ LOG_TEST_RET(card->ctx, r, "Cannot select private DO"); | |||||
+ r = sc_read_binary(card, 0, buf, sizeof(buf), 0); | |||||
+ if (r < 0) { | |||||
+ sc_log(ctx, "Cannot read DO 0101"); | |||||
+ break; | |||||
+ } | |||||
+ if (r > 0) { | |||||
+ sc_log(ctx, "DO 0101 is full."); | |||||
+ r = SC_ERROR_TOO_MANY_OBJECTS; | |||||
+ break; | |||||
+ } | |||||
+ r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); | |||||
+ if (r >= 0 && content->len) { | |||||
+ r = sc_update_binary(p15card->card, 0, | |||||
+ (const unsigned char *) content->value, | |||||
+ content->len, 0); | |||||
+ } | |||||
+ break; | |||||
+ | |||||
default: | |||||
r = SC_ERROR_NOT_IMPLEMENTED; | |||||
} |
@ -1,84 +0,0 @@ | |||||
From 752f8981bed49a98d3592ead3aa50e743318dea8 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/26] OpenPGP: Provide enough buffer to read pubkey from | |||||
Gnuk. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 28 +++++++++++++++++++++++----- | |||||
1 file changed, 23 insertions(+), 5 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -265,7 +265,12 @@ static struct do_info pgp2_objects[] = | |||||
/* 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 { | |||||
@@ -739,6 +744,14 @@ pgp_read_blob(sc_card_t *card, struct bl | |||||
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 */ | |||||
@@ -1836,6 +1849,7 @@ static int pgp_gen_key(sc_card_t *card, | |||||
u8 apdu_case; | |||||
u8 *apdu_data; | |||||
size_t apdu_le; | |||||
+ size_t resplen = 0; | |||||
int r = SC_SUCCESS; | |||||
LOG_FUNC_CALLED(card->ctx); | |||||
@@ -1876,23 +1890,27 @@ static int pgp_gen_key(sc_card_t *card, | |||||
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,217 +0,0 @@ | |||||
From 5110ae3ba33d165c43ea5eca8f929a82d81cb3fe 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: Thu, 11 Apr 2013 11:47:51 +0700 | |||||
Subject: [PATCH 12/26] OpenPGP: Support write certificate for Gnuk. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 158 +++++++++++++++++++++++++++++++++---------- | |||||
1 file changed, 123 insertions(+), 35 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -735,6 +735,8 @@ pgp_iterate_blobs(struct blob *blob, int | |||||
static int | |||||
pgp_read_blob(sc_card_t *card, struct blob *blob) | |||||
{ | |||||
+ struct pgp_priv_data *priv = DRVDATA (card); | |||||
+ | |||||
if (blob->data != NULL) | |||||
return SC_SUCCESS; | |||||
if (blob->info == NULL) | |||||
@@ -745,6 +747,11 @@ pgp_read_blob(sc_card_t *card, struct bl | |||||
size_t buf_len = (card->caps & SC_CARD_CAP_APDU_EXT) | |||||
? sizeof(buffer) : 256; | |||||
+ /* Buffer length for certificate */ | |||||
+ if (blob->id == DO_CERT && priv->max_cert_size > 0) { | |||||
+ buf_len = MIN(priv->max_cert_size, sizeof(buffer)); | |||||
+ } | |||||
+ | |||||
/* Buffer length for Gnuk pubkey */ | |||||
if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && | |||||
(blob->id == 0xa400 || blob->id == 0xb600 || blob->id == 0xb800 | |||||
@@ -1200,49 +1207,75 @@ pgp_get_data(sc_card_t *card, unsigned i | |||||
LOG_FUNC_RETURN(card->ctx, apdu.resplen); | |||||
} | |||||
-/* ABI: PUT DATA */ | |||||
-static int | |||||
-pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len) | |||||
+ | |||||
+/* Internal: Write certificate for Gnuk */ | |||||
+static int gnuk_write_certificate(sc_card_t *card, const u8 *buf, size_t length) | |||||
{ | |||||
+ sc_context_t *ctx = card->ctx; | |||||
+ size_t i = 0; | |||||
sc_apdu_t apdu; | |||||
+ u8 *part; | |||||
+ size_t plen; | |||||
+ int r = SC_SUCCESS; | |||||
+ | |||||
+ LOG_FUNC_CALLED(ctx); | |||||
+ | |||||
+ /* If null data is passed, delete certificate */ | |||||
+ if (buf == NULL || length == 0) { | |||||
+ sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xD6, 0x85, 0); | |||||
+ r = sc_transmit_apdu(card, &apdu); | |||||
+ LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); | |||||
+ /* Check response */ | |||||
+ r = sc_check_sw(card, apdu.sw1, apdu.sw2); | |||||
+ LOG_FUNC_RETURN(card->ctx, length); | |||||
+ } | |||||
+ | |||||
+ /* Ref: gnuk_put_binary_libusb.py and gnuk_token.py in Gnuk source tree */ | |||||
+ /* Split data to segments of 256 bytes. Send each segment via command chaining, | |||||
+ * with particular P1 byte for each segment */ | |||||
+ while (i*256 < length) { | |||||
+ part = (u8 *)buf + i*256; | |||||
+ plen = MIN(length - i*256, 256); | |||||
+ | |||||
+ sc_log(card->ctx, "Write part %d from offset 0x%X, len %d", i+1, part, plen); | |||||
+ | |||||
+ if (i == 0) { | |||||
+ sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD6, 0x85, 0); | |||||
+ } | |||||
+ else { | |||||
+ sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD6, i, 0); | |||||
+ } | |||||
+ apdu.flags |= SC_APDU_FLAGS_CHAINING; | |||||
+ apdu.data = part; | |||||
+ apdu.datalen = apdu.lc = plen; | |||||
+ | |||||
+ r = sc_transmit_apdu(card, &apdu); | |||||
+ LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); | |||||
+ /* Check response */ | |||||
+ r = sc_check_sw(card, apdu.sw1, apdu.sw2); | |||||
+ LOG_TEST_RET(card->ctx, r, "UPDATE BINARY returned error"); | |||||
+ | |||||
+ /* To next part */ | |||||
+ i++; | |||||
+ } | |||||
+ LOG_FUNC_RETURN(card->ctx, length); | |||||
+} | |||||
+ | |||||
+ | |||||
+/* Internal: Use PUT DATA command to write */ | |||||
+static int | |||||
+pgp_put_data_plain(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len) | |||||
+{ | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
- struct blob *affected_blob = NULL; | |||||
- struct do_info *dinfo = NULL; | |||||
+ sc_context_t *ctx = card->ctx; | |||||
+ sc_apdu_t apdu; | |||||
u8 ins = 0xDA; | |||||
u8 p1 = tag >> 8; | |||||
u8 p2 = tag & 0xFF; | |||||
u8 apdu_case = SC_APDU_CASE_3; | |||||
int r; | |||||
- LOG_FUNC_CALLED(card->ctx); | |||||
- | |||||
- /* Check if the tag is writable */ | |||||
- affected_blob = pgp_find_blob(card, tag); | |||||
- | |||||
- /* Non-readable DOs have no represented blob, we have to check from pgp_get_info_by_tag */ | |||||
- if (affected_blob == NULL) | |||||
- dinfo = pgp_get_info_by_tag(card, tag); | |||||
- else | |||||
- dinfo = affected_blob->info; | |||||
- | |||||
- if (dinfo == NULL) { | |||||
- sc_log(card->ctx, "The DO %04X does not exist.", tag); | |||||
- LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); | |||||
- } | |||||
- else if ((dinfo->access & WRITE_MASK) == WRITE_NEVER) { | |||||
- sc_log(card->ctx, "DO %04X is not writable.", tag); | |||||
- LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ALLOWED); | |||||
- } | |||||
- | |||||
- /* Check data size. | |||||
- * We won't check other DOs than 7F21 (certificate), because their capacity | |||||
- * is hard-codded and may change in various version of the card. If we check here, | |||||
- * the driver may be sticked to a limit version number of card. | |||||
- * 7F21 size is soft-coded, so we can check it. */ | |||||
- if (tag == DO_CERT && buf_len > priv->max_cert_size) { | |||||
- sc_log(card->ctx, "Data size %ld exceeds DO size limit %ld.", buf_len, priv->max_cert_size); | |||||
- LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH); | |||||
- } | |||||
+ LOG_FUNC_CALLED(ctx); | |||||
/* Extended Header list (004D DO) needs a variant of PUT DATA command */ | |||||
if (tag == 0x004D) { | |||||
@@ -1268,15 +1301,70 @@ pgp_put_data(sc_card_t *card, unsigned i | |||||
apdu.lc = buf_len; | |||||
} | |||||
else { | |||||
+ /* This case is to empty DO */ | |||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_1, ins, p1, p2); | |||||
} | |||||
/* Send APDU to card */ | |||||
r = sc_transmit_apdu(card, &apdu); | |||||
- LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); | |||||
+ LOG_TEST_RET(ctx, r, "APDU transmit failed"); | |||||
/* Check response */ | |||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2); | |||||
+ if (r < 0) | |||||
+ LOG_FUNC_RETURN(ctx, r); | |||||
+ | |||||
+ LOG_FUNC_RETURN(ctx, buf_len); | |||||
+} | |||||
+ | |||||
+/* ABI: PUT DATA */ | |||||
+static int | |||||
+pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len) | |||||
+{ | |||||
+ struct pgp_priv_data *priv = DRVDATA(card); | |||||
+ struct blob *affected_blob = NULL; | |||||
+ struct do_info *dinfo = NULL; | |||||
+ int r; | |||||
+ | |||||
+ LOG_FUNC_CALLED(card->ctx); | |||||
+ | |||||
+ /* Check if the tag is writable */ | |||||
+ if (priv->current->id != tag) | |||||
+ affected_blob = pgp_find_blob(card, tag); | |||||
+ | |||||
+ /* Non-readable DOs have no represented blob, we have to check from pgp_get_info_by_tag */ | |||||
+ if (affected_blob == NULL) | |||||
+ dinfo = pgp_get_info_by_tag(card, tag); | |||||
+ else | |||||
+ dinfo = affected_blob->info; | |||||
+ | |||||
+ if (dinfo == NULL) { | |||||
+ sc_log(card->ctx, "The DO %04X does not exist.", tag); | |||||
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); | |||||
+ } | |||||
+ else if ((dinfo->access & WRITE_MASK) == WRITE_NEVER) { | |||||
+ sc_log(card->ctx, "DO %04X is not writable.", tag); | |||||
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ALLOWED); | |||||
+ } | |||||
+ | |||||
+ /* Check data size. | |||||
+ * We won't check other DOs than 7F21 (certificate), because their capacity | |||||
+ * is hard-codded and may change in various version of the card. If we check here, | |||||
+ * the driver may be sticked to a limit version number of card. | |||||
+ * 7F21 size is soft-coded, so we can check it. */ | |||||
+ if (tag == DO_CERT && buf_len > priv->max_cert_size) { | |||||
+ sc_log(card->ctx, "Data size %ld exceeds DO size limit %ld.", buf_len, priv->max_cert_size); | |||||
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH); | |||||
+ } | |||||
+ | |||||
+ if (tag == DO_CERT && card->type == SC_CARD_TYPE_OPENPGP_GNUK) { | |||||
+ /* Gnuk need a special way to write certificate. */ | |||||
+ r = gnuk_write_certificate(card, buf, buf_len); | |||||
+ } | |||||
+ else { | |||||
+ r = pgp_put_data_plain(card, tag, buf, buf_len); | |||||
+ } | |||||
+ | |||||
/* Instruct more in case of error */ | |||||
if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { | |||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Please verify PIN first."); |
@ -1,28 +0,0 @@ | |||||
From 7823e836e8279c8d77786d8f10ffaa83cf50bf1d 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: Wed, 10 Apr 2013 18:35:58 +0700 | |||||
Subject: [PATCH 13/26] pkcs15-openpgp: Change to sc_put_data instead of | |||||
sc_update_binary when writing certificate. | |||||
--- | |||||
src/pkcs15init/pkcs15-openpgp.c | 5 ++--- | |||||
1 file changed, 2 insertions(+), 3 deletions(-) | |||||
Index: opensc-20150513/src/pkcs15init/pkcs15-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/pkcs15init/pkcs15-openpgp.c | |||||
+++ opensc-20150513/src/pkcs15init/pkcs15-openpgp.c | |||||
@@ -279,10 +279,9 @@ static int openpgp_store_data(struct sc_ | |||||
r = sc_select_file(card, path, &file); | |||||
LOG_TEST_RET(card->ctx, r, "Cannot select cert file"); | |||||
r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); | |||||
+ sc_log(card->ctx, "Data to write is %d long", content->len); | |||||
if (r >= 0 && content->len) | |||||
- r = sc_update_binary(p15card->card, 0, | |||||
- (const unsigned char *) content->value, | |||||
- content->len, 0); | |||||
+ r = sc_put_data(p15card->card, 0x7F21, (const unsigned char *) content->value, content->len); | |||||
break; | |||||
case SC_PKCS15_TYPE_DATA_OBJECT: |
@ -1,50 +0,0 @@ | |||||
From 3ff1f7234abb4c42273adedbe06d9e7f9f3a5f9d 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: Thu, 11 Apr 2013 16:18:31 +0700 | |||||
Subject: [PATCH 14/26] OpenPGP: Overcome the restriction of even data length | |||||
of Gnuk. | |||||
When write certificate with odd length to Gnuk, we add zero padding to make it even. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 20 ++++++++++++++++++-- | |||||
1 file changed, 18 insertions(+), 2 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -1216,6 +1216,10 @@ static int gnuk_write_certificate(sc_car | |||||
sc_apdu_t apdu; | |||||
u8 *part; | |||||
size_t plen; | |||||
+ /* Two round_ variables below are to build APDU data | |||||
+ * with even length for Gnuk */ | |||||
+ u8 roundbuf[256]; | |||||
+ size_t roundlen = 0; | |||||
int r = SC_SUCCESS; | |||||
LOG_FUNC_CALLED(ctx); | |||||
@@ -1246,8 +1250,20 @@ static int gnuk_write_certificate(sc_car | |||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD6, i, 0); | |||||
} | |||||
apdu.flags |= SC_APDU_FLAGS_CHAINING; | |||||
- apdu.data = part; | |||||
- apdu.datalen = apdu.lc = plen; | |||||
+ | |||||
+ /* If the last part has odd length, we add zero padding to make it even. | |||||
+ * Gnuk does not allow data with odd length */ | |||||
+ if (plen < 256 && (plen % 2) != 0) { | |||||
+ roundlen = plen + 1; | |||||
+ memset(roundbuf, 0, roundlen); | |||||
+ memcpy(roundbuf, part, plen); | |||||
+ apdu.data = roundbuf; | |||||
+ apdu.datalen = apdu.lc = roundlen; | |||||
+ } | |||||
+ else { | |||||
+ apdu.data = part; | |||||
+ apdu.datalen = apdu.lc = plen; | |||||
+ } | |||||
r = sc_transmit_apdu(card, &apdu); | |||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); |
@ -1,89 +0,0 @@ | |||||
From 9af45c4cf052e3a6059a3004082f9ee3d2b3b2bf 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, 12 Apr 2013 15:33:31 +0700 | |||||
Subject: [PATCH 15/26] OpenPGP: Delete key as file, for Gnuk. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 51 +++++++++++++++++++++++++++++++++++++++++++- | |||||
1 file changed, 50 insertions(+), 1 deletion(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -2448,6 +2448,44 @@ static int pgp_card_ctl(sc_card_t *card, | |||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); | |||||
} | |||||
+ | |||||
+/* Internal: Delete key */ | |||||
+static int | |||||
+gnuk_delete_key(sc_card_t *card, u8 key_id) | |||||
+{ | |||||
+ sc_context_t *ctx = card->ctx; | |||||
+ int r = SC_SUCCESS; | |||||
+ u8 *data = NULL; | |||||
+ | |||||
+ LOG_FUNC_CALLED(ctx); | |||||
+ | |||||
+ /* Delete fingerprint */ | |||||
+ sc_log(ctx, "Delete fingerprints"); | |||||
+ r = pgp_put_data(card, 0xC6 + key_id, NULL, 0); | |||||
+ LOG_TEST_RET(ctx, r, "Failed to delete fingerprints"); | |||||
+ /* Delete creation time */ | |||||
+ sc_log(ctx, "Delete creation time"); | |||||
+ r = pgp_put_data(card, 0xCD + key_id, NULL, 0); | |||||
+ LOG_TEST_RET(ctx, r, "Failed to delete creation time"); | |||||
+ | |||||
+ /* 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 | |||||
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); | |||||
+ | |||||
+ r = pgp_put_data(card, 0x4D, data, strlen(data) + 1); | |||||
+ | |||||
+ LOG_FUNC_RETURN(ctx, r); | |||||
+} | |||||
+ | |||||
+ | |||||
/* ABI: DELETE FILE */ | |||||
static int | |||||
pgp_delete_file(sc_card_t *card, const sc_path_t *path) | |||||
@@ -2455,6 +2493,7 @@ pgp_delete_file(sc_card_t *card, const s | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
struct blob *blob; | |||||
sc_file_t *file; | |||||
+ u8 key_id; | |||||
int r; | |||||
LOG_FUNC_CALLED(card->ctx); | |||||
@@ -2470,10 +2509,20 @@ pgp_delete_file(sc_card_t *card, const s | |||||
if (blob == priv->mf) | |||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); | |||||
- if (file->id == 0xB601 || file->id == 0xB801 || file->id == 0xA401) { | |||||
+ if (card->type != SC_CARD_TYPE_OPENPGP_GNUK && | |||||
+ (file->id == 0xB601 || file->id == 0xB801 || file->id == 0xA401)) { | |||||
/* These tags are just symbolic. We don't really delete it. */ | |||||
r = SC_SUCCESS; | |||||
} | |||||
+ else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == 0xB601) { | |||||
+ r = gnuk_delete_key(card, 1); | |||||
+ } | |||||
+ else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == 0xB801) { | |||||
+ r = gnuk_delete_key(card, 2); | |||||
+ } | |||||
+ else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == 0xA401) { | |||||
+ r = gnuk_delete_key(card, 3); | |||||
+ } | |||||
else { | |||||
/* call pgp_put_data() with zero-sized NULL-buffer to zap the DO contents */ | |||||
r = pgp_put_data(card, file->id, NULL, 0); |
@ -1,44 +0,0 @@ | |||||
From ee23d262768e7e54ed0fc554bc0b869c65868ace 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: Tue, 16 Apr 2013 10:19:34 +0700 | |||||
Subject: [PATCH 16/26] OpenPGP: Correct parameter checking. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 9 +++++++-- | |||||
1 file changed, 7 insertions(+), 2 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -1231,6 +1231,8 @@ static int gnuk_write_certificate(sc_car | |||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); | |||||
/* Check response */ | |||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2); | |||||
+ if (r < 0) | |||||
+ LOG_FUNC_RETURN(card->ctx, r); | |||||
LOG_FUNC_RETURN(card->ctx, length); | |||||
} | |||||
@@ -2459,6 +2461,11 @@ gnuk_delete_key(sc_card_t *card, u8 key_ | |||||
LOG_FUNC_CALLED(ctx); | |||||
+ if (key_id < 1 || key_id > 3) { | |||||
+ sc_log(ctx, "Key ID %d is invalid. Should be 1, 2 or 3.", key_id); | |||||
+ LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); | |||||
+ } | |||||
+ | |||||
/* Delete fingerprint */ | |||||
sc_log(ctx, "Delete fingerprints"); | |||||
r = pgp_put_data(card, 0xC6 + key_id, NULL, 0); | |||||
@@ -2477,8 +2484,6 @@ gnuk_delete_key(sc_card_t *card, u8 key_ | |||||
data = "\x4D\x02\xB8"; | |||||
else if (key_id == 3) | |||||
data = "\x4D\x02\xA4"; | |||||
- else | |||||
- LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); | |||||
r = pgp_put_data(card, 0x4D, data, strlen(data) + 1); | |||||
@ -1,36 +0,0 @@ | |||||
From f4aec38233010953cea72c367bccc71c3687b2f1 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: Tue, 16 Apr 2013 16:02:17 +0700 | |||||
Subject: [PATCH 17/26] OpenPGP: Make code neater | |||||
--- | |||||
src/libopensc/card-openpgp.c | 8 ++------ | |||||
1 file changed, 2 insertions(+), 6 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -1230,10 +1230,7 @@ static int gnuk_write_certificate(sc_car | |||||
r = sc_transmit_apdu(card, &apdu); | |||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); | |||||
/* Check response */ | |||||
- r = sc_check_sw(card, apdu.sw1, apdu.sw2); | |||||
- if (r < 0) | |||||
- LOG_FUNC_RETURN(card->ctx, r); | |||||
- LOG_FUNC_RETURN(card->ctx, length); | |||||
+ LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Certificate writing failed"); | |||||
} | |||||
/* Ref: gnuk_put_binary_libusb.py and gnuk_token.py in Gnuk source tree */ | |||||
@@ -1270,8 +1267,7 @@ static int gnuk_write_certificate(sc_car | |||||
r = sc_transmit_apdu(card, &apdu); | |||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); | |||||
/* Check response */ | |||||
- r = sc_check_sw(card, apdu.sw1, apdu.sw2); | |||||
- LOG_TEST_RET(card->ctx, r, "UPDATE BINARY returned error"); | |||||
+ LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "UPDATE BINARY returned error"); | |||||
/* To next part */ | |||||
i++; |
@ -1,31 +0,0 @@ | |||||
From c84c84169f7a73eab27f6a9b13b77432baa5c3f8 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: Wed, 8 May 2013 16:51:21 +0700 | |||||
Subject: [PATCH 18/26] Move declaration to top of block. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 3 ++- | |||||
1 file changed, 2 insertions(+), 1 deletion(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -746,6 +746,7 @@ pgp_read_blob(sc_card_t *card, struct bl | |||||
u8 buffer[2048]; | |||||
size_t buf_len = (card->caps & SC_CARD_CAP_APDU_EXT) | |||||
? sizeof(buffer) : 256; | |||||
+ int r = SC_SUCCESS; | |||||
/* Buffer length for certificate */ | |||||
if (blob->id == DO_CERT && priv->max_cert_size > 0) { | |||||
@@ -759,7 +760,7 @@ pgp_read_blob(sc_card_t *card, struct bl | |||||
buf_len = MAXLEN_RESP_PUBKEY_GNUK; | |||||
} | |||||
- int r = blob->info->get_fn(card, blob->id, buffer, buf_len); | |||||
+ r = blob->info->get_fn(card, blob->id, buffer, buf_len); | |||||
if (r < 0) { /* an error occurred */ | |||||
blob->status = r; |
@ -1,179 +0,0 @@ | |||||
From c6abf7976f64be5191dc80fecdbcb07daab7a2e0 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: Sun, 3 Nov 2013 01:45:56 +0800 | |||||
Subject: [PATCH 19/26] OpenPGP: Make indentation consistent (space -> tab). | |||||
--- | |||||
src/libopensc/card-openpgp.c | 22 ++++++++--------- | |||||
src/tools/openpgp-tool.c | 56 ++++++++++++++++++++++---------------------- | |||||
2 files changed, 39 insertions(+), 39 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -194,12 +194,12 @@ static struct do_info pgp1_objects[] = | |||||
{ 0x5f35, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, | |||||
{ 0x5f50, SIMPLE, READ_ALWAYS | WRITE_PIN3, sc_get_data, sc_put_data }, | |||||
{ 0x7f49, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, NULL, NULL }, | |||||
- { 0xa400, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
- { 0xa401, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
- { 0xb600, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
- { 0xb601, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
- { 0xb800, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
- { 0xb801, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
+ { 0xa400, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
+ { 0xa401, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
+ { 0xb600, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
+ { 0xb601, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
+ { 0xb800, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
+ { 0xb801, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
{ 0, 0, 0, NULL, NULL }, | |||||
}; | |||||
@@ -255,11 +255,11 @@ static struct do_info pgp2_objects[] = | |||||
/* The 0xA401, 0xB601, 0xB801 are just symbolic, it does not represent any real DO. | |||||
* However, their R/W access condition may block the process of importing key in pkcs15init. | |||||
* So we set their accesses condition as WRITE_PIN3 (writable). */ | |||||
- { 0xa401, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
- { 0xb600, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
- { 0xb601, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
- { 0xb800, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
- { 0xb801, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
+ { 0xa401, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
+ { 0xb600, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
+ { 0xb601, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
+ { 0xb800, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
+ { 0xb801, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
{ 0, 0, 0, NULL, NULL }, | |||||
}; | |||||
Index: opensc-20150513/src/tools/openpgp-tool.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/tools/openpgp-tool.c | |||||
+++ opensc-20150513/src/tools/openpgp-tool.c | |||||
@@ -37,11 +37,11 @@ | |||||
#include "util.h" | |||||
#include "libopensc/log.h" | |||||
-#define OPT_RAW 256 | |||||
-#define OPT_PRETTY 257 | |||||
-#define OPT_VERIFY 258 | |||||
-#define OPT_PIN 259 | |||||
-#define OPT_DELKEY 260 | |||||
+#define OPT_RAW 256 | |||||
+#define OPT_PRETTY 257 | |||||
+#define OPT_VERIFY 258 | |||||
+#define OPT_PIN 259 | |||||
+#define OPT_DELKEY 260 | |||||
/* define structures */ | |||||
struct ef_name_map { | |||||
@@ -142,10 +142,10 @@ static const struct ef_name_map openpgp_ | |||||
static void show_version(void) | |||||
{ | |||||
fprintf(stderr, | |||||
- "openpgp-tool - OpenPGP card utility version " PACKAGE_VERSION "\n" | |||||
- "\n" | |||||
- "Copyright (c) 2012 Peter Marschall <peter@adpm.de>\n" | |||||
- "Licensed under LGPL v2\n"); | |||||
+ "openpgp-tool - OpenPGP card utility version " PACKAGE_VERSION "\n" | |||||
+ "\n" | |||||
+ "Copyright (c) 2012 Peter Marschall <peter@adpm.de>\n" | |||||
+ "Licensed under LGPL v2\n"); | |||||
} | |||||
@@ -176,16 +176,16 @@ static char *prettify_language(char *str | |||||
{ | |||||
if (str != NULL) { | |||||
switch (strlen(str)) { | |||||
- case 8: memmove(str+7, str+6, 1+strlen(str+6)); | |||||
+ case 8: memmove(str+7, str+6, 1+strlen(str+6)); | |||||
str[6] = ','; | |||||
/* fall through */ | |||||
- case 6: memmove(str+5, str+4, 1+strlen(str+4)); | |||||
+ case 6: memmove(str+5, str+4, 1+strlen(str+4)); | |||||
str[4] = ','; | |||||
/* fall through */ | |||||
- case 4: memmove(str+3, str+2, 1+strlen(str+2)); | |||||
+ case 4: memmove(str+3, str+2, 1+strlen(str+2)); | |||||
str[2] = ','; | |||||
/* fall through */ | |||||
- case 2: return str; | |||||
+ case 2: return str; | |||||
} | |||||
} | |||||
return NULL; | |||||
@@ -197,10 +197,10 @@ static char *prettify_gender(char *str) | |||||
{ | |||||
if (str != NULL) { | |||||
switch (*str) { | |||||
- case '0': return "unknown"; | |||||
- case '1': return "male"; | |||||
- case '2': return "female"; | |||||
- case '9': return "not applicable"; | |||||
+ case '0': return "unknown"; | |||||
+ case '1': return "male"; | |||||
+ case '2': return "female"; | |||||
+ case '9': return "not applicable"; | |||||
} | |||||
} | |||||
return NULL; | |||||
@@ -218,7 +218,7 @@ static void display_data(const struct ef | |||||
char *envvar; | |||||
envvar = malloc(strlen(mapping->env_name) + | |||||
- strlen(value) + 2); | |||||
+ strlen(value) + 2); | |||||
if (envvar != NULL) { | |||||
strcpy(envvar, mapping->env_name); | |||||
strcat(envvar, "="); | |||||
@@ -344,20 +344,20 @@ static int do_userinfo(sc_card_t *card) | |||||
if (!count) | |||||
continue; | |||||
- if (count > (int)sizeof(buf) - 1) { | |||||
+ if (count > (int)sizeof(buf) - 1) { | |||||
fprintf(stderr, "Too small buffer to read the OpenPGP data\n"); | |||||
return EXIT_FAILURE; | |||||
} | |||||
- | |||||
- r = sc_read_binary(card, 0, buf, count, 0); | |||||
- if (r < 0) { | |||||
+ | |||||
+ r = sc_read_binary(card, 0, buf, count, 0); | |||||
+ if (r < 0) { | |||||
fprintf(stderr, "%s: read failed - %s\n", openpgp_data[i].ef, sc_strerror(r)); | |||||
return EXIT_FAILURE; | |||||
- } | |||||
- if (r != count) { | |||||
- fprintf(stderr, "%s: expecting %d, got only %d bytes\n", openpgp_data[i].ef, count, r); | |||||
+ } | |||||
+ if (r != count) { | |||||
+ fprintf(stderr, "%s: expecting %d, got only %d bytes\n", openpgp_data[i].ef, count, r); | |||||
return EXIT_FAILURE; | |||||
- } | |||||
+ } | |||||
buf[count] = '\0'; | |||||
@@ -628,7 +628,7 @@ int main(int argc, char **argv) | |||||
r = sc_context_create(&ctx, &ctx_param); | |||||
if (r) { | |||||
util_fatal("failed to establish context: %s\n", | |||||
- sc_strerror(r)); | |||||
+ sc_strerror(r)); | |||||
return EXIT_FAILURE; | |||||
} | |||||
@@ -640,7 +640,7 @@ int main(int argc, char **argv) | |||||
r = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); | |||||
if (r) { | |||||
util_fatal("failed to connect to card: %s\n", | |||||
- sc_strerror(r)); | |||||
+ sc_strerror(r)); | |||||
return EXIT_FAILURE; | |||||
} | |||||
@ -1,81 +0,0 @@ | |||||
From 9acf5c1ad7d8a32b472203d3bd8860ea2cbde0e7 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: Sun, 3 Nov 2013 02:53:35 +0800 | |||||
Subject: [PATCH 20/26] OpenPGP: Don't use sc_log in openpgp-tool. | |||||
--- | |||||
src/tools/openpgp-tool.c | 21 +++++++++++---------- | |||||
1 file changed, 11 insertions(+), 10 deletions(-) | |||||
Index: opensc-20150513/src/tools/openpgp-tool.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/tools/openpgp-tool.c | |||||
+++ opensc-20150513/src/tools/openpgp-tool.c | |||||
@@ -414,8 +414,6 @@ int do_genkey(sc_card_t *card, u8 key_id | |||||
sc_path_t path; | |||||
sc_file_t *file; | |||||
- LOG_FUNC_CALLED(card->ctx); | |||||
- | |||||
if (key_id < 1 || key_id > 3) { | |||||
printf("Unknown key ID %d.\n", key_id); | |||||
return 1; | |||||
@@ -479,14 +477,14 @@ int delete_key_gnuk(sc_card_t *card, u8 | |||||
u8 *data = NULL; | |||||
/* Delete fingerprint */ | |||||
- sc_log(ctx, "Delete fingerprints"); | |||||
+ fprintf(stdout, "Delete fingerprints"); | |||||
r |= sc_put_data(card, 0xC6 + key_id, NULL, 0); | |||||
/* Delete creation time */ | |||||
- sc_log(ctx, "Delete creation time"); | |||||
+ fprintf(stdout, "Delete creation time"); | |||||
r |= sc_put_data(card, 0xCD + key_id, NULL, 0); | |||||
/* Rewrite Extended Header List */ | |||||
- sc_log(ctx, "Rewrite Extended Header List"); | |||||
+ fprintf(stdout, "Rewrite Extended Header List"); | |||||
if (key_id == 1) | |||||
data = "\x4D\x02\xB6"; | |||||
@@ -534,15 +532,18 @@ int delete_key_openpgp(sc_card_t *card, | |||||
/* 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); | |||||
+ fprintf(stderr, "Failed to build APDU: %s\n", sc_strerror(r)); | |||||
+ return r; | |||||
} | |||||
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"); | |||||
+ if (r) { | |||||
+ fprintf(stderr, "Transmiting APDU failed: %s\n", sc_strerror(r)); | |||||
+ return r; | |||||
+ } | |||||
} | |||||
/* TODO: Rewrite Extended Header List. | |||||
* Not support by OpenGPG v2 yet */ | |||||
@@ -557,7 +558,7 @@ int delete_key(sc_card_t *card, u8 key_i | |||||
LOG_FUNC_CALLED(ctx); | |||||
/* Check key ID */ | |||||
if (key_id < 1 || key_id > 3) { | |||||
- sc_log(ctx, "Invalid key ID %d", key_id); | |||||
+ fprintf(stderr, "Invalid key ID %d", key_id); | |||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); | |||||
} | |||||
@@ -649,7 +650,7 @@ int main(int argc, char **argv) | |||||
(card->type != SC_CARD_TYPE_OPENPGP_V2) && | |||||
(card->type != SC_CARD_TYPE_OPENPGP_GNUK)) { | |||||
util_error("not an OpenPGP card"); | |||||
- sc_log(card->ctx, "Card type %X", card->type); | |||||
+ fprintf(stderr, "Card type %X\n", card->type); | |||||
exit_status = EXIT_FAILURE; | |||||
goto out; | |||||
} |
@ -1,109 +0,0 @@ | |||||
From 0fdbf868976172486af210accafbab163452ff78 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: Sun, 3 Nov 2013 11:26:25 +0800 | |||||
Subject: [PATCH 21/26] OpenPGP: Don't reimplement gnuk_delete_key in | |||||
openpgp-tool. | |||||
--- | |||||
src/tools/openpgp-tool.c | 64 ++++++------------------------------------------ | |||||
1 file changed, 8 insertions(+), 56 deletions(-) | |||||
Index: opensc-20150513/src/tools/openpgp-tool.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/tools/openpgp-tool.c | |||||
+++ opensc-20150513/src/tools/openpgp-tool.c | |||||
@@ -468,38 +468,6 @@ int do_verify(sc_card_t *card, char *typ | |||||
} | |||||
/** | |||||
- * 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 */ | |||||
- fprintf(stdout, "Delete fingerprints"); | |||||
- r |= sc_put_data(card, 0xC6 + key_id, NULL, 0); | |||||
- /* Delete creation time */ | |||||
- fprintf(stdout, "Delete creation time"); | |||||
- r |= sc_put_data(card, 0xCD + key_id, NULL, 0); | |||||
- | |||||
- /* Rewrite Extended Header List */ | |||||
- fprintf(stdout, "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. | |||||
**/ | |||||
@@ -547,32 +515,13 @@ int delete_key_openpgp(sc_card_t *card, | |||||
} | |||||
/* 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) { | |||||
- fprintf(stderr, "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); | |||||
+ return r; | |||||
} | |||||
int do_delete_key(sc_card_t *card, u8 key_id) | |||||
{ | |||||
sc_context_t *ctx = card->ctx; | |||||
+ sc_path_t path; | |||||
int r = SC_SUCCESS; | |||||
/* Currently, only Gnuk supports deleting keys */ | |||||
@@ -586,13 +535,16 @@ int do_delete_key(sc_card_t *card, u8 ke | |||||
return SC_ERROR_INVALID_ARGUMENTS; | |||||
} | |||||
if (key_id == 1 || key_id == 'a') { | |||||
- r |= delete_key(card, 1); | |||||
+ sc_format_path("B601", &path); | |||||
+ r |= sc_delete_file(card, &path); | |||||
} | |||||
if (key_id == 2 || key_id == 'a') { | |||||
- r |= delete_key(card, 2); | |||||
+ sc_format_path("B801", &path); | |||||
+ r |= sc_delete_file(card, &path); | |||||
} | |||||
if (key_id == 3 || key_id == 'a') { | |||||
- r |= delete_key(card, 3); | |||||
+ sc_format_path("A401", &path); | |||||
+ r |= sc_delete_file(card, &path); | |||||
} | |||||
return r; | |||||
} |
@ -1,84 +0,0 @@ | |||||
From 0cd2a488d86006bb2740a4e73e7a0d859e1bf33c 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: Sun, 13 Jul 2014 17:37:59 +0800 | |||||
Subject: [PATCH 22/26] OpenPGP: Use directly binary array of APDUs for ERASE | |||||
command. | |||||
I used a string presentation before and it needed an extra conversion step. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 47 +++++++++++++++++++++++--------------------- | |||||
1 file changed, 25 insertions(+), 22 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -2358,24 +2358,27 @@ out: | |||||
static int pgp_erase_card(sc_card_t *card) | |||||
{ | |||||
sc_context_t *ctx = card->ctx; | |||||
- u8 *apdustring[10] = { | |||||
- "00:20:00:81:08:40:40:40:40:40:40:40:40", | |||||
- "00:20:00:81:08:40:40:40:40:40:40:40:40", | |||||
- "00:20:00:81:08:40:40:40:40:40:40:40:40", | |||||
- "00:20:00:81:08:40:40:40:40:40:40:40:40", | |||||
- "00:20:00:83:08:40:40:40:40:40:40:40:40", | |||||
- "00:20:00:83:08:40:40:40:40:40:40:40:40", | |||||
- "00:20:00:83:08:40:40:40:40:40:40:40:40", | |||||
- "00:20:00:83:08:40:40:40:40:40:40:40:40", | |||||
- "00:e6:00:00", | |||||
- "00:44:00:00" | |||||
+ /* Special series of commands to erase OpenPGP card, | |||||
+ * according to https://www.crypto-stick.com/en/faq | |||||
+ * (How to reset a Crypto Stick? question). | |||||
+ * Gnuk is known not to support this feature. */ | |||||
+ u8 apdu_binaries[10][13] = { | |||||
+ {0, 0x20, 0, 0x81, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, | |||||
+ {0, 0x20, 0, 0x81, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, | |||||
+ {0, 0x20, 0, 0x81, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, | |||||
+ {0, 0x20, 0, 0x81, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, | |||||
+ {0, 0x20, 0, 0x83, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, | |||||
+ {0, 0x20, 0, 0x83, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, | |||||
+ {0, 0x20, 0, 0x83, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, | |||||
+ {0, 0x20, 0, 0x83, 0x08, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40}, | |||||
+ {0, 0xe6, 0, 0}, | |||||
+ {0, 0x44, 0, 0} | |||||
}; | |||||
+ u8 apdu_lens[10] = {13, 13, 13, 13, 13, 13, 13, 13, 4, 4}; | |||||
u8 buf[SC_MAX_APDU_BUFFER_SIZE]; | |||||
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; | |||||
sc_apdu_t apdu; | |||||
- size_t len0; | |||||
- int commandsnum = 10; | |||||
- int i, r; | |||||
+ int i, l, r; | |||||
LOG_FUNC_CALLED(ctx); | |||||
@@ -2387,17 +2390,17 @@ static int pgp_erase_card(sc_card_t *car | |||||
sc_log(ctx, "Card is OpenPGP v2. Erase card."); | |||||
/* Iterate over 10 commands above */ | |||||
- for (i = 0; i < commandsnum; i++) { | |||||
- /* Convert the string to binary array */ | |||||
- len0 = sizeof(buf); | |||||
- sc_hex_to_bin(apdustring[i], buf, &len0); | |||||
- printf("Sending: "); | |||||
- for (r = 0; r < len0; r++) | |||||
- printf("%02X ", buf[r]); | |||||
+ for (i = 0; i < sizeof(apdu_lens); i++) { | |||||
+ /* Length of the binary array of the current command */ | |||||
+ l = apdu_lens[i]; | |||||
+ /* Print the command to console */ | |||||
+ printf("Sending %d: ", i); | |||||
+ for (r = 0; r < l; r++) | |||||
+ printf("%02X ", apdu_binaries[i][r]); | |||||
printf("\n"); | |||||
/* Build APDU from binary array */ | |||||
- r = sc_bytes2apdu(card->ctx, buf, len0, &apdu); | |||||
+ r = sc_bytes2apdu(card->ctx, apdu_binaries[i], l, &apdu); | |||||
if (r) { | |||||
sc_log(ctx, "Failed to build APDU"); | |||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); |
@ -1,336 +0,0 @@ | |||||
From 6f56ea4cfc52323002d818731a50a31e863b6843 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: Sun, 13 Jul 2014 19:41:36 +0800 | |||||
Subject: [PATCH 23/26] OpenPGP: Rename private "blob" type to avoid confusing | |||||
with variable name. | |||||
This name has been used for both data type and variable name of that | |||||
type. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 96 ++++++++++++++++++++++---------------------- | |||||
1 file changed, 49 insertions(+), 47 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -113,9 +113,9 @@ enum _card_state { | |||||
CARD_STATE_ACTIVATED = 0x05 | |||||
}; | |||||
-struct blob { | |||||
- struct blob * next; /* pointer to next sibling */ | |||||
- struct blob * parent; /* pointer to parent */ | |||||
+typedef struct pgp_blob { | |||||
+ struct pgp_blob * next; /* pointer to next sibling */ | |||||
+ struct pgp_blob * parent; /* pointer to parent */ | |||||
struct do_info *info; | |||||
sc_file_t * file; | |||||
@@ -124,8 +124,8 @@ struct blob { | |||||
unsigned char * data; | |||||
unsigned int len; | |||||
- struct blob * files; /* pointer to 1st child */ | |||||
-}; | |||||
+ struct pgp_blob * files; /* pointer to 1st child */ | |||||
+} pgp_blob_t; | |||||
struct do_info { | |||||
unsigned int id; /* ID of the DO in question */ | |||||
@@ -143,12 +143,12 @@ struct do_info { | |||||
static int pgp_get_card_features(sc_card_t *card); | |||||
static int pgp_finish(sc_card_t *card); | |||||
-static void pgp_iterate_blobs(struct blob *, int, void (*func)()); | |||||
+static void pgp_iterate_blobs(pgp_blob_t *, int, void (*func)()); | |||||
-static int pgp_get_blob(sc_card_t *card, struct blob *blob, | |||||
- unsigned int id, struct blob **ret); | |||||
-static struct blob * pgp_new_blob(sc_card_t *, struct blob *, unsigned int, sc_file_t *); | |||||
-static void pgp_free_blob(struct blob *); | |||||
+static int pgp_get_blob(sc_card_t *card, pgp_blob_t *blob, | |||||
+ unsigned int id, pgp_blob_t **ret); | |||||
+static pgp_blob_t * pgp_new_blob(sc_card_t *, pgp_blob_t *, unsigned int, sc_file_t *); | |||||
+static void pgp_free_blob(pgp_blob_t *); | |||||
static int pgp_get_pubkey(sc_card_t *, unsigned int, | |||||
u8 *, size_t); | |||||
static int pgp_get_pubkey_pem(sc_card_t *, unsigned int, | |||||
@@ -274,8 +274,8 @@ static struct do_info pgp2_objects[] = | |||||
#define DRVDATA(card) ((struct pgp_priv_data *) ((card)->drv_data)) | |||||
struct pgp_priv_data { | |||||
- struct blob * mf; | |||||
- struct blob * current; /* currently selected file */ | |||||
+ pgp_blob_t * mf; | |||||
+ pgp_blob_t * current; /* currently selected file */ | |||||
enum _version bcd_version; | |||||
struct do_info *pgp_objects; | |||||
@@ -313,7 +313,7 @@ pgp_init(sc_card_t *card) | |||||
sc_file_t *file = NULL; | |||||
struct do_info *info; | |||||
int r; | |||||
- struct blob *child = NULL; | |||||
+ pgp_blob_t *child = NULL; | |||||
LOG_FUNC_CALLED(card->ctx); | |||||
@@ -397,7 +397,7 @@ pgp_get_card_features(sc_card_t *card) | |||||
unsigned char *hist_bytes = card->atr.value; | |||||
size_t atr_len = card->atr.len; | |||||
size_t i = 0; | |||||
- struct blob *blob, *blob6e, *blob73; | |||||
+ pgp_blob_t *blob, *blob6e, *blob73; | |||||
/* parse card capabilities from historical bytes */ | |||||
while ((i < atr_len) && (hist_bytes[i] != 0x73)) | |||||
@@ -534,7 +534,7 @@ pgp_finish(sc_card_t *card) | |||||
/* internal: fill a blob's data */ | |||||
static int | |||||
-pgp_set_blob(struct blob *blob, const u8 *data, size_t len) | |||||
+pgp_set_blob(pgp_blob_t *blob, const u8 *data, size_t len) | |||||
{ | |||||
if (blob->data) | |||||
free(blob->data); | |||||
@@ -628,16 +628,16 @@ pgp_attach_acl(sc_card_t *card, sc_file_ | |||||
} | |||||
/* internal: append a blob to the list of children of a given parent blob */ | |||||
-static struct blob * | |||||
-pgp_new_blob(sc_card_t *card, struct blob *parent, unsigned int file_id, | |||||
+static pgp_blob_t * | |||||
+pgp_new_blob(sc_card_t *card, pgp_blob_t *parent, unsigned int file_id, | |||||
sc_file_t *file) | |||||
{ | |||||
- struct blob *blob = NULL; | |||||
+ pgp_blob_t *blob = NULL; | |||||
if (file == NULL) | |||||
return NULL; | |||||
- if ((blob = calloc(1, sizeof(struct blob))) != NULL) { | |||||
+ if ((blob = calloc(1, sizeof(pgp_blob_t))) != NULL) { | |||||
struct pgp_priv_data *priv = DRVDATA (card); | |||||
struct do_info *info; | |||||
@@ -651,7 +651,7 @@ pgp_new_blob(sc_card_t *card, struct blo | |||||
blob->parent = parent; | |||||
if (parent != NULL) { | |||||
- struct blob **p; | |||||
+ pgp_blob_t **p; | |||||
/* set file's path = parent's path + file's id */ | |||||
blob->file->path = parent->file->path; | |||||
@@ -689,11 +689,11 @@ pgp_new_blob(sc_card_t *card, struct blo | |||||
/* internal: free a blob including its content */ | |||||
static void | |||||
-pgp_free_blob(struct blob *blob) | |||||
+pgp_free_blob(pgp_blob_t *blob) | |||||
{ | |||||
if (blob) { | |||||
if (blob->parent) { | |||||
- struct blob **p; | |||||
+ pgp_blob_t **p; | |||||
/* remove blob from list of parent's children */ | |||||
for (p = &blob->parent->files; *p != NULL && *p != blob; p = &(*p)->next) | |||||
@@ -713,14 +713,14 @@ pgp_free_blob(struct blob *blob) | |||||
/* internal: iterate through the blob tree, calling a function for each blob */ | |||||
static void | |||||
-pgp_iterate_blobs(struct blob *blob, int level, void (*func)()) | |||||
+pgp_iterate_blobs(pgp_blob_t *blob, int level, void (*func)()) | |||||
{ | |||||
if (blob) { | |||||
if (level > 0) { | |||||
- struct blob *child = blob->files; | |||||
+ pgp_blob_t *child = blob->files; | |||||
while (child != NULL) { | |||||
- struct blob *next = child->next; | |||||
+ pgp_blob_t *next = child->next; | |||||
pgp_iterate_blobs(child, level-1, func); | |||||
child = next; | |||||
@@ -733,7 +733,7 @@ pgp_iterate_blobs(struct blob *blob, int | |||||
/* internal: read a blob's contents from card */ | |||||
static int | |||||
-pgp_read_blob(sc_card_t *card, struct blob *blob) | |||||
+pgp_read_blob(sc_card_t *card, pgp_blob_t *blob) | |||||
{ | |||||
struct pgp_priv_data *priv = DRVDATA (card); | |||||
@@ -780,7 +780,7 @@ pgp_read_blob(sc_card_t *card, struct bl | |||||
* The OpenPGP card has a TLV encoding according ASN.1 BER-encoding rules. | |||||
*/ | |||||
static int | |||||
-pgp_enumerate_blob(sc_card_t *card, struct blob *blob) | |||||
+pgp_enumerate_blob(sc_card_t *card, pgp_blob_t *blob) | |||||
{ | |||||
const u8 *in; | |||||
int r; | |||||
@@ -797,7 +797,7 @@ pgp_enumerate_blob(sc_card_t *card, stru | |||||
unsigned int cla, tag, tmptag; | |||||
size_t len; | |||||
const u8 *data = in; | |||||
- struct blob *new; | |||||
+ pgp_blob_t *new; | |||||
r = sc_asn1_read_tag(&data, blob->len - (in - blob->data), | |||||
&cla, &tag, &len); | |||||
@@ -827,10 +827,10 @@ pgp_enumerate_blob(sc_card_t *card, stru | |||||
/* internal: find a blob by ID below a given parent, filling its contents when necessary */ | |||||
static int | |||||
-pgp_get_blob(sc_card_t *card, struct blob *blob, unsigned int id, | |||||
- struct blob **ret) | |||||
+pgp_get_blob(sc_card_t *card, pgp_blob_t *blob, unsigned int id, | |||||
+ pgp_blob_t **ret) | |||||
{ | |||||
- struct blob *child; | |||||
+ pgp_blob_t *child; | |||||
int r; | |||||
if ((r = pgp_enumerate_blob(card, blob)) < 0) | |||||
@@ -866,10 +866,10 @@ pgp_get_blob(sc_card_t *card, struct blo | |||||
/* Internal: search recursively for a blob by ID below a given root */ | |||||
static int | |||||
-pgp_seek_blob(sc_card_t *card, struct blob *root, unsigned int id, | |||||
- struct blob **ret) | |||||
+pgp_seek_blob(sc_card_t *card, pgp_blob_t *root, unsigned int id, | |||||
+ pgp_blob_t **ret) | |||||
{ | |||||
- struct blob *child; | |||||
+ pgp_blob_t *child; | |||||
int r; | |||||
if ((r = pgp_get_blob(card, root, id, ret)) == 0) | |||||
@@ -891,11 +891,11 @@ pgp_seek_blob(sc_card_t *card, struct bl | |||||
} | |||||
/* internal: find a blob by tag - pgp_seek_blob with optimizations */ | |||||
-static struct blob * | |||||
+static pgp_blob_t * | |||||
pgp_find_blob(sc_card_t *card, unsigned int tag) | |||||
{ | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
- struct blob *blob = NULL; | |||||
+ pgp_blob_t *blob = NULL; | |||||
int r; | |||||
/* Check if current selected blob is which we want to test*/ | |||||
@@ -949,7 +949,7 @@ static int | |||||
pgp_select_file(sc_card_t *card, const sc_path_t *path, sc_file_t **ret) | |||||
{ | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
- struct blob *blob; | |||||
+ pgp_blob_t *blob; | |||||
unsigned int path_start = 0; | |||||
unsigned int n; | |||||
sc_path_t dummy_path; | |||||
@@ -1030,7 +1030,7 @@ static int | |||||
pgp_list_files(sc_card_t *card, u8 *buf, size_t buflen) | |||||
{ | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
- struct blob *blob; | |||||
+ pgp_blob_t *blob; | |||||
unsigned int k; | |||||
int r; | |||||
@@ -1066,7 +1066,7 @@ pgp_read_binary(sc_card_t *card, unsigne | |||||
u8 *buf, size_t count, unsigned long flags) | |||||
{ | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
- struct blob *blob; | |||||
+ pgp_blob_t *blob; | |||||
int r; | |||||
LOG_FUNC_CALLED(card->ctx); | |||||
@@ -1142,7 +1142,7 @@ static int | |||||
pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) | |||||
{ | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
- struct blob *blob, *mod_blob, *exp_blob; | |||||
+ pgp_blob_t *blob, *mod_blob, *exp_blob; | |||||
sc_pkcs15_pubkey_t pubkey; | |||||
u8 *data; | |||||
size_t len; | |||||
@@ -1337,7 +1337,7 @@ static int | |||||
pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len) | |||||
{ | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
- struct blob *affected_blob = NULL; | |||||
+ pgp_blob_t *affected_blob = NULL; | |||||
struct do_info *dinfo = NULL; | |||||
int r; | |||||
@@ -1611,7 +1611,7 @@ static int | |||||
pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) | |||||
{ | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
- struct blob *algo_blob; | |||||
+ pgp_blob_t *algo_blob; | |||||
unsigned int old_modulus_len; /* Measured in bit */ | |||||
unsigned int old_exponent_len; | |||||
const unsigned int tag = 0x00C0 | key_info->keytype; | |||||
@@ -1716,7 +1716,7 @@ pgp_calculate_and_store_fingerprint(sc_c | |||||
u8 *p; /* Use this pointer to set fp_buffer content */ | |||||
size_t pk_packet_len; | |||||
unsigned int tag; | |||||
- struct blob *fpseq_blob; | |||||
+ pgp_blob_t *fpseq_blob; | |||||
u8 *newdata; | |||||
int r; | |||||
@@ -1805,7 +1805,7 @@ pgp_update_pubkey_blob(sc_card_t *card, | |||||
u8* exponent, size_t exponent_len, u8 key_id) | |||||
{ | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
- struct blob *pk_blob; | |||||
+ pgp_blob_t *pk_blob; | |||||
unsigned int blob_id; | |||||
sc_pkcs15_pubkey_t pubkey; | |||||
u8 *data = NULL; | |||||
@@ -1947,6 +1947,8 @@ static int pgp_update_card_algorithms(sc | |||||
**/ | |||||
static int pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) | |||||
{ | |||||
+ struct pgp_priv_data *priv = DRVDATA(card); | |||||
+ pgp_blob_t *algo_blob; | |||||
sc_apdu_t apdu; | |||||
/* Temporary variables to hold APDU params */ | |||||
u8 apdu_case; | |||||
@@ -2143,7 +2145,7 @@ pgp_build_extended_header_list(sc_card_t | |||||
}; | |||||
size_t comp_to_add = 3; | |||||
size_t req_e_len = 0; /* The exponent length specified in Algorithm Attributes */ | |||||
- struct blob *alat_blob; | |||||
+ pgp_blob_t *alat_blob; | |||||
u8 i; | |||||
int r; | |||||
@@ -2496,7 +2498,7 @@ static int | |||||
pgp_delete_file(sc_card_t *card, const sc_path_t *path) | |||||
{ | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
- struct blob *blob; | |||||
+ pgp_blob_t *blob; | |||||
sc_file_t *file; | |||||
u8 key_id; | |||||
int r; | |||||
@@ -2546,7 +2548,7 @@ pgp_update_binary(sc_card_t *card, unsig | |||||
const u8 *buf, size_t count, unsigned long flags) | |||||
{ | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
- struct blob *blob = priv->current; | |||||
+ pgp_blob_t *blob = priv->current; | |||||
int r = SC_SUCCESS; | |||||
LOG_FUNC_CALLED(card->ctx); |
@ -1,38 +0,0 @@ | |||||
From 8a87a4ee9107f250254d5c93c6fd62224c400ce7 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: Mon, 14 Jul 2014 01:30:28 +0800 | |||||
Subject: [PATCH 24/26] OpenPGP: Fix crash after accessing inexistent file. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 3 --- | |||||
1 file changed, 3 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -981,7 +981,6 @@ pgp_select_file(sc_card_t *card, const s | |||||
* So we set its size to be the same as max certificate size the card supports. */ | |||||
(*ret)->size = priv->max_cert_size; | |||||
} | |||||
- priv->current = NULL; | |||||
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); | |||||
} | |||||
@@ -998,7 +997,6 @@ pgp_select_file(sc_card_t *card, const s | |||||
/* This file ID is referred when importing key&certificate via pkcs15init, like above. | |||||
* We pretend to successfully find this inexistent file. */ | |||||
if (id == 0x4402 || id == 0x5f48) { | |||||
- priv->current = NULL; | |||||
if (ret == NULL) | |||||
/* No need to return file */ | |||||
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); | |||||
@@ -1010,7 +1008,6 @@ pgp_select_file(sc_card_t *card, const s | |||||
} | |||||
if (r < 0) { /* failure */ | |||||
- priv->current = NULL; | |||||
LOG_FUNC_RETURN(card->ctx, r); | |||||
} | |||||
} |
@ -1,145 +0,0 @@ | |||||
From da70a41383e2ab81fbcc89fb1067f5a189e0fb97 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: Sun, 9 Nov 2014 15:58:40 +0700 | |||||
Subject: [PATCH 25/26] Replace hardcode. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 72 +++++++++++++++++++++++++------------------- | |||||
1 file changed, 41 insertions(+), 31 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -154,6 +154,24 @@ static int pgp_get_pubkey(sc_card_t *, | |||||
static int pgp_get_pubkey_pem(sc_card_t *, unsigned int, | |||||
u8 *, size_t); | |||||
+/* 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 | |||||
+/* Control Reference Template of private keys. Ref: Section 4.3.3.7 of OpenPGP card v2 spec. | |||||
+ * Here we seen it as DO just for convenient */ | |||||
+#define DO_SIGN 0xb600 | |||||
+#define DO_ENCR 0xb800 | |||||
+#define DO_AUTH 0xa400 | |||||
+/* These DO does not exist. They are defined and used just for ease of implementation */ | |||||
+#define DO_SIGN_SYM 0xb601 | |||||
+#define DO_ENCR_SYM 0xb801 | |||||
+#define DO_AUTH_SYM 0xa401 | |||||
+/* 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 | |||||
+ | |||||
static struct do_info pgp1_objects[] = { /* OpenPGP card spec 1.1 */ | |||||
{ 0x004f, SIMPLE, READ_ALWAYS | WRITE_NEVER, NULL, NULL }, | |||||
{ 0x005b, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, | |||||
@@ -194,12 +212,12 @@ static struct do_info pgp1_objects[] = | |||||
{ 0x5f35, SIMPLE, READ_ALWAYS | WRITE_PIN3, NULL, sc_put_data }, | |||||
{ 0x5f50, SIMPLE, READ_ALWAYS | WRITE_PIN3, sc_get_data, sc_put_data }, | |||||
{ 0x7f49, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, NULL, NULL }, | |||||
- { 0xa400, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
- { 0xa401, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
- { 0xb600, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
- { 0xb601, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
- { 0xb800, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
- { 0xb801, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
+ { DO_AUTH, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
+ { DO_AUTH_SYM, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
+ { DO_SIGN, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
+ { DO_SIGN_SYM, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
+ { DO_ENCR, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
+ { DO_ENCR_SYM, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
{ 0, 0, 0, NULL, NULL }, | |||||
}; | |||||
@@ -248,30 +266,21 @@ static struct do_info pgp2_objects[] = | |||||
{ 0x5f52, SIMPLE, READ_ALWAYS | WRITE_NEVER, sc_get_data, NULL }, | |||||
/* The 7F21 is constructed DO in spec, but in practice, its content can be retrieved | |||||
* as simple DO (no need to parse TLV). */ | |||||
- { 0x7f21, SIMPLE, READ_ALWAYS | WRITE_PIN3, sc_get_data, sc_put_data }, | |||||
+ { DO_CERT, SIMPLE, READ_ALWAYS | WRITE_PIN3, sc_get_data, sc_put_data }, | |||||
{ 0x7f48, CONSTRUCTED, READ_NEVER | WRITE_NEVER, NULL, NULL }, | |||||
{ 0x7f49, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, NULL, NULL }, | |||||
- { 0xa400, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
+ { DO_AUTH, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
/* The 0xA401, 0xB601, 0xB801 are just symbolic, it does not represent any real DO. | |||||
* However, their R/W access condition may block the process of importing key in pkcs15init. | |||||
* So we set their accesses condition as WRITE_PIN3 (writable). */ | |||||
- { 0xa401, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
- { 0xb600, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
- { 0xb601, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
- { 0xb800, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
- { 0xb801, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
+ { DO_AUTH_SYM, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
+ { DO_SIGN, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
+ { DO_SIGN_SYM, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
+ { DO_ENCR, CONSTRUCTED, READ_ALWAYS | WRITE_NEVER, pgp_get_pubkey, NULL }, | |||||
+ { DO_ENCR_SYM, SIMPLE, READ_ALWAYS | WRITE_PIN3, pgp_get_pubkey_pem, NULL }, | |||||
{ 0, 0, 0, NULL, NULL }, | |||||
}; | |||||
-/* 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 | |||||
-/* 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 { | |||||
pgp_blob_t * mf; | |||||
@@ -755,8 +764,9 @@ pgp_read_blob(sc_card_t *card, pgp_blob_ | |||||
/* 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)) { | |||||
+ (blob->id == DO_AUTH || blob->id == DO_SIGN || blob->id == DO_ENCR | |||||
+ || blob->id == DO_AUTH_SYM || blob->id == DO_SIGN_SYM | |||||
+ || blob->id == DO_ENCR_SYM)) { | |||||
buf_len = MAXLEN_RESP_PUBKEY_GNUK; | |||||
} | |||||
@@ -1812,11 +1822,11 @@ pgp_update_pubkey_blob(sc_card_t *card, | |||||
LOG_FUNC_CALLED(card->ctx); | |||||
if (key_id == SC_OPENPGP_KEY_SIGN) | |||||
- blob_id = 0xB601; | |||||
+ blob_id = DO_SIGN_SYM; | |||||
else if (key_id == SC_OPENPGP_KEY_ENCR) | |||||
- blob_id = 0xB801; | |||||
+ blob_id = DO_ENCR_SYM; | |||||
else if (key_id == SC_OPENPGP_KEY_AUTH) | |||||
- blob_id = 0xA401; | |||||
+ blob_id = DO_AUTH_SYM; | |||||
else { | |||||
sc_log(card->ctx, "Unknown key id %X.", key_id); | |||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); | |||||
@@ -2514,17 +2524,17 @@ pgp_delete_file(sc_card_t *card, const s | |||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); | |||||
if (card->type != SC_CARD_TYPE_OPENPGP_GNUK && | |||||
- (file->id == 0xB601 || file->id == 0xB801 || file->id == 0xA401)) { | |||||
+ (file->id == DO_SIGN_SYM || file->id == DO_ENCR_SYM || file->id == DO_AUTH_SYM)) { | |||||
/* These tags are just symbolic. We don't really delete it. */ | |||||
r = SC_SUCCESS; | |||||
} | |||||
- else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == 0xB601) { | |||||
+ else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == DO_SIGN_SYM) { | |||||
r = gnuk_delete_key(card, 1); | |||||
} | |||||
- else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == 0xB801) { | |||||
+ else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == DO_ENCR_SYM) { | |||||
r = gnuk_delete_key(card, 2); | |||||
} | |||||
- else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == 0xA401) { | |||||
+ else if (card->type == SC_CARD_TYPE_OPENPGP_GNUK && file->id == DO_AUTH_SYM) { | |||||
r = gnuk_delete_key(card, 3); | |||||
} | |||||
else { |
@ -1,50 +0,0 @@ | |||||
From b9dae832db54b206a15bcc12e290cef50f31c3d0 Mon Sep 17 00:00:00 2001 | |||||
From: george <ggkitsas@yahoo.com> | |||||
Date: Tue, 11 Nov 2014 16:16:15 +0100 | |||||
Subject: [PATCH 26/26] hardcode->defines for DO's | |||||
--- | |||||
src/libopensc/card-openpgp.c | 16 ++++++++++++++-- | |||||
1 file changed, 14 insertions(+), 2 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -166,6 +166,18 @@ static int pgp_get_pubkey_pem(sc_card_t | |||||
#define DO_SIGN_SYM 0xb601 | |||||
#define DO_ENCR_SYM 0xb801 | |||||
#define DO_AUTH_SYM 0xa401 | |||||
+/* Private DO's */ | |||||
+#define DO_PRIV1 0x0101 | |||||
+#define DO_PRIV2 0x0102 | |||||
+#define DO_PRIV3 0x0103 | |||||
+#define DO_PRIV4 0x0104 | |||||
+/* Cardholder information DO's */ | |||||
+#define DO_CARDHOLDER 0x65 | |||||
+#define DO_NAME 0x5b | |||||
+#define DO_LANG_PREF 0x5f2d | |||||
+#define DO_SEX 0x5f35 | |||||
+ | |||||
+ | |||||
/* Maximum length for response buffer when reading pubkey. This value is calculated with | |||||
* 4096-bit key length */ | |||||
#define MAXLEN_RESP_PUBKEY 527 | |||||
@@ -859,7 +871,7 @@ pgp_get_blob(sc_card_t *card, pgp_blob_t | |||||
/* Special case: | |||||
* Gnuk does not have default value for children of DO 65 (DOs 5B, 5F2D, 5F35) | |||||
* So, if these blob was not found, we create it. */ | |||||
- if (blob->id == 0x65 && (id == 0x5B || id == 0x5F2D || id == 0x5F35)) { | |||||
+ if (blob->id == DO_CARDHOLDER && (id == DO_NAME || id == DO_LANG_PREF || id == DO_SEX)) { | |||||
sc_log(card->ctx, "Create blob %X under %X", id, blob->id); | |||||
child = pgp_new_blob(card, blob, id, sc_file_new()); | |||||
if (child) { | |||||
@@ -1206,7 +1218,7 @@ pgp_get_data(sc_card_t *card, unsigned i | |||||
/* For Gnuk card, if there is no certificate, it returns error instead of empty data. | |||||
* So, for this case, we ignore error and consider success */ | |||||
if (r == SC_ERROR_DATA_OBJECT_NOT_FOUND && card->type == SC_CARD_TYPE_OPENPGP_GNUK | |||||
- && (tag == DO_CERT || tag == 0x0101 || tag == 0x0102 || tag == 0x0103 || tag == 0x0104)) { | |||||
+ && (tag == DO_CERT || tag == DO_PRIV1 || tag == DO_PRIV2 || tag == DO_PRIV3 || tag == DO_PRIV4)) { | |||||
r = SC_SUCCESS; | |||||
apdu.resplen = 0; | |||||
} |
@ -1,82 +0,0 @@ | |||||
From 99b5cb53e1da2f0d7692f28dceff8485d4b74daf 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: Wed, 10 Dec 2014 03:59:54 +0800 | |||||
Subject: [PATCH 1/2] OpenPGP: Remove unused variables and fix type cast. | |||||
--- | |||||
src/libopensc/card-openpgp.c | 10 +++------- | |||||
src/tools/openpgp-tool.c | 4 +--- | |||||
2 files changed, 4 insertions(+), 10 deletions(-) | |||||
Index: opensc-20150513/src/libopensc/card-openpgp.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/libopensc/card-openpgp.c | |||||
+++ opensc-20150513/src/libopensc/card-openpgp.c | |||||
@@ -1966,8 +1966,6 @@ static int pgp_update_card_algorithms(sc | |||||
**/ | |||||
static int pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) | |||||
{ | |||||
- struct pgp_priv_data *priv = DRVDATA(card); | |||||
- pgp_blob_t *algo_blob; | |||||
sc_apdu_t apdu; | |||||
/* Temporary variables to hold APDU params */ | |||||
u8 apdu_case; | |||||
@@ -2396,10 +2394,9 @@ static int pgp_erase_card(sc_card_t *car | |||||
{0, 0x44, 0, 0} | |||||
}; | |||||
u8 apdu_lens[10] = {13, 13, 13, 13, 13, 13, 13, 13, 4, 4}; | |||||
- u8 buf[SC_MAX_APDU_BUFFER_SIZE]; | |||||
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; | |||||
sc_apdu_t apdu; | |||||
- int i, l, r; | |||||
+ u8 i, l, r; | |||||
LOG_FUNC_CALLED(ctx); | |||||
@@ -2478,7 +2475,7 @@ gnuk_delete_key(sc_card_t *card, u8 key_ | |||||
{ | |||||
sc_context_t *ctx = card->ctx; | |||||
int r = SC_SUCCESS; | |||||
- u8 *data = NULL; | |||||
+ char *data = NULL; | |||||
LOG_FUNC_CALLED(ctx); | |||||
@@ -2506,7 +2503,7 @@ gnuk_delete_key(sc_card_t *card, u8 key_ | |||||
else if (key_id == 3) | |||||
data = "\x4D\x02\xA4"; | |||||
- r = pgp_put_data(card, 0x4D, data, strlen(data) + 1); | |||||
+ r = pgp_put_data(card, 0x4D, (const u8 *)data, strlen((const char *)data) + 1); | |||||
LOG_FUNC_RETURN(ctx, r); | |||||
} | |||||
@@ -2519,7 +2516,6 @@ pgp_delete_file(sc_card_t *card, const s | |||||
struct pgp_priv_data *priv = DRVDATA(card); | |||||
pgp_blob_t *blob; | |||||
sc_file_t *file; | |||||
- u8 key_id; | |||||
int r; | |||||
LOG_FUNC_CALLED(card->ctx); | |||||
Index: opensc-20150513/src/tools/openpgp-tool.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/tools/openpgp-tool.c | |||||
+++ opensc-20150513/src/tools/openpgp-tool.c | |||||
@@ -473,7 +473,6 @@ int do_verify(sc_card_t *card, char *typ | |||||
**/ | |||||
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 */ | |||||
@@ -520,7 +519,6 @@ int delete_key_openpgp(sc_card_t *card, | |||||
int do_delete_key(sc_card_t *card, u8 key_id) | |||||
{ | |||||
- sc_context_t *ctx = card->ctx; | |||||
sc_path_t path; | |||||
int r = SC_SUCCESS; | |||||
@ -1,28 +0,0 @@ | |||||
From c71a453ff1e19721a9245b8a2d637eabd9f12e54 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: Thu, 11 Dec 2014 12:51:15 +0800 | |||||
Subject: [PATCH 2/2] openpgp-tool: Fix wrong operator | |||||
Used "!=" instead of "|=" | |||||
--- | |||||
src/tools/openpgp-tool.c | 4 ++-- | |||||
1 file changed, 2 insertions(+), 2 deletions(-) | |||||
Index: opensc-20150513/src/tools/openpgp-tool.c | |||||
=================================================================== | |||||
--- opensc-20150513.orig/src/tools/openpgp-tool.c | |||||
+++ opensc-20150513/src/tools/openpgp-tool.c | |||||
@@ -639,10 +639,10 @@ int main(int argc, char **argv) | |||||
} | |||||
if (opt_delkey) | |||||
- exit_status != do_delete_key(card, key_id); | |||||
+ exit_status |= do_delete_key(card, key_id); | |||||
if (opt_erase) | |||||
- exit_status != do_erase(card); | |||||
+ exit_status |= do_erase(card); | |||||
out: | |||||
sc_unlock(card); |
@ -1,14 +1,15 @@ | |||||
#!/bin/sh /etc/rc.common | #!/bin/sh /etc/rc.common | ||||
# Copyright (C) 2009-2011 OpenWrt.org | |||||
START=50 | START=50 | ||||
SERVICE_PID_FILE=/var/run/pcscd/pcscd.pid | |||||
USE_PROCD=1 | |||||
start() { | |||||
service_start /usr/sbin/pcscd | |||||
start_service() { | |||||
procd_open_instance | |||||
procd_set_param command /usr/sbin/pcscd --foreground | |||||
procd_close_instance | |||||
} | } | ||||
stop() { | |||||
service_stop /usr/sbin/pcscd | |||||
reload_service() { | |||||
/usr/sbin/pcscd --hotplug | |||||
} | } |