[pkg-opensc-commit] [opensc] 142/295: myeid: added card capabilities check to ...

Eric Dorland eric at moszumanska.debian.org
Sat Jun 24 21:11:24 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 7598c822eda5f2ab930ba59b9f78f9b814302d9d
Author: Hannu Honkanen <hannu.honkanen at aventra.fi>
Date:   Tue Dec 27 16:33:18 2016 +0200

    myeid: added card capabilities check to ...
    
    ... correctly determine which algorithms and key sizes are supported.
---
 src/libopensc/card-myeid.c | 97 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 81 insertions(+), 16 deletions(-)

diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c
index 3514626..0e75486 100644
--- a/src/libopensc/card-myeid.c
+++ b/src/libopensc/card-myeid.c
@@ -46,9 +46,17 @@
 #define MYEID_STATE_CREATION	0x01
 #define MYEID_STATE_ACTIVATED	0x07
 
-#define MYEID_INFINEON_CHIP_ATR		0x04
 #define MYEID_CARD_NAME_MAX_LEN		100
 
+/* The following flags define the features supported by the card currently in use.
+  They are used in 'card_supported_features' field in myeid_card_caps struct */
+#define MYEID_CARD_CAP_RSA		0x01
+#define MYEID_CARD_CAP_3DES		0x02
+#define MYEID_CARD_CAP_AES		0x04
+#define MYEID_CARD_CAP_ECC		0x08
+#define MYEID_CARD_CAP_GRIDPIN		0x10
+#define MYEID_CARD_CAP_PIV_EMU		0x20
+
 static const char *myeid_card_name = "MyEID";
 static char card_name_buf[MYEID_CARD_NAME_MAX_LEN];
 
@@ -83,6 +91,15 @@ typedef struct myeid_private_data {
 	const struct sc_security_env* sec_env;
 } myeid_private_data_t;
 
+typedef struct myeid_card_caps {
+	unsigned char card_caps_ver;
+	unsigned short card_supported_features;
+	unsigned short max_rsa_key_length;
+	unsigned short max_des_key_length;
+	unsigned short max_aes_key_length;
+	unsigned short max_ecc_key_length;
+} myeid_card_caps_t;
+
 static struct myeid_supported_ec_curves {
 	char *curve_name;
 	struct sc_object_id curve_oid;
@@ -97,6 +114,7 @@ static struct myeid_supported_ec_curves {
 };
 
 static int myeid_get_info(struct sc_card *card, u8 *rbuf, size_t buflen);
+static int myeid_get_card_caps(struct sc_card *card, myeid_card_caps_t* card_caps);
 
 static int myeid_match_card(struct sc_card *card)
 {
@@ -130,10 +148,8 @@ static int myeid_init(struct sc_card *card)
 	u8 appletInfo[20];
 	size_t appletInfoLen;
 	int r;
-	int largeEccKeys = 0;
-	u8 defatr[SC_MAX_ATR_SIZE];
-	size_t len = sizeof(defatr);
-	const char *atrp = myeid_atrs[MYEID_INFINEON_CHIP_ATR];
+	unsigned short max_ecc_key_length = 256;
+	myeid_card_caps_t card_caps;
 
 	LOG_FUNC_CALLED(card->ctx);
 
@@ -165,16 +181,24 @@ static int myeid_init(struct sc_card *card)
 	_sc_card_add_rsa_alg(card, 1024, flags, 0);
 	_sc_card_add_rsa_alg(card, 1536, flags, 0);
 	_sc_card_add_rsa_alg(card, 2048, flags, 0);
-
-	if (sc_hex_to_bin(atrp, defatr, &len) == 0
-		&& (len == card->atr.len) &&
-		memcmp(card->atr.value, defatr, len) == 0) {
-	    largeEccKeys = 1;
+	
+	memset(&card_caps, 0, sizeof(myeid_card_caps_t));
+
+	if (card->version.fw_major >= 40) {
+	    /* Since 4.0, we can query available algorithms and key sizes.
+	     * Since 3.5.0 RSA up to 2048 and ECC up to 256 are always supported, so we check only max ECC key length. */
+	    r = myeid_get_card_caps(card, &card_caps);
+
+	    if (r == SC_SUCCESS) {
+		max_ecc_key_length = card_caps.max_ecc_key_length;
+	    }
+	    else {
+		sc_log(card->ctx, "Failed to get card capabilities. Using default max ECC key length 256.");
+	    }
 	}
 
 	/* show ECC algorithms if the applet version of the inserted card supports them */
-	if ((card->version.fw_major == 3 && card->version.fw_minor > 5) ||
-			card->version.fw_major >= 4)   {
+	if (card->version.fw_major >= 35) {
 		int i;
 
 		flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN;
@@ -182,10 +206,12 @@ static int myeid_init(struct sc_card *card)
 		ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES;
 
 		for (i=0; ec_curves[i].curve_name != NULL; i++) {
-		    if (i >= 2 && !largeEccKeys)
-			continue;
-		    else
-			_sc_card_add_ec_alg(card,  ec_curves[i].size, flags, ext_flags, &ec_curves[i].curve_oid);
+			if (i == 2 && max_ecc_key_length < 384)
+				continue;
+			else if (i == 3 && max_ecc_key_length < 521)
+				continue;
+			else
+				_sc_card_add_ec_alg(card,  ec_curves[i].size, flags, ext_flags, &ec_curves[i].curve_oid);
 		}
 	}
 
@@ -1387,6 +1413,45 @@ static int myeid_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
 	LOG_FUNC_RETURN(card->ctx, r);
 }
 
+/*
+ Get information of features that the card supports. MyEID 4.x cards are available on different
+ hardware and maximum key sizes cannot be determined simply from the version number anymore.
+ */
+static int myeid_get_card_caps(struct sc_card *card, myeid_card_caps_t* card_caps)
+{
+	sc_apdu_t apdu;
+	int r;
+	unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE];
+
+	LOG_FUNC_CALLED(card->ctx);
+
+	sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0xAA);
+	apdu.resp    = rbuf;
+	apdu.resplen = sizeof(myeid_card_caps_t);
+	apdu.le      = sizeof(myeid_card_caps_t);
+
+	r = sc_transmit_apdu(card, &apdu);
+	LOG_TEST_RET(card->ctx, r,  "APDU transmit failed");
+
+	if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00)
+		return SC_ERROR_INTERNAL;
+
+	if (apdu.resplen < 11) {
+		sc_log(card->ctx, "Unexpected response to GET DATA (MyEIC card capabilities)");
+		return SC_ERROR_INTERNAL;
+	}
+
+	card_caps->card_caps_ver = rbuf[0];
+	/* the card returns big endian values */
+	card_caps->card_supported_features = (unsigned short) rbuf[1] << 8 | rbuf[2];
+	card_caps->max_rsa_key_length = (unsigned short) rbuf[3] << 8 | rbuf[4];
+	card_caps->max_des_key_length = (unsigned short) rbuf[5] << 8 | rbuf[6];
+	card_caps->max_aes_key_length = (unsigned short) rbuf[7] << 8 | rbuf[8];
+	card_caps->max_ecc_key_length = (unsigned short) rbuf[9] << 8 | rbuf[10];
+
+	LOG_FUNC_RETURN(card->ctx, r);
+}
+
 static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
 {
 	int r = SC_ERROR_NOT_SUPPORTED;

-- 
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