I added support for both types of D-Trust cards. Please see the patch
attached to this email.

The general behavior for CardOS cards should be unchanged. Only if it
matches the D-Trust cards names, it adds some special flags and
generates the valid signature.

With this patch, the current D-Trust 2048 bit cards work without
problems, no matter which type/revision you got.

Best regards,
Simon


Am Mittwoch, den 05.12.2007, 10:19 +0100 schrieb Simon Eisenmann:
> I could produce a patch which supports both cards properly by doing
> string matching and adding some new flags to card os to disable
> certain
> parts of signature tries in card-cardos.c, but could this be the
> general
> solution? 
> 
> There should be a possibility to detect what type of data has to be
> sent
> to the card. Or if that is not possible, some better way to enable /
> disable code which is required for some card vendors, based on some
> kind
> of configuration file. I do not like to add all kinds of conditions to
> the code based of string compare to some card meta data.
-- 
Simon Eisenmann

[ mailto:[EMAIL PROTECTED] ]

[ struktur AG | Kronenstraße 22a | D-70173 Stuttgart ]
[ T. +49.711.896656.68 | F.+49.711.89665610 ]
[ http://www.struktur.de | mailto:[EMAIL PROTECTED] ]
diff -dur opensc-0.11.4.orig/src/libopensc/card-cardos.c opensc-0.11.4.dtrustall/src/libopensc/card-cardos.c
--- opensc-0.11.4.orig/src/libopensc/card-cardos.c	2007-08-19 21:11:27.000000000 +0200
+++ opensc-0.11.4.dtrustall/src/libopensc/card-cardos.c	2007-12-05 18:37:19.000000000 +0100
@@ -802,14 +802,29 @@
 	 * certain key, let's try RSA_PURE etc. and see which operation
 	 * succeeds (this is not really beautiful, but currently the
 	 * only way I see) -- Nils
+	 *
+	 * We also check for several caps flags here to pervent generating
+	 * invalid signatures with duplicated hash prefixes with some cards
+	 *
 	 */
-	if (ctx->debug >= 3)
-		sc_debug(ctx, "trying RSA_PURE_SIG (padded DigestInfo)\n");
-	sc_ctx_suppress_errors_on(ctx);
-	r = do_compute_signature(card, data, datalen, out, outlen);
-	sc_ctx_suppress_errors_off(ctx);
-	if (r >= SC_SUCCESS)
-		SC_FUNC_RETURN(ctx, 4, r);
+
+    if (ctx->debug >= 3) {	 
+        if (card->caps & SC_CARD_CAP_ONLY_RAW_HASH_STRIPPED)
+            sc_debug(ctx, "Forcing RAW_HASH_STRIPPED\n");        	 
+        if (card->caps & SC_CARD_CAP_ONLY_RAW_HASH)
+            sc_debug(ctx, "Forcing RAW_HASH\n");
+    }
+
+    if (!(card->caps & (SC_CARD_CAP_ONLY_RAW_HASH_STRIPPED | SC_CARD_CAP_ONLY_RAW_HASH))) {
+	    if (ctx->debug >= 3)
+		    sc_debug(ctx, "trying RSA_PURE_SIG (padded DigestInfo)\n");
+	    sc_ctx_suppress_errors_on(ctx);
+	    r = do_compute_signature(card, data, datalen, out, outlen);
+	    sc_ctx_suppress_errors_off(ctx);
+	    if (r >= SC_SUCCESS)
+		    SC_FUNC_RETURN(ctx, 4, r);
+    }		
+		
 	if (ctx->debug >= 3)
 		sc_debug(ctx, "trying RSA_SIG (just the DigestInfo)\n");
 	/* remove padding: first try pkcs1 bt01 padding */
@@ -826,13 +841,26 @@
 		}
 		memcpy(buf, p, tmp_len);
 	}
-	sc_ctx_suppress_errors_on(ctx);
-	r = do_compute_signature(card, buf, tmp_len, out, outlen);
-	sc_ctx_suppress_errors_off(ctx);
-	if (r >= SC_SUCCESS)	
-		SC_FUNC_RETURN(ctx, 4, r);
+
+    if (!(card->caps & (SC_CARD_CAP_ONLY_RAW_HASH_STRIPPED | 
+                SC_CARD_CAP_ONLY_RAW_HASH)) || 
+          card->caps & SC_CARD_CAP_ONLY_RAW_HASH ) {
+        if (ctx->debug >= 3)
+		    sc_debug(ctx, "trying to sign raw hash value with prefix\n");	
+	    sc_ctx_suppress_errors_on(ctx);
+	    r = do_compute_signature(card, buf, tmp_len, out, outlen);
+	    sc_ctx_suppress_errors_off(ctx);
+	    if (r >= SC_SUCCESS)	
+		    SC_FUNC_RETURN(ctx, 4, r);
+    }
+	
+	if (card->caps & SC_CARD_CAP_ONLY_RAW_HASH) {
+	    sc_debug(ctx, "Failed to sign raw hash value with prefix when forcing\n");
+	    SC_FUNC_RETURN(ctx, 4, SC_ERROR_INVALID_ARGUMENTS);
+	}
+	   
 	if (ctx->debug >= 3)
-		sc_debug(ctx, "trying to sign raw hash value\n");
+		sc_debug(ctx, "trying to sign stripped raw hash value (card is responsible for prefix)\n");
 	r = sc_pkcs1_strip_digest_info_prefix(NULL,buf,tmp_len,buf,&buf_len);
 	if (r != SC_SUCCESS)
 		SC_FUNC_RETURN(ctx, 4, r);

diff -dur opensc-0.11.4.orig/src/libopensc/opensc.h opensc-0.11.4.dtrustall/src/libopensc/opensc.h
--- opensc-0.11.4.orig/src/libopensc/opensc.h	2007-08-02 20:52:05.000000000 +0200
+++ opensc-0.11.4.dtrustall/src/libopensc/opensc.h	2007-12-05 17:42:12.000000000 +0100
@@ -446,6 +446,10 @@
 /* The card supports 2048 bit RSA keys */
 #define SC_CARD_CAP_RSA_2048		0x00000020
 
+/* D-TRUST CardOS cards special flags */
+#define SC_CARD_CAP_ONLY_RAW_HASH        0x00000040
+#define SC_CARD_CAP_ONLY_RAW_HASH_STRIPPED      0x00000080
+
 typedef struct sc_card {
 	struct sc_context *ctx;
 	struct sc_reader *reader;

diff -dur opensc-0.11.4.orig/src/libopensc/pkcs15.c opensc-0.11.4.dtrustall/src/libopensc/pkcs15.c
--- opensc-0.11.4.orig/src/libopensc/pkcs15.c	2007-08-08 22:07:31.000000000 +0200
+++ opensc-0.11.4.dtrustall/src/libopensc/pkcs15.c	2007-12-05 19:01:59.000000000 +0100
@@ -681,6 +681,38 @@
 			|| strcmp(p15card->manufacturer_id,"Prime") == 0 ))
 		p15card->flags |= SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT;
 
+    /* set special flags based on card meta data */
+    if (strcmp(p15card->card->driver->short_name,"cardos") == 0) {
+     
+        /* D-Trust cards (D-TRUST, D-SIGN) */
+        if (strstr(p15card->label,"D-TRUST") == 0
+			    || strstr(p15card->label,"D-SIGN") == 0) {
+        
+            /* D-TRUST Card 2.0 2cc (standard cards, which always add 
+             * SHA1 prefix itself */
+            if (strstr(p15card->label, "2cc") != NULL) {
+                p15card->card->caps |= SC_CARD_CAP_ONLY_RAW_HASH_STRIPPED;
+                p15card->flags = p15card->flags &~ SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT;
+                sc_debug(p15card->card->ctx, "D-TRUST 2cc card detected, only SHA1 works with this card\n");
+                /* XXX: add detection when other hash than SHA1 is used with
+                 *      such a card, as this produces invalid signatures.
+                 */
+            }
+
+            /* D-SIGN multicard 2.0 2ca (cards working with all types of hashes 
+             * and no addition of prefix) */
+            else if (strstr(p15card->label, "2ca") != NULL) {
+                p15card->card->caps |= SC_CARD_CAP_ONLY_RAW_HASH;
+                p15card->flags = p15card->flags &~ SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT;
+                sc_debug(p15card->card->ctx, "D-TRUST 2ca card detected\n");
+            }
+            
+            /* XXX: probably there are more D-Trust card in the wild, 
+             *      which also need these flags to produce valid signatures
+             */
+        }
+    }
+
 	ok = 1;
 end:
 	if(buf != NULL)

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to