I have submitted ticket #179 with an attached patch
to pkcs15-gemsafeV1.c after discussing the issue with
the module's author, David Mattes. I would hope that
this patch could be applied soon so it will be in 0.11.5.


The pkcs15-gemsafeV1.c code assumes that the key_ref
is always 3. But that is not always the case. In our case
it is 4. The patch tries to determine the key_ref by
looking at what appears to be a table of allocated keys,
and picking the first allocated key.

In case this is not always true, the patch will also
allow for the the opensc.conf card flag = n to specify
the key_ref as the low order 4 bits of the flag.

The attached patch is against the SVN.
--

 Douglas E. Engert  <[EMAIL PROTECTED]>
 Argonne National Laboratory
 9700 South Cass Avenue
 Argonne, Illinois  60439
 (630) 252-5444
Index: pkcs15-gemsafeV1.c
===================================================================
--- pkcs15-gemsafeV1.c	(revision 3447)
+++ pkcs15-gemsafeV1.c	(working copy)
@@ -114,10 +114,12 @@
 	{ NULL, NULL, 0, 0, NULL, 0, NULL, 0}
 };
 
-static int gemsafe_get_cert_len(sc_card_t *card, sc_path_t *path)
+static int gemsafe_get_cert_len(sc_card_t *card, sc_path_t *path, 
+	int *key_ref)
 {
 	const char *fn_name = "gemsafe_get_cert_len";
 	int r;
+	int ind;
 	u8  ibuf[248];
 	struct sc_file *file;
 	size_t objlen, certlen;
@@ -146,6 +148,26 @@
 	    return 0;
 	}
 
+	/*
+	 * We need to find the private key associated with the cert
+	 * It looks like the first thing in the block is a table of
+	 * which keys are allocated. 
+	 * We will look for the first allocated key, and save the 
+	 * key_ref. The table is small and is in the first 248 bytes.
+	 * If for some reason this is not true, we can still override
+	 * the key_ref in the opensc.conf with flag = n.
+	 */
+	ind = 2; /* skip length */
+	while (ibuf[ind] == 0x01) {
+		if (ibuf[ind+1] == 0xFE) {
+			*key_ref = ibuf[ind+4];
+			sc_debug(card->ctx, "Using key_ref %d found at offset %d\n",
+					*key_ref, ind);
+			break;
+		}
+		ind = ind + 8;
+	}
+
 	/* Using (block+1) in while loop avoids using final cert object data block */
 	while (!found && ( (block+1) * 248 < objlen) ) {
 	    /* Check current buffer */
@@ -193,6 +215,7 @@
     const char *fn_name = "sc_pkcs15emu_gemsafe_init";
 
     int    r, i;
+	int	   key_ref = 0x03; 
     struct sc_path path;
     struct sc_file *file = NULL;
     struct sc_card *card = p15card->card;
@@ -252,7 +275,7 @@
 	    struct sc_pkcs15_id  p15Id;
 
 	    sc_format_path(gemsafe_cert[i].path, &path);
-	    if (!gemsafe_get_cert_len(card, &path))
+	    if (!gemsafe_get_cert_len(card, &path, &key_ref))
 		    /* skip errors */
 		    continue;
 	    sc_pkcs15_format_id(gemsafe_cert[i].id, &p15Id);
@@ -284,10 +307,20 @@
 		    pauthId = &authId;
 	    } else
 		    pauthId = NULL;
+			/*
+			 * the key ref may be different for different sites 
+			 * by adding flags=n where the low order 4 bits can be
+			 * the key ref we can force it. 
+			 */
+			if ( p15card->card->flags & 0x0F) {
+				key_ref = p15card->card->flags & 0x0F;
+				sc_debug(p15card->card->ctx,
+					"Overriding key_ref  with %d\n", key_ref);
+			} 
 	    sc_pkcs15emu_add_prkey(p15card, &p15Id, gemsafe_prkeys[i].label,
 			    SC_PKCS15_TYPE_PRKEY_RSA,
 			    gemsafe_prkeys[i].modulus_len, gemsafe_prkeys[i].usage,
-			    &path, gemsafe_prkeys[i].ref, pauthId,
+			    &path, key_ref, pauthId,
 			    gemsafe_prkeys[i].obj_flags);
     }
 
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to