[pkg-opensc-commit] [opensc] 224/295: Avoid dnie_transmit_apdu in the dnie driver (#970) (#1013)

Eric Dorland eric at moszumanska.debian.org
Sat Jun 24 21:11:34 UTC 2017


This is an automated email from the git hooks/post-receive script.

eric pushed a commit to branch master
in repository opensc.

commit d757db2ca8251ef06e58b2ed443cb7f937f7c816
Author: Frank Morgner <frankmorgner at gmail.com>
Date:   Mon Apr 3 18:00:41 2017 +0200

    Avoid dnie_transmit_apdu in the dnie driver (#970) (#1013)
    
    closes #975
    closes #972
---
 src/libopensc/apdu.c      |  5 +++--
 src/libopensc/card-dnie.c | 23 +++++++++++++----------
 src/libopensc/cwa-dnie.c  | 18 ------------------
 src/libopensc/cwa-dnie.h  |  4 +---
 src/libopensc/cwa14890.c  |  8 ++++----
 src/libopensc/sm.c        |  5 +++--
 src/libopensc/types.h     |  2 ++
 7 files changed, 26 insertions(+), 39 deletions(-)

diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c
index 777b951..3a46825 100644
--- a/src/libopensc/apdu.c
+++ b/src/libopensc/apdu.c
@@ -377,7 +377,8 @@ sc_single_transmit(struct sc_card *card, struct sc_apdu *apdu)
 	       apdu->cla, apdu->ins, apdu->p1, apdu->p2, apdu->datalen,
 	       apdu->data);
 #ifdef ENABLE_SM
-	if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT) {
+	if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT
+		   	&& (apdu->flags & SC_APDU_FLAGS_NO_SM) == 0) {
 		LOG_FUNC_RETURN(ctx, sc_sm_single_transmit(card, apdu));
 	}
 #endif
@@ -404,7 +405,7 @@ sc_set_le_and_transmit(struct sc_card *card, struct sc_apdu *apdu, size_t olen)
 		LOG_TEST_RET(ctx, SC_ERROR_WRONG_LENGTH, "wrong length: required length exceeds resplen");
 
 	/* don't try again if it doesn't work this time */
-	apdu->flags  |= SC_APDU_FLAGS_NO_GET_RESP;
+	apdu->flags  |= SC_APDU_FLAGS_NO_RETRY_WL;
 	/* set the new expected length */
 	apdu->resplen = olen;
 	apdu->le      = nlen;
diff --git a/src/libopensc/card-dnie.c b/src/libopensc/card-dnie.c
index 76e9010..c4f1641 100644
--- a/src/libopensc/card-dnie.c
+++ b/src/libopensc/card-dnie.c
@@ -656,7 +656,7 @@ static int dnie_get_serialnr(sc_card_t * card, sc_serial_number_t * serial)
 					rbuf, sizeof(rbuf), NULL, 0);
 	apdu.cla = 0x90;	/* propietary cmd */
 	/* send apdu */
-	result = dnie_transmit_apdu(card, &apdu);
+	result = sc_transmit_apdu(card, &apdu);
 	if (result != SC_SUCCESS) {
 		dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
 		LOG_TEST_RET(card->ctx, result, "APDU transmit failed");
@@ -750,9 +750,11 @@ static int dnie_sm_free_wrapped_apdu(struct sc_card *card,
 		struct sc_apdu *plain, struct sc_apdu **sm_apdu)
 {
 	struct sc_context *ctx = card->ctx;
+	cwa_provider_t *provider = NULL;
 	int rv = SC_SUCCESS;
 
 	LOG_FUNC_CALLED(ctx);
+	provider = GET_DNIE_PRIV_DATA(card)->cwa_provider;
 	if (!sm_apdu)
 		LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
 	if (!(*sm_apdu))
@@ -769,6 +771,7 @@ static int dnie_sm_free_wrapped_apdu(struct sc_card *card,
 		}
 
 		free(*sm_apdu);
+		rv = cwa_decode_response(card, provider, plain);
 	}
 	*sm_apdu = NULL;
 
@@ -1029,7 +1032,7 @@ static int dnie_fill_cache(sc_card_t * card)
 		apdu.resplen = MAX_RESP_BUFFER_SIZE;
 		apdu.resp = tmp;
 		/* transmit apdu */
-		r = dnie_transmit_apdu(card, &apdu);
+		r = sc_transmit_apdu(card, &apdu);
 		if (r != SC_SUCCESS) {
 			free(buffer);
 			if (apdu.resp != tmp)
@@ -1174,7 +1177,7 @@ static int dnie_compose_and_send_apdu(sc_card_t *card, const u8 *path, size_t pa
 	if (file_out == NULL)
 		apdu.cse = SC_APDU_CASE_4_SHORT;
 
-	res = dnie_transmit_apdu(card, &apdu);
+	res = sc_transmit_apdu(card, &apdu);
 	if ((res != SC_SUCCESS) || (file_out == NULL))
 		dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
 	LOG_TEST_RET(ctx, res, "SelectFile() APDU transmit failed");
@@ -1379,7 +1382,7 @@ static int dnie_get_challenge(struct sc_card *card, u8 * rnd, size_t len)
 		apdu.le = BUFFER_SIZE;
 		apdu.resp = buf;
 		apdu.resplen = MAX_RESP_BUFFER_SIZE;	/* include SW's */
-		result = dnie_transmit_apdu(card, &apdu);
+		result = sc_transmit_apdu(card, &apdu);
 		if (result != SC_SUCCESS) {
 			dnie_free_apdu_buffers(&apdu, buf, MAX_RESP_BUFFER_SIZE);
 			LOG_TEST_RET(card->ctx, result, "APDU transmit failed");
@@ -1547,7 +1550,7 @@ static int dnie_set_security_env(struct sc_card *card,
 	 * store sec env apdu (00 22 F2 se_num) command will not be issued */
 
 	/* send composed apdu and parse result */
-	result = dnie_transmit_apdu(card, &apdu);
+	result = sc_transmit_apdu(card, &apdu);
 	dnie_free_apdu_buffers(&apdu, rbuf, MAX_RESP_BUFFER_SIZE);
 	LOG_TEST_RET(card->ctx, result, "Set Security Environment failed");
 	result = sc_check_sw(card, apdu.sw1, apdu.sw2);
@@ -1612,7 +1615,7 @@ static int dnie_decipher(struct sc_card *card,
 	sbuf[0] = 0;		/* padding indicator byte, 0x00 = No further indication */
 	memcpy(sbuf + 1, crgram, crgram_len);
 	/* send apdu */
-	result = dnie_transmit_apdu(card, &apdu);
+	result = sc_transmit_apdu(card, &apdu);
 	LOG_TEST_RET(card->ctx, result, "APDU transmit failed");
 	/* check response */
 	result = sc_check_sw(card, apdu.sw1, apdu.sw2);
@@ -1696,7 +1699,7 @@ static int dnie_compute_signature(struct sc_card *card,
 	dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A, 256, datalen,
 					rbuf, sizeof(rbuf), data, datalen);
 	/* tell card to compute signature */
-	result = dnie_transmit_apdu(card, &apdu);
+	result = sc_transmit_apdu(card, &apdu);
 	if (result != SC_SUCCESS) {
 		dnie_free_apdu_buffers(&apdu, rbuf, sizeof(rbuf));
 		LOG_TEST_RET(card->ctx, result, "compute_signature() failed");
@@ -1771,7 +1774,7 @@ static int dnie_list_files(sc_card_t * card, u8 * buf, size_t buflen)
 			/* compose and transmit select_file() cmd */
 			data[0] = (u8) (0xff & id1);
 			data[1] = (u8) (0xff & id2);
-			res = dnie_transmit_apdu(card, &apdu);
+			res = sc_transmit_apdu(card, &apdu);
 			dnie_free_apdu_buffers(&apdu, NULL, 0);
 			if (res != SC_SUCCESS) {
 				sc_log(card->ctx, "List file '%02X%02X' failed",
@@ -1923,7 +1926,7 @@ static int dnie_read_header(struct sc_card *card)
 	dnie_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, 0x00, 0x00, 8, 0,
 					buf, MAX_RESP_BUFFER_SIZE, NULL, 0);
 	/* transmit apdu */
-	r = dnie_transmit_apdu(card, &apdu);
+	r = sc_transmit_apdu(card, &apdu);
 	if (r != SC_SUCCESS) {
 		dnie_free_apdu_buffers(&apdu, buf, SC_MAX_APDU_BUFFER_SIZE);
 		sc_log(ctx, "read_header() APDU transmit failed");
@@ -2201,7 +2204,7 @@ static int dnie_pin_verify(struct sc_card *card,
 					resp, MAX_RESP_BUFFER_SIZE, pinbuffer, pinlen);
 
 	/* and send to card throught virtual channel */
-	res = dnie_transmit_apdu(card, &apdu);
+	res = sc_transmit_apdu(card, &apdu);
 	if (res != SC_SUCCESS) {
 		dnie_free_apdu_buffers(&apdu, resp, MAX_RESP_BUFFER_SIZE);
 		LOG_TEST_RET(card->ctx, res, "VERIFY APDU Transmit fail");
diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c
index 3901905..7e54e4a 100644
--- a/src/libopensc/cwa-dnie.c
+++ b/src/libopensc/cwa-dnie.c
@@ -895,24 +895,6 @@ void dnie_change_cwa_provider_to_pin(sc_card_t * card)
 	res->cwa_get_sn_ifd = dnie_get_sn_ifd_pin;
 }
 
-int dnie_transmit_apdu(sc_card_t * card, sc_apdu_t * apdu)
-{
-	int res = SC_SUCCESS;
-	sc_context_t *ctx;
-	cwa_provider_t *provider = NULL;
-	ctx=card->ctx;
-	provider = GET_DNIE_PRIV_DATA(card)->cwa_provider;
-	if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT) {
-		res = sc_transmit_apdu(card, apdu);
-		LOG_TEST_RET(ctx, res, "Error in dnie_wrap_apdu process");
-		res = cwa_decode_response(card, provider, apdu);
-		LOG_TEST_RET(ctx, res, "Error in cwa_decode_response process");
-	}
-	else
-		res = sc_transmit_apdu(card, apdu);
-	return res;
-}
-
 void dnie_format_apdu(sc_card_t *card, sc_apdu_t *apdu,
 			int cse, int ins, int p1, int p2, int le, int lc,
 			unsigned char * resp, size_t resplen,
diff --git a/src/libopensc/cwa-dnie.h b/src/libopensc/cwa-dnie.h
index 74ebe7e..0fd5ed8 100644
--- a/src/libopensc/cwa-dnie.h
+++ b/src/libopensc/cwa-dnie.h
@@ -1,5 +1,5 @@
 /**
- * cwa-dnie.h: Defines dnie_transmit_apdu wrapper for sc_transmit_apdu
+ * cwa-dnie.h: CWA specifics for DNIe
  *
  * This work is derived from many sources at OpenSC Project site,
  * (see references), and the information made public for Spanish 
@@ -70,8 +70,6 @@ void dnie_change_cwa_provider_to_pin(sc_card_t * card);
 
 void dnie_change_cwa_provider_to_secure(sc_card_t * card);
 
-int dnie_transmit_apdu(sc_card_t * card, sc_apdu_t * apdu);
-
 void dnie_format_apdu(sc_card_t *card, sc_apdu_t *apdu,
                        int cse, int ins, int p1, int p2, int le, int lc,
                        unsigned char * resp, size_t resplen,
diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c
index 1a6e17d..4352fdc 100644
--- a/src/libopensc/cwa14890.c
+++ b/src/libopensc/cwa14890.c
@@ -450,7 +450,7 @@ static int cwa_verify_cvc_certificate(sc_card_t * card,
 					resp, MAX_RESP_BUFFER_SIZE, cert, len);
 
 	/* send composed apdu and parse result */
-	result = dnie_transmit_apdu(card, &apdu);
+	result = sc_transmit_apdu(card, &apdu);
 	LOG_TEST_RET(ctx, result, "Verify CVC certificate failed");
 	result = sc_check_sw(card, apdu.sw1, apdu.sw2);
 	LOG_FUNC_RETURN(ctx, result);
@@ -491,7 +491,7 @@ static int cwa_set_security_env(sc_card_t * card,
 					resp, MAX_RESP_BUFFER_SIZE, buffer, length);
 
 	/* send composed apdu and parse result */
-	result = dnie_transmit_apdu(card, &apdu);
+	result = sc_transmit_apdu(card, &apdu);
 	LOG_TEST_RET(ctx, result, "SM Set Security Environment failed");
 	result = sc_check_sw(card, apdu.sw1, apdu.sw2);
 	LOG_FUNC_RETURN(ctx, result);
@@ -529,7 +529,7 @@ static int cwa_internal_auth(sc_card_t * card, u8 * sig, size_t sig_len, u8 * da
 					rbuf, sizeof(rbuf), data, datalen);
 
 	/* send composed apdu and parse result */
-	result = dnie_transmit_apdu(card, &apdu);
+	result = sc_transmit_apdu(card, &apdu);
 	LOG_TEST_RET(ctx, result, "SM internal auth failed");
 
 	result = sc_check_sw(card, apdu.sw1, apdu.sw2);
@@ -739,7 +739,7 @@ static int cwa_external_auth(sc_card_t * card, u8 * sig, size_t sig_len)
 					resp, MAX_RESP_BUFFER_SIZE, sig, sig_len);
 
 	/* send composed apdu and parse result */
-	result = dnie_transmit_apdu(card, &apdu);
+	result = sc_transmit_apdu(card, &apdu);
 	LOG_TEST_RET(ctx, result, "SM external auth failed");
 	result = sc_check_sw(card, apdu.sw1, apdu.sw2);
 	LOG_TEST_RET(ctx, result, "SM external auth invalid response");
diff --git a/src/libopensc/sm.c b/src/libopensc/sm.c
index 44cdfa4..a5f53de 100644
--- a/src/libopensc/sm.c
+++ b/src/libopensc/sm.c
@@ -156,8 +156,9 @@ sc_sm_single_transmit(struct sc_card *card, struct sc_apdu *apdu)
 		LOG_TEST_RET(ctx, rv, "cannot validate SM encoded APDU");
 	}
 
-	/* send APDU to the reader driver */
-	rv = card->reader->ops->transmit(card->reader, sm_apdu);
+	/* send APDU flagged as NO_SM */
+	sm_apdu->flags |= SC_APDU_FLAGS_NO_SM;
+	rv = sc_transmit_apdu(card, sm_apdu);
 	if (rv < 0) {
 		card->sm_ctx.ops.free_sm_apdu(card, apdu, &sm_apdu);
 		sc_sm_stop(card);
diff --git a/src/libopensc/types.h b/src/libopensc/types.h
index a5f9250..7368422 100644
--- a/src/libopensc/types.h
+++ b/src/libopensc/types.h
@@ -279,6 +279,8 @@ typedef struct sc_file {
  * returns 0x6Cxx (wrong length)
  */
 #define SC_APDU_FLAGS_NO_RETRY_WL	0x00000004UL
+/* APDU is from Secure Messaging  */
+#define SC_APDU_FLAGS_NO_SM		0x00000008UL
 
 #define SC_APDU_ALLOCATE_FLAG		0x01
 #define SC_APDU_ALLOCATE_FLAG_DATA	0x02

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-opensc/opensc.git



More information about the pkg-opensc-commit mailing list