OK, I have applied Thomas's patch to the svn revision 3121
checkout a few hours ago with these changes:

   I have added #ifdef HAVE_ZLIB_H so it should compile
   without zlib. If a compressed certificate is found, it
   will call sc_error and return SC_ERROR_NOT_SUPPORTED
   But all my Unix systems have zlib, will try it on Windows too.

   I added some code to piv-tool.c so it could write out
   a compressed certificate created by gzip.

   Change the card-piv.c to write the cert object with
   the "CertInfo" with compressed flag.

Have compiled and tested on Ubuntu, with writing a compressed
certificate and the code can read both compressed and
uncompressed certificates.


See the attachment. svn diff output patch.


I can change the names if you want or any other changes too.



Andreas Jellinghaus wrote:
what would be better? release -pre4 as 0.11.2 and create 0.11.3-pre1 with that patch? or do a -pre5 with it?

Nils already gave a comment on the code a long time ago, should
be on the ML archive. I rely on Nils for comments, as he knows the
code much better than I do. but I'm currently quite busy and have
little time for opensc, and since Nils hasn't responded to the thread so
far I guess he is busy too. so if anyone can step in and work on the
code to address these issues, that would be great.

for example compiling without zlib support would be a good thing.
(most windows users might want to try without I guess.)

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



--

 Douglas E. Engert  <[EMAIL PROTECTED]>
 Argonne National Laboratory
 9700 South Cass Avenue
 Argonne, Illinois  60439
 (630) 252-5444
Index: src/tools/piv-tool.c
===================================================================
--- src/tools/piv-tool.c	(revision 3121)
+++ src/tools/piv-tool.c	(working copy)
@@ -41,7 +41,7 @@
 #include <openssl/pem.h>
 #include <openssl/err.h>
 
-const char *app_name = "opensc-tool";
+const char *app_name = "piv-tool";
 
 static int	opt_reader = -1,
 		opt_wait = 0;
@@ -60,6 +60,7 @@
 	{ "usepin",		0, 0,		'P' }, /* some beta cards want user pin for put_data */
 	{ "genkey",		0, 0,		'G' },
 	{ "cert",		0, 0,		'C' },
+	{ "compresscert", 0, 0,		'Z' },
 	{ "req",		0, 0, 		'R' },
 	{ "out",	0, 0, 		'o' },
 	{ "in",		0, 0, 		'o' },
@@ -77,7 +78,8 @@
 	"authenticate using default 3des key",
 	"authenticate using user pin", 
 	"Generate key <ref>:<alg> 9A:06 on card, and output pubkey",
-	"Load the AUTH cert onto card from file <arg>",
+	"Load a cert <ref> where <ref> is 9A,9B,9C or 9D",
+	"Load a cert that has been gziped <ref>",
 	"Generate a cert req",
 	"Output file for cert or key or req",
 	"Inout file for cert",
@@ -94,7 +96,8 @@
 RSA * newkey = NULL;
 
 
-static int load_cert(const char * cert_id, const char * cert_file)
+static int load_cert(const char * cert_id, const char * cert_file,
+					int compress)
 {
 	X509 * cert = NULL;
 	FILE *fp;
@@ -106,25 +109,39 @@
 	size_t derlen;
 	int r;
 
-
     if((fp=fopen(cert_file, "r"))==NULL){
         printf("Cannot open cert file, %s %s\n", 
 			cert_file, strerror(errno));
         return -1;
     }
-	cert = PEM_read_X509(fp, &cert, NULL, NULL);
-    fclose(fp);
-    if(cert == NULL){
-        printf("file %s does not conatin PEM-encoded certificate\n",
-			 cert_file);
-        return-1 ;
-    }
+	if (compress) { /* file is gziped already */
+		struct stat stat_buf;
 
-	derlen = i2d_X509(cert, NULL);
-	der = (u8 *) malloc(derlen);
-	p = der;
-	i2d_X509(cert, &p);
+		stat(cert_file, &stat_buf);
+		derlen = stat_buf.st_size;
+		der = malloc(derlen);
+		if (der == NULL) {
+			printf("file %s is too big, %d\n", cert_file, derlen);
+			return-1 ;
+		}
+		if (1 != fread(der, derlen, 1, fp)) {
+			printf("unable to read file %s\n",cert_file);
+			return -1;
+		}
+	} else {
+		cert = PEM_read_X509(fp, &cert, NULL, NULL);
+    	if(cert == NULL){
+        	printf("file %s does not conatin PEM-encoded certificate\n",
+				 cert_file);
+        	return -1 ;
+    	}
 
+		derlen = i2d_X509(cert, NULL);
+		der = (u8 *) malloc(derlen);
+		p = der;
+		i2d_X509(cert, &p);
+	}
+    fclose(fp);
 	sc_hex_to_bin(cert_id, buf,&buflen);
 	
 	switch (buf[0]) {
@@ -142,7 +159,8 @@
 		fprintf(stderr, "select file failed\n");
 		 return -1;
 	}
-	r = sc_write_binary(card, 0, der, derlen, 0); 
+	/* we pass compress as the flag to card-piv.c write_binary */
+	r = sc_write_binary(card, 0, der, derlen, compress); 
 	
 	return r;
 
@@ -340,6 +358,7 @@
 	int do_admin_mode = 0;
 	int do_gen_key = 0;
 	int do_load_cert = 0;
+	int compress_cert = 0;
 	int do_req = 0;
 	int do_print_serial = 0;
 	int do_print_name = 0;
@@ -355,7 +374,7 @@
 	setbuf(stdout, NULL);
 
 	while (1) {
-		c = getopt_long(argc, argv, "nA:G:C:Ri:o:fvs:c:w", options, &long_optind);
+		c = getopt_long(argc, argv, "nA:G:Z:C:Ri:o:fvs:c:w", options, &long_optind);
 		if (c == -1)
 			break;
 		if (c == '?')
@@ -384,6 +403,8 @@
 			key_info = optarg;
 			action_count++;
 			break;
+		case 'Z':
+			compress_cert = 1;
 		case 'C':
 			do_load_cert = 1;
 			cert_id = optarg;
@@ -469,7 +490,7 @@
 		action_count--;
 	}
 	if (do_load_cert) {
-		if ((err = load_cert(cert_id, in_file)))
+		if ((err = load_cert(cert_id, in_file, compress_cert)))
 			goto end;
 		action_count--;
 	}
Index: src/libopensc/card-piv.c
===================================================================
--- src/libopensc/card-piv.c	(revision 3121)
+++ src/libopensc/card-piv.c	(working copy)
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2001, 2002  Juha Yrjölä <[EMAIL PROTECTED]>
  * Copyright (C) 2005, Douglas E. Engert <[EMAIL PROTECTED]>
+ * Copyright (C) 2006, Identity Alliance, Thomas Harning <[EMAIL PROTECTED]>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -29,8 +30,17 @@
 #include <openssl/rsa.h>
 #include "asn1.h"
 #include "cardctl.h"
+#ifdef HAVE_ZLIB_H
+#include "compression.h"
+#endif
 
-struct piv_private_data {
+typedef struct {
+	u8* data;
+	size_t length;
+	int enumtag;
+} piv_cache_item;
+
+typedef struct piv_private_data {
 	struct sc_pin_cmd_pin pin_info;
 	sc_file_t *aid_file;
 	int enumtag;
@@ -39,9 +49,54 @@
 	size_t max_recv_size; /* saved size, need to lie to pkcs15_read_file */
 	size_t max_send_size; 
 	int key_ref; /* saved from set_security_env and */
-	int alg_id;  /* used in decrypy, signature */ 
-};
+	int alg_id;  /* used in decrypt, signature */ 
+	piv_cache_item* cache;
+	int cacheLen;
+	piv_cache_item* current_item;
+} piv_private_data_t;
 
+#define PIV_DATA(card) ((piv_private_data_t*)card->drv_data)
+
+static int add_cache_item(piv_private_data_t* priv, int enumtag, u8* data, size_t length) {
+	int idx, len = priv->cacheLen;
+	piv_cache_item* cache = priv->cache;
+	for(idx = 0; idx < len; idx++) {
+		if(!cache[idx].data)
+			break;
+		if(cache[idx].enumtag == enumtag) /* Found matching tag */
+			break;
+	}
+	if(idx == len) 
+		return -1; /* FAILED NO FREE ROOM */
+	if(cache[idx].data)
+		free(cache[idx].data);
+	cache[idx].data = data;
+	cache[idx].length = length;
+	cache[idx].enumtag = enumtag;
+	return 0;
+}
+
+static piv_cache_item* get_cache_item(piv_private_data_t* priv, int enumtag) {
+	int idx, len = priv->cacheLen;
+	piv_cache_item* cache = priv->cache;
+	for(idx = 0; idx < len; idx++) {
+		if(cache[idx].enumtag == enumtag)
+			return &cache[idx];
+	}
+	return NULL;
+}
+
+static void free_cache_items(piv_private_data_t* priv) {
+	int idx, len = priv->cacheLen;
+	piv_cache_item* cache = priv->cache;
+	for(idx = 0; idx < len; idx++) {
+		if(cache[idx].data) {
+			free(cache[idx].data);
+			cache[idx].data = NULL;
+		}
+	}
+}
+
 struct piv_aid {
 	int enumtag;
 	size_t len_short;	/* min lenght without version */
@@ -71,7 +126,8 @@
 	PIV_OBJ_X509_CARD_AUTH,
 	PIV_OBJ_SEC_OBJ,
 	PIV_OBJ_9B03,
-	PIV_OBJ_9A06
+	PIV_OBJ_9A06,
+	PIV_CACHE_SIZE
 };
 
 struct piv_object {
@@ -88,14 +144,12 @@
 	{ PIV_OBJ_CCC, "Card Capability Container", 
 			"2.16.840.1.101.3.7.1.219.0", 3, "\x5F\xC1\x07", "\xDB\x00", 266},
 	{ PIV_OBJ_CHUI, "Card Holder Unique Identifier", 
-			"2.16.840.1.101.3.7.2.48.0", 3, "\x5F\xC1\x02", "\x30\x00", 3377},
+			"2.16.840.1.101.3.7.2.48.0", 3, "\x5F\xC1\x02", "\x30\x00", 3379}, /* Updated per SP800-73-1 Errata */
 	{ PIV_OBJ_X509_PIV_AUTH, "X.509 Certificate for PIV Authentication", 
 			"2.16.840.1.101.3.7.2.1.1", 3, "\x5F\xC1\x05", "\x01\x01", 1856+4+400} , 
 		/* extra 400 is hack for MultOS card which returns 2200 bytes  */
-	{ PIV_OBJ_CHF1, "Card Holder Fingerprint I",
-			"2.16.840.1.101.3.7.2.96.16", 3, "\x5F\xC1\x03", "\x60\x01", 7768},
-	{ PIV_OBJ_CHF2, "Card Holder Fingerprint II",
-			"2.16.840.1.101.3.7.2.96.17", 3, "\x5F\xC1\x04", "\x60\x11", 7768},
+	{ PIV_OBJ_CHF1, "Card Holder Fingerprints",
+			"2.16.840.1.101.3.7.2.96.16", 3, "\x5F\xC1\x03", "\x60\x10", 7768},
 	{ PIV_OBJ_PI, "Printed Information", 
 			"2.16.840.1.101.3.7.2.48.1", 3, "\x5F\xC1\x09", "\x30\x01", 106},
 	{ PIV_OBJ_CHFI, "Card Holder Facial Image",
@@ -184,7 +238,7 @@
 	const u8 * sendbuf, size_t sendbuflen, u8 ** recvbuf,
 	size_t * recvbuflen)
 {
-	struct piv_private_data * priv = (struct piv_private_data *) card->drv_data;
+	piv_private_data_t * priv = PIV_DATA(card);
 	int r;
 	sc_apdu_t apdu;
 	u8 rbufinitbuf[20000]; /* crude way to do this  see above comments */
@@ -502,12 +556,12 @@
 static int piv_get_data(sc_card_t * card, unsigned int enumtag, 
 			u8 **buf, size_t *buf_len)
 {
-	struct piv_private_data * priv = (struct piv_private_data *) card->drv_data;
+	piv_private_data_t * priv = PIV_DATA(card);
 	u8 *p;
 	int r = 0;
 	u8 tagbuf[8];
 	size_t tag_len;
-		
+	
 	SC_FUNC_CALLED(card->ctx,1);
 	sc_debug(card->ctx, "get_data: tag=%d \n", enumtag);
 
@@ -599,7 +653,98 @@
 
 	SC_FUNC_RETURN(card->ctx, 1, r);
 }
-	  
+
+
+static int piv_handle_certificate_data(sc_card_t *card,
+		int enumtag,
+		unsigned idx, u8* buf, size_t count,
+		u8* data, size_t length) {
+	piv_private_data_t * priv = PIV_DATA(card);
+	u8* tag;
+	size_t taglen;
+	int compressed = 0;
+	piv_cache_item* item;
+	/* get the certificate out */
+	tag = (u8 *) sc_asn1_find_tag(card->ctx, data, length, 0x71, &taglen);
+	if (tag && (((*tag) & 0x80) || ((*tag) & 0x01))) {
+		compressed = 1;
+	}
+	tag = (u8 *) sc_asn1_find_tag(card->ctx, data,  length, 0x70, &taglen);
+	if (tag == NULL) {
+		return SC_ERROR_OBJECT_NOT_VALID;
+	}
+	/* Potential truncation */
+	if(compressed) {
+#ifdef HAVE_ZLIB_H
+		size_t len = count;
+		u8* newBuf = NULL;
+		if(SC_SUCCESS != do_decompress_alloc(&newBuf, &len, tag, taglen, COMPRESSION_AUTO)) {
+			return SC_ERROR_OBJECT_NOT_VALID;
+		} else {
+			if(len < count + idx)
+				count = len - idx;
+			if(count <= 0)
+				return 0;
+			memcpy(buf, newBuf + idx, count);
+			if(0 != add_cache_item(priv, enumtag, newBuf, len)) {
+				/* Failed to cache item */
+				free(newBuf);
+			}
+		}
+		return count;
+#else
+		sc_error(card->ctx,"PIV compression not supported, no zlib");
+		return SC_ERROR_NOT_SUPPORTED;
+#endif
+	}
+	if(taglen < count + idx)
+		count = taglen - idx;
+	if(count <= 0)
+		return 0;
+	memcpy(buf, tag, count);
+	if(0 == add_cache_item(priv, enumtag, NULL, 0)) {
+		/* Space available in the cache array, use it */
+		item = get_cache_item(priv, enumtag);
+		if(item) {
+			item->data = malloc(taglen);
+			if(item->data) {
+				item->length = taglen;
+				memcpy(item->data, tag, taglen);
+			}
+		}
+	}
+	return count;
+}
+
+static int piv_handle_data(sc_card_t *card, int enumtag, 
+		unsigned idx, u8* buf, size_t count, u8* data, size_t length) {
+	/* For now get the first tag, and return the data */
+	piv_private_data_t * priv = PIV_DATA(card);
+	u8* tag;
+	size_t taglen;
+	piv_cache_item* item;
+
+	tag = (u8 *) sc_asn1_find_tag(card->ctx, data,  length, *data, &taglen);
+	if (tag == NULL) {
+		return SC_ERROR_OBJECT_NOT_VALID;
+	}
+	if(taglen < count + idx)
+		count = taglen - idx;
+	if(count <= 0)
+		return 0;
+	memcpy(buf, tag + idx, count);
+	if(0 == add_cache_item(priv, enumtag, NULL, 0)) {
+		item = get_cache_item(priv, enumtag);
+		if(item) {
+			item->data = malloc(taglen);
+			if(item->data) {
+				item->length = taglen;
+				memcpy(item->data, tag, taglen);
+			}
+		}
+	}
+	return count;
+}
 /* 
  * Callers of this are expecting a file without tags,
  * So we need to know what type of file this is, so we can get the
@@ -609,19 +754,32 @@
 static int piv_read_binary(sc_card_t *card, unsigned int idx,
 		unsigned char *buf, size_t count, unsigned long flags)
 {
-	struct piv_private_data * priv = (struct piv_private_data *) card->drv_data;
+	piv_private_data_t * priv = PIV_DATA(card);
+	piv_cache_item* item = NULL;
+	int enumtag;
 	int r;
 	u8 *rbuf = NULL;
 	size_t rbuflen = 0;
-	u8 *tag;
-	size_t taglen;
 	u8 *body;
 	size_t bodylen;
 
 	SC_FUNC_CALLED(card->ctx,1);
 	if (priv->selected_obj < 0) 
 		 SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INTERNAL);
+	enumtag = piv_objects[priv->selected_obj].enumtag;
 
+	/* Hit the cache */
+	if(priv->current_item) {
+		item = priv->current_item;
+		if(idx + count > item->length) {
+			count = item->length - idx;
+		}
+		if(count <= 0)
+			return 0;
+		memcpy(buf, item->data + idx, count);
+		return count;
+	}
+
 	if (priv->eof == 1)
 		return 0;
 
@@ -629,7 +787,7 @@
 	
 	if (r >=0) {
 		/* if tag is 0, assume card is telling us no object on card */
-		if (rbuf[0] == '0') {
+		if (!rbuf || rbuf[0] == '0') {
 			r = SC_ERROR_FILE_NOT_FOUND;
 			goto err;
 		}
@@ -639,40 +797,18 @@
 			/* if missing, assume its the body */
 			/* DEE bug in the beta card */
 			sc_debug(card->ctx," ***** tag 0x53 MISSING \n");
-			body =  rbuf;
-			bodylen = rbuflen;
-#if 0
 			r = SC_ERROR_INVALID_DATA;
 			goto err;
-#endif
 		}
-		switch (piv_objects[priv->selected_obj].enumtag) {
+		switch (enumtag) {
 			case PIV_OBJ_X509_PIV_AUTH:
 			case PIV_OBJ_X509_DS:
 			case PIV_OBJ_X509_KM:
 			case PIV_OBJ_X509_CARD_AUTH:
-				/* get the certificate out */
-				tag = (u8 *) sc_asn1_find_tag(card->ctx, body,  bodylen, 0x70, &taglen);
-				if (tag == NULL) {
-					r = SC_ERROR_OBJECT_NOT_VALID;
-					break;
-				}
-				memcpy(buf, tag, taglen); /*DEE should check lengths */
-				r = taglen;
-				tag = (u8 *) sc_asn1_find_tag(card->ctx, body,  bodylen, 0x71, &taglen);
-				if (tag && ((*tag) & 0x80)) {
-					sc_debug(card->ctx,0,"Cert is gziped! %0x2.2x\n",*tag);
-				}
+				r = piv_handle_certificate_data(card, enumtag, idx, buf, count, body, bodylen);
 				break;
 			default:
-				/* For now get the first tag, and return the data */
-				tag = (u8 *) sc_asn1_find_tag(card->ctx, body,  bodylen, *body, &taglen);
-				if (tag == NULL) {
-					r = SC_ERROR_OBJECT_NOT_VALID;
-					break;
-				}
-				memcpy(buf, tag, taglen); /*DEE should check lengths */
-				r = taglen;
+				r = piv_handle_data(card, enumtag, idx, buf, count, body, bodylen);
 				break;
 		}
 	}
@@ -720,23 +856,57 @@
 	SC_FUNC_RETURN(card->ctx, 1, r);
 }
 
+static int piv_write_certificate(sc_card_t *card,
+		unsigned idx, const u8* buf, size_t count,
+		unsigned long flags) {
+	piv_private_data_t * priv = PIV_DATA(card);
+	int r = SC_SUCCESS;
+	u8 *sbuf = NULL;
+	u8 *p;
+	size_t sbuflen;
+	size_t taglen;
 
+	sc_debug(card->ctx,"DEE cert len=%d",count);
+	taglen = put_tag_and_len(0x70, count, NULL) 
+		+ put_tag_and_len(0x71, 1, NULL)
+		+ put_tag_and_len(0xFE, 0, NULL);
+
+	sbuflen =  put_tag_and_len(0x53, taglen, NULL);
+
+	sbuf = (u8*) malloc(sbuflen);
+	if (sbuf == NULL) 
+		SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_OUT_OF_MEMORY);
+	p = sbuf;
+	put_tag_and_len(0x53, taglen, &p);
+
+	put_tag_and_len(0x70, count, &p);
+	memcpy(p, buf, count);
+	p += count;
+	put_tag_and_len(0x71, 1, &p);
+	*p++ = (flags && 1)? 0x80:0x00; /* certinfo, i.e. gziped? */
+	put_tag_and_len(0xFE,0,&p); /* LRC tag */
+
+	sc_debug(card->ctx,"DEE buf %p len %d %d", sbuf, p -sbuf, sbuflen);
+
+	r = piv_put_data(card, priv->selected_obj, sbuf, sbuflen);
+	if (sbuf)
+		free(sbuf);
+
+	return r;
+}
 /* 
  * We need to add the 0x53 tag and other specific tags, 
  * and call the piv_put_data 
  * Note: the select file will have saved the object type for us 
+ * Write is only used by piv-tool, so we will use flags==1
+ * to indicate we are writing a compressed cert. 
  */
 
 static int piv_write_binary(sc_card_t *card, unsigned int idx,
 		const u8 *buf, size_t count, unsigned long flags)
 {
-	struct piv_private_data * priv = (struct piv_private_data *) card->drv_data;
-	int r = 0;
-	u8 *sbuf = NULL;
-	u8 *p;
-	size_t sbuflen;
-	size_t taglen;
-	
+	piv_private_data_t * priv = PIV_DATA(card);
+	/* TODO: Add cache hooks */	
 	SC_FUNC_CALLED(card->ctx,1);
 
 	if (priv->selected_obj < 0)
@@ -749,40 +919,12 @@
 		case PIV_OBJ_X509_DS:
 		case PIV_OBJ_X509_KM:
 		case PIV_OBJ_X509_CARD_AUTH:
-		sc_debug(card->ctx,"DEE cert len=%d",count);
-		
-			taglen = put_tag_and_len(0x70, count, NULL) 
-				+ put_tag_and_len(0x71, 1, NULL);
-
-			sbuflen =  put_tag_and_len(0x53, taglen, NULL);
-
-			sbuf = (u8*) malloc(sbuflen);
-			if (sbuf == NULL) 
-				SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_OUT_OF_MEMORY);
-			p = sbuf;
-			put_tag_and_len(0x53, taglen, &p);
-
-			put_tag_and_len(0x70, count, &p);
-			memcpy(p, buf, count);
-			p += count;
-			put_tag_and_len(0x71, 1, &p);
-			*p++ = 0x00; /* certinfo, i.e. not gziped */
-			sc_debug(card->ctx,"DEE buf %p len %d %d", sbuf, p -sbuf, sbuflen);
-			break;
-			
+			SC_FUNC_RETURN(card->ctx, 1, piv_write_certificate(card, idx, buf, count, flags));
 		default:
 		sc_debug(card->ctx, "Don't know how to write object %s\n",
 			piv_objects[priv->selected_obj].name);
-			r = SC_ERROR_NOT_SUPPORTED;
-			break;
+			SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
 	}
-
-	if (r == 0) 
-		r = piv_put_data(card, priv->selected_obj, sbuf, sbuflen);
-	if (sbuf)
-		free(sbuf);
-
-	SC_FUNC_RETURN(card->ctx, 1, r);
 }
 
 /*
@@ -954,7 +1096,7 @@
 static int piv_general_external_authenticate(sc_card_t *card, 
 		unsigned int key_ref, unsigned int alg_id)
 {
-	struct piv_private_data * priv = (struct piv_private_data *) card->drv_data;
+	piv_private_data_t * priv = PIV_DATA(card);
 	int r, outl;
 	u8  *rbuf = NULL;
 	size_t rbuflen;
@@ -1109,7 +1251,7 @@
                     const sc_security_env_t *env,
                     int se_num)
 {
-	struct piv_private_data * priv = (struct piv_private_data *) card->drv_data;
+	piv_private_data_t * priv = PIV_DATA(card);
 	
 	SC_FUNC_CALLED(card->ctx,1);
 
@@ -1139,7 +1281,7 @@
 					const u8 * data, size_t datalen,
 					u8 * out, size_t outlen)
 {
-	struct piv_private_data * priv = (struct piv_private_data *) card->drv_data;
+	piv_private_data_t * priv = PIV_DATA(card);
 	int r;
 	u8 *p;
 	u8 *tag;
@@ -1228,7 +1370,8 @@
 static int piv_select_file(sc_card_t *card, const sc_path_t *in_path,
 	sc_file_t **file_out)
 {
- 	struct piv_private_data * priv = (struct piv_private_data *) card->drv_data;
+ 	piv_private_data_t * priv = PIV_DATA(card);
+	piv_cache_item* item = NULL;
 	int i;
 	const u8 *path;
 	int pathlen;
@@ -1255,8 +1398,14 @@
 	priv->selected_obj = i;
 	priv->eof = 0;
 
+	/* check out the cache */
+	item = get_cache_item(priv, i);
+	if(item) {
+		priv->current_item = item;
+	}
+	
 	/* make it look like the file was found. We don't want to read it now,. */ 
-
+	
 	if (file_out) {
 		file = sc_file_new();
 		if (file == NULL)
@@ -1266,8 +1415,13 @@
 		/* this could be like the FCI */
 		file->type =  SC_FILE_TYPE_DF;
 		file->shareable = 0;
-		file->ef_structure = 0; 
-		file->size = piv_objects[i].maxlen;
+		file->ef_structure = 0;
+		if(item) {
+			file->size = item->length;
+		} else {
+			file->size = piv_objects[i].maxlen;
+		}
+
 		file->id = (piv_objects[i].containerid[0]<<8) + piv_objects[i].containerid[1];
 
 		*file_out = file;
@@ -1280,12 +1434,16 @@
 
 static int piv_finish(sc_card_t *card)
 {
- 	struct piv_private_data * priv = (struct piv_private_data *) card->drv_data;
+ 	piv_private_data_t * priv = PIV_DATA(card);
 
 	SC_FUNC_CALLED(card->ctx,1);
 	if (priv) {
 		if (priv->aid_file)
 			sc_file_free(priv->aid_file);
+		if(priv->cache) {
+			free_cache_items(priv);
+			free(priv->cache);
+		}
 		free(priv);
 	}
 	return 0;
@@ -1294,9 +1452,18 @@
 
 static int piv_match_card(sc_card_t *card)
 {
+	int i;
+	sc_file_t aidfile;
 	SC_FUNC_CALLED(card->ctx,1);
-	/* dee need to look at AID */
-	return 0; /* never match */
+	/* Since we send an APDU, the card's logout function may be called...
+	 * however it may be in dirty memory */
+	card->ops->logout = NULL;
+
+	/* Detect by selecting applet */
+	sc_ctx_suppress_errors_on(card->ctx);
+	i = !(piv_find_aid(card, &aidfile));
+	sc_ctx_suppress_errors_off(card->ctx);
+	return i; /* never match */
 }
 
 
@@ -1304,16 +1471,17 @@
 {
 	int r;
 	unsigned long flags;
-	struct piv_private_data *priv;
+	piv_private_data_t *priv;
 
 	SC_FUNC_CALLED(card->ctx,1);
-	priv = (struct piv_private_data *) calloc(1, sizeof(struct piv_private_data));
+	priv = (piv_private_data_t *) calloc(1, sizeof(piv_private_data_t));
 
 	if (!priv)
 		return SC_ERROR_OUT_OF_MEMORY;
 	priv->aid_file = sc_file_new();
 	priv->selected_obj = -1;
-	priv->max_recv_size = card->max_recv_size;
+	priv->max_recv_size = 256;
+	//priv->max_recv_size = card->max_recv_size;
 	priv->max_send_size = card->max_send_size;
 	card->max_recv_size = 0xffff; /* must force pkcs15 read_binary in one call */
 	card->max_send_size = 0xffff;
@@ -1339,6 +1507,9 @@
 	_sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */
 	
 	card->caps |= SC_CARD_CAP_RNG;
+	
+	priv->cache = calloc(PIV_CACHE_SIZE, sizeof(piv_cache_item));
+	priv->cacheLen = PIV_CACHE_SIZE;
 
 	if (r > 0)
 		r = 0;
Index: src/libopensc/pkcs15-piv.c
===================================================================
--- src/libopensc/pkcs15-piv.c	(revision 3121)
+++ src/libopensc/pkcs15-piv.c	(working copy)
@@ -5,6 +5,9 @@
  * Copyright (C) 2005, Douglas E. Engert <[EMAIL PROTECTED]> 
  *               2004, Nils Larsch <[EMAIL PROTECTED]>
  *
+ * Copyright (C) 2006, Identity Alliance, 
+ *               Thomas Harning <[EMAIL PROTECTED]>
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
@@ -19,7 +22,6 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include "internal.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -33,88 +35,12 @@
 #include <openssl/rsa.h>
 #include <openssl/pem.h>
 #include "strlcpy.h"
+#include "p15card-helper.h"
 
 #define MANU_ID		"piv_II "
 
 int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
 
-
-typedef struct objdata_st {
-	const char *id;
-	const char *label;
-	const char *aoid;
-	int     authority;
-	const char *path;
-	int         obj_flags;
-} objdata;
-
-typedef struct cdata_st {
-	const char *id;
-	const char *label;
-	int	    authority;
-	const char *path;
-	int         obj_flags;
-} cdata;
-
-typedef struct pdata_st {
-	const char *id;
-	const char *label;
-	const char *path;
-	int         ref;
-	int         type;
-	unsigned int maxlen;
-	unsigned int minlen;
-	unsigned int storedlen;
-	int         flags;	
-	int         tries_left;
-	const char  pad_char;
-	int         obj_flags;
-} pindata; 
-
-typedef struct pubdata_st {
-	const char *id;
-	const char *label;
-	unsigned int modulus_len;
-	int         usage;
-	const char *path;
-	int         ref;
-	const char *auth_id;
-	int         obj_flags;
-} pubdata;
-
-typedef struct prdata_st {
-	const char *id;
-	const char *label;
-	unsigned int modulus_len;
-	int         usage;
-	const char *path;
-	int         ref;
-	const char *auth_id;
-	int         obj_flags;
-} prdata;
-
-typedef struct keyinfo_st {
-	int fileid;
-	sc_pkcs15_id_t id;
-	unsigned int modulus_len;
-	u8 modulus[1024/8];
-} keyinfo;
-
-	
-
-#define USAGE_NONREP	SC_PKCS15_PRKEY_USAGE_NONREPUDIATION
-#define USAGE_KE	SC_PKCS15_PRKEY_USAGE_ENCRYPT | \
-			SC_PKCS15_PRKEY_USAGE_DECRYPT | \
-			SC_PKCS15_PRKEY_USAGE_WRAP    | \
-			SC_PKCS15_PRKEY_USAGE_UNWRAP
-#define USAGE_AUT	SC_PKCS15_PRKEY_USAGE_ENCRYPT | \
-			SC_PKCS15_PRKEY_USAGE_DECRYPT | \
-			SC_PKCS15_PRKEY_USAGE_WRAP    | \
-			SC_PKCS15_PRKEY_USAGE_UNWRAP  | \
-			SC_PKCS15_PRKEY_USAGE_SIGN
-
-
-
 static int piv_detect_card(sc_pkcs15_card_t *p15card)
 {
 	sc_card_t *card = p15card->card;
@@ -126,98 +52,137 @@
 	return SC_SUCCESS;
 }
 
-static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
-{
-	const objdata objects[] = {
-		{"1", "Card Capability Container", 
-				"2.16.840.1.101.3.7.1.219.0", 0, "DB00", 0},
-		{"2", "Card Holder Unique Identifier",
-				"2.16.840.1.101.3.7.2.48.0", 0 , "3000", 0},
-		{"3", "Card Holder Fingerprint I",
-				"2.16.840.1.101.3.7.2.96.16", 0, "6010", SC_PKCS15_CO_FLAG_PRIVATE},
-		{"4", "Card Holder Fingerprint II",
-				"2.16.840.1.101.3.7.2.96.17", 0, "6011", SC_PKCS15_CO_FLAG_PRIVATE},
-		{"5", "Printed Information",
-				"2.16.840.1.101.3.7.2.48.1", 0, "3001", SC_PKCS15_CO_FLAG_PRIVATE},
-		{"6", "Card Holder Facial Image", 
-				"2.16.840.1.101.3.7.2.96.48", 0, "6030", SC_PKCS15_CO_FLAG_PRIVATE},
-		{"7", "Security Object",
-				"2.16.840.1.101.3.7.2.144.0", 0, "9000", 0},
-		{NULL, NULL, NULL, 0, NULL, 0}
-	};
+const objdata objects[] = {
+	{"1", "Card Capability Container", 
+			"2.16.840.1.101.3.7.1.219.0", 0, "DB00", 0},
+	{"2", "Card Holder Unique Identifier",
+			"2.16.840.1.101.3.7.2.48.0", 0 , "3000", 0},
+	{"3", "Card Holder Fingerprints",
+			"2.16.840.1.101.3.7.2.96.16", 0, "6010", SC_PKCS15_CO_FLAG_PRIVATE},
+	{"4", "Printed Information",
+			"2.16.840.1.101.3.7.2.48.1", 0, "3001", SC_PKCS15_CO_FLAG_PRIVATE},
+	{"5", "Card Holder Facial Image", 
+			"2.16.840.1.101.3.7.2.96.48", 0, "6030", SC_PKCS15_CO_FLAG_PRIVATE},
+	{"6", "Security Object",
+			"2.16.840.1.101.3.7.2.144.0", 0, "9000", 0},
+	{NULL, NULL, NULL, 0, NULL, 0}
+};
 
-	/* 
-	 * NIST 800-73-1 is proposing to lift the restriction on 
-	 * requering pin protected certs. Thus the default will be to 
-	 * not require this. But there are a number of test cards 
-	 * that do enforce it. Code later on will allow SC_PKCS15_CO_FLAG_PRIVATE
-	 * to be set. 
-	 */
-	const cdata certs[] = {
-		{"1", "Certificate for PIV Authentication", 0, "0101", 0},
-		{"2", "Certificate for Digital Signature", 0, "0100", 0},
-		{"3", "Certificate for Key Management", 0, "0102", 0},
-		{"4", "Certificate for Card Authentication", 0, "0500", 0},
-		{NULL, NULL, 0, NULL, 0}
-	};
+/* 
+ * NIST 800-73-1 is proposing to lift the restriction on 
+ * requering pin protected certs. Thus the default will be to 
+ * not require this. But there are a number of test cards 
+ * that do enforce it. Code later on will allow SC_PKCS15_CO_FLAG_PRIVATE
+ * to be set. 
+ */
+const cdata certs[] = {
+	{"1", "Certificate for PIV Authentication", 0, "0101", 0},
+	{"2", "Certificate for Digital Signature", 0, "0100", 0},
+	{"3", "Certificate for Key Management", 0, "0102", 0},
+#if 0 /* Strange break */
+	{"4", "Certificate for Card Authentication", 0, "0500", 0},
+#endif
+	{NULL, NULL, 0, NULL, 0}
+};
 
-	const pindata pins[] = {
-		{ "1", "PIV Card Holder pin", "", 0x80,
-		  SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
-		  8, 4, 8, 
-		  SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
-		  SC_PKCS15_PIN_FLAG_LOCAL, 
-		  -1, 0xFF,
-		  SC_PKCS15_CO_FLAG_PRIVATE },
-		{ "2", "PIV PUK", "", 0x81, 
-		  SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
-		  8, 4, 8, 
-		  SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
-		  SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_SO_PIN |
-		  SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN, 
-		  -1, 0xFF, 
-		  SC_PKCS15_CO_FLAG_PRIVATE },
-		/* there are some more key, but dont need for now */
-		/* The admin 9b might fall in here */
-		{ NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-	};
+const pindata pins[] = {
+	{ "1", "PIV Card Holder pin", "", 0x80,
+	  SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
+	  8, 4, 8, 
+	  SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
+	  SC_PKCS15_PIN_FLAG_LOCAL, 
+	  -1, 0xFF,
+	  SC_PKCS15_CO_FLAG_PRIVATE },
+	{ "2", "PIV PUK", "", 0x81, 
+	  SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
+	  8, 4, 8, 
+	  SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
+	  SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_SO_PIN |
+	  SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN, 
+	  -1, 0xFF, 
+	  SC_PKCS15_CO_FLAG_PRIVATE },
+	/* there are some more key, but dont need for now */
+	/* The admin 9b might fall in here */
+	{ NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+};
 
 
-	/*
-	 * The size of the key or the algid is not really known
-	 * but can be derived from the certificates. 
-	 * DEE need to fix - We will still refer to the "key files" as 06 even of not.
-	 * 07 is 2048, 05 is 3072. 
-	 */
-	const pubdata pubkeys[] = {
+/*
+ * The size of the key or the algid is not really known
+ * but can be derived from the certificates. 
+ * DEE need to fix - We will still refer to the "key files" as 06 even of not.
+ * 07 is 2048, 05 is 3072. 
+ */
+const pubdata pubkeys[] = {
 
-		{ "1", "AUTH pubkey", 1024, USAGE_AUT, "9A06", 
-		  0x9A, "1", 0},
-		{ "2", "SIGN pubkey", 1024, USAGE_AUT, "9C06", 
-		  0x9C, "1", 0},
-		{ "3", "KEY MAN pubkey", 1024, USAGE_AUT, "9D06", 
-		  0x9D, "1", 0},
-		{ "4", "ADMIN pubkey", 1024, USAGE_AUT, "9B06", 
-		  0x9B, "1", 0},
-		{ NULL, NULL, 0, 0, NULL, 0, NULL, 0}
-		
-	};
+	{ "1", "AUTH pubkey", 1024, USAGE_AUT, "9A06", 
+	  0x9A, "1", 0},
+	{ "2", "SIGN pubkey", 1024, USAGE_AUT, "9C06", 
+	  0x9C, "1", 0},
+	{ "3", "KEY MAN pubkey", 1024, USAGE_AUT, "9D06", 
+	  0x9E, "1", 0},
+	{ "4", "ADMIN pubkey", 1024, USAGE_AUT, "9B06", 
+	  0x9B, "1", 0},
+	{ NULL, NULL, 0, 0, NULL, 0, NULL, 0}
+	
+};
 
-	const prdata prkeys[] = {
-		{ "1", "AUTH key", 1024, USAGE_AUT, "",
-		  0x9A, "1", 0},
-		{ "2", " SIGN key", 1024, USAGE_AUT, "",
-		  0x9B, "1", 0},
-		{ "3", "KEY MAN key", 1024, USAGE_AUT, "",
-		  0x9C, "1", 0},
-		{ "4", "ADMIN key", 1024, USAGE_AUT, "",
-		  0x9D, "1", 0},
-		{ NULL, NULL, 0, 0, NULL, 0, NULL, 0}
-	};
+const prdata prkeys[] = {
+	{ "1", "AUTH key", 1024, USAGE_AUT, "",
+	  0x9A, "1", 0},
+	{ "2", "SIGN key", 1024, USAGE_AUT, "",
+	  0x9C, "1", 0},
+	{ "3", "KEY MAN key", 1024, USAGE_AUT, "",
+	  0x9E, "1", 0},
+	{ "4", "ADMIN key", 1024, USAGE_AUT, "",
+	  0x9B, "1", 0},
+	{ NULL, NULL, 0, 0, NULL, 0, NULL, 0}
+};
 
-	int    r, i;
+/* TEMPORARY: Should hook into card-piv ... */
+static int piv_load_cached_cert(sc_card_t *card, u8** buf, size_t* count, int* should_free) {
+	/* File already selected.. just read... */
+	int r;
+	u8* out = malloc(4096*2);
+	r = sc_read_binary(card, 0, out, 4096*2, 0);
+	if(r < 0) {
+		free(out);
+		*buf = NULL;
+		*count = 0;
+		return r;
+	}
+	*count = r;
+	*buf = out;
+	*should_free = 1;
+	return SC_SUCCESS;
+}
+
+#define CHECK_CERTIFICATES 1
+static p15data_items items = {
+	objects,
+	certs,
+	pins,
+	NULL,
+	prkeys,
+#ifdef CHECK_CERTIFICATES
+	piv_load_cached_cert,
+#else
+	NULL,
+#endif
+	default_cert_handle,
+	1,
+#ifdef CHECK_CERTIFICATES
+	0,
+#else
+	1,
+#endif
+	0
+};
+
+static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
+{
+	int    r;
 	sc_card_t *card = p15card->card;
-	int exposed_cert[4] = {1, 0, 0, 0};
 
 	SC_FUNC_CALLED(card->ctx, 1);
 
@@ -238,162 +203,9 @@
         p15card->serial_number = strdup("9876543210");
 
 	sc_debug(card->ctx, "PIV-II adding objects...");
-
-	/* set other objects */
-	for (i = 0; objects[i].label; i++) {
-		struct sc_pkcs15_data_info obj_info;
-		struct sc_pkcs15_object    obj_obj;
-
-		memset(&obj_info, 0, sizeof(obj_info));
-		memset(&obj_obj, 0, sizeof(obj_obj));
-		sc_pkcs15_format_id(objects[i].id, &obj_info.id);
-		sc_format_path(objects[i].path, &obj_info.path);
-		strlcpy(obj_info.app_label, objects[i].label, sizeof(obj_info.app_label));
-		r = sc_format_oid(&obj_info.app_oid, objects[i].aoid);
-		if (r != SC_SUCCESS)
-			return r;
-
-		strlcpy(obj_obj.label, objects[i].label, sizeof(obj_obj.label));
-		obj_obj.flags = objects[i].obj_flags;
-		
-		r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, 
-			&obj_obj, &obj_info); 
-		if (r < 0)
-			SC_FUNC_RETURN(card->ctx, 1, r);
-	}
-
-	/* set certs */
-	for (i = 0; certs[i].label; i++) {
-		struct sc_pkcs15_cert_info cert_info;
-		struct sc_pkcs15_object    cert_obj;
-		
-		if ((card->flags & 0x20) &&  (exposed_cert[i] == 0))
-			continue;
-
-		memset(&cert_info, 0, sizeof(cert_info));
-		memset(&cert_obj,  0, sizeof(cert_obj));
 	
-		sc_pkcs15_format_id(certs[i].id, &cert_info.id);
-		cert_info.authority = certs[i].authority;
-		sc_format_path(certs[i].path, &cert_info.path);
+	r = initialize_all(p15card, &items);
 
-		strlcpy(cert_obj.label, certs[i].label, sizeof(cert_obj.label));
-		cert_obj.flags = certs[i].obj_flags;
-
-		/* Cards based on NIST 800-73 may enforce pin protected certs */
-		/* But this is being dropped in 800-73-1 */
-		if (card->flags & 0x10) {
-			cert_obj.flags |=  SC_PKCS15_CO_FLAG_PRIVATE;
-		}
-
-		r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
-		if (r < 0)
-			SC_FUNC_RETURN(card->ctx, 1, r);
-	}
-
-
-	/* set pins */
-
-	for (i = 0; pins[i].label; i++) {
-		struct sc_pkcs15_pin_info pin_info;
-		struct sc_pkcs15_object   pin_obj;
-
-		memset(&pin_info, 0, sizeof(pin_info));
-		memset(&pin_obj,  0, sizeof(pin_obj));
-
-		sc_pkcs15_format_id(pins[i].id, &pin_info.auth_id);
-		pin_info.reference     = pins[i].ref;
-		pin_info.flags         = pins[i].flags;
-		pin_info.type          = pins[i].type;
-		pin_info.min_length    = pins[i].minlen;
-		pin_info.stored_length = pins[i].storedlen;
-		pin_info.max_length    = pins[i].maxlen;
-		pin_info.pad_char      = pins[i].pad_char;
-		sc_format_path(pins[i].path, &pin_info.path);
-		pin_info.tries_left    = -1;
-
-		strlcpy(pin_obj.label, pins[i].label, sizeof(pin_obj.label));
-		pin_obj.flags = pins[i].obj_flags;
-
-		r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
-		if (r < 0)
-			SC_FUNC_RETURN(card->ctx, 1, r);
-	}
-
-
-
-	/* set public keys */
-	/* We may only need this during initialzation when genkey
-	 * gets the pubkey, but it can not be read from the card 
-	 * at a later time. The piv-tool can stach in file 
-	 */ 
-
-	for (i = 0; pubkeys[i].label; i++) {
-		struct sc_pkcs15_pubkey_info pubkey_info;
-		struct sc_pkcs15_object     pubkey_obj;
-
-		if ((card->flags & 0x20) &&  (exposed_cert[i] == 0))
-			continue;
-
-		memset(&pubkey_info, 0, sizeof(pubkey_info));
-		memset(&pubkey_obj,  0, sizeof(pubkey_obj));
-
-		sc_pkcs15_format_id(pubkeys[i].id, &pubkey_info.id);
-		pubkey_info.usage         = pubkeys[i].usage;
-		pubkey_info.native        = 1;
-		pubkey_info.key_reference = pubkeys[i].ref;
-		pubkey_info.modulus_length= pubkeys[i].modulus_len;
-		/* we really don't know how many bits or module length,
-		 * we will assume 1024 for now 
-		 */
-		sc_format_path(pubkeys[i].path, &pubkey_info.path);
-
-		strlcpy(pubkey_obj.label, pubkeys[i].label, sizeof(pubkey_obj.label));
-
-		pubkey_obj.flags = pubkeys[i].obj_flags;
-
-		if (pubkeys[i].auth_id)
-			sc_pkcs15_format_id(pubkeys[i].auth_id, &pubkey_obj.auth_id);
-
-		r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
-		if (r < 0)
-			SC_FUNC_RETURN(card->ctx, 1, r);
-	}
-
-
-	/* set private keys */
-	for (i = 0; prkeys[i].label; i++) {
-		struct sc_pkcs15_prkey_info prkey_info;
-		struct sc_pkcs15_object     prkey_obj;
-
-		if ((card->flags & 0x20) &&  (exposed_cert[i] == 0))
-			continue;
-
-		memset(&prkey_info, 0, sizeof(prkey_info));
-		memset(&prkey_obj,  0, sizeof(prkey_obj));
-
-		sc_pkcs15_format_id(prkeys[i].id, &prkey_info.id);
-		prkey_info.usage         = prkeys[i].usage;
-		prkey_info.native        = 1;
-		prkey_info.key_reference = prkeys[i].ref;
-		prkey_info.modulus_length= prkeys[i].modulus_len;
-		/* we really don't know how many bits or module length,
-		 * we will assume 1024 for now
-		 */
-		sc_format_path(prkeys[i].path, &prkey_info.path);
-
-		strlcpy(prkey_obj.label, prkeys[i].label, sizeof(prkey_obj.label));
-
-		prkey_obj.flags = prkeys[i].obj_flags;
-
-		if (prkeys[i].auth_id)
-			sc_pkcs15_format_id(prkeys[i].auth_id, &prkey_obj.auth_id);
-
-		r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
-		if (r < 0)
-			SC_FUNC_RETURN(card->ctx, 1, r);
-	}
-
 	SC_FUNC_RETURN(card->ctx, 1, SC_SUCCESS);
 }
 
Index: src/libopensc/Makefile.mak
===================================================================
--- src/libopensc/Makefile.mak	(revision 3121)
+++ src/libopensc/Makefile.mak	(working copy)
@@ -29,6 +29,7 @@
 	card-oberthur.obj card-belpic.obj card-atrust-acos.obj \
 	card-incrypto34.obj card-piv.obj\
 	muscle.obj card-muscle.obj muscle-filesystem.obj \
+	compression.obj p15card-helper.obj \
 	\
 	pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \
 	pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-postecert.obj \
Index: src/libopensc/Makefile.am
===================================================================
--- src/libopensc/Makefile.am	(revision 3121)
+++ src/libopensc/Makefile.am	(working copy)
@@ -33,14 +33,15 @@
 	\
 	pkcs15-openpgp.c pkcs15-infocamere.c pkcs15-starcert.c \
 	pkcs15-tcos.c pkcs15-esteid.c pkcs15-postecert.c pkcs15-gemsafe.c \
-	pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c
+	pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \
+	compression.c p15card-helper.c
 libopensc_la_LDFLAGS = -version-info @OPENSC_LT_CURRENT@:@OPENSC_LT_REVISION@:@OPENSC_LT_AGE@
 libopensc_la_LIBADD = @LIBSCCONF@ $(OPENSSL_LIBS) $(OPENCT_LIBS) $(PCSC_LIBS) $(LTLIBLTDL)
 
 include_HEADERS = \
 	opensc.h pkcs15.h emv.h \
 	cardctl.h asn1.h log.h ui.h \
-	errors.h types.h
+	errors.h types.h compression.h
 
 noinst_HEADERS = cards.h ctbcs.h internal.h esteid.h muscle.h muscle-filesystem.h part10.h
 
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to