new pre release for 0.11.2 available

classic Classic list List threaded Threaded
45 messages Options
123
Reply | Threaded
Open this post in threaded view
|

new pre release for 0.11.2 available

Andreas Jellinghaus-2
It would be good to have opensc 0.11.2 soon, so I made another
pre-release with current trunk available:

http://www.opensc-project.org/files/opensc/testing/
http://www.opensc-project.org/files/opensc/testing/opensc-0.11.2-pre4.tar.gz

Please test this and give feedback.

I'm sorry, currently I find next to no time for opensc.

Regards, Andreas
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Douglas E. Engert
Any chance getting the patch for the PIV compression ticket #128
into this release?

Andreas Jellinghaus wrote:

> It would be good to have opensc 0.11.2 soon, so I made another
> pre-release with current trunk available:
>
> http://www.opensc-project.org/files/opensc/testing/
> http://www.opensc-project.org/files/opensc/testing/opensc-0.11.2-pre4.tar.gz
>
> Please test this and give feedback.
>
> I'm sorry, currently I find next to no time for opensc.
>
> Regards, Andreas
> _______________________________________________
> opensc-devel mailing list
> [hidden email]
> http://www.opensc-project.org/mailman/listinfo/opensc-devel
>
>

--

  Douglas E. Engert  <[hidden email]>
  Argonne National Laboratory
  9700 South Cass Avenue
  Argonne, Illinois  60439
  (630) 252-5444
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Peter Stuge
On Mon, Mar 05, 2007 at 04:37:14PM -0600, Douglas E. Engert wrote:
> Any chance getting the patch for the PIV compression ticket #128
> into this release?

I think it looks good at a glance.

Does it apply cleanly to svn?

Has it been tested?


Two general comments:

1. I would prefer if the p15card-helper bit was made into a separate
patch to be applied first.

2. Does the copyright belong to Identity Alliance or Thomas Harning
or both? Currently both are in the notice. In another project we use
(for the Identity Alliance case):

/*
 * Copyright (C) 2006 Identity Alliance
 * Written by Thomas Harning <thomas..@..> for Identity Alliance
 */

..so it is ultra clear.


//Peter
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Thomas Harning Jr.
On Tue, 2007-03-06 at 13:11 +0100, Peter Stuge wrote:
> On Mon, Mar 05, 2007 at 04:37:14PM -0600, Douglas E. Engert wrote:
> > Any chance getting the patch for the PIV compression ticket #128
> > into this release?
>
> I think it looks good at a glance.
>
> Does it apply cleanly to svn?
>
(Not sure on that... haven't worked w/ OpenSC for a little while)
> Has it been tested?
>
We've tested it on end-state PIV cards, ones that we have programmed,
and used the compression utility for a few other items we've worked on.

>
> Two general comments:
>
> 1. I would prefer if the p15card-helper bit was made into a separate
> patch to be applied first.
>
> 2. Does the copyright belong to Identity Alliance or Thomas Harning
> or both? Currently both are in the notice. In another project we use
> (for the Identity Alliance case):
>
> /*
>  * Copyright (C) 2006 Identity Alliance
>  * Written by Thomas Harning <thomas..@..> for Identity Alliance
>  */
Sorry it wasn't more clear.  The copyright for those patches would
belong to Identity Alliance.  Feel free to modify the headers to better
match the necessary format...
--
Thomas Harning Jr.
Authentication Engineer @ Identity Alliance
http://www.trustbearer.com/

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Douglas E. Engert
In reply to this post by Douglas E. Engert
Peter,
I sent this to Andreas and Nils, but it might help answer your
questions


Andreas Jellinghaus wrote:
> Am Montag, 5. März 2007 23:37 schrieben Sie:
>> Any chance getting the patch for the PIV compression ticket #128
>> into this release?
>
> I'm asking Nils for feedback. As far as I remember he had some comment /
> change request for the code.
>

There where some issues with not testing for zlib, that would be easy to
add the #ifdef's. I think there where some comments about naming too.
Nils would know more.

> but on the other hand - if the patch doesn't break anything - I prefer to
> add code if noone has time to improve it. Work shouldn't be lost.
>
> if I remember correctly, the code was done by the author of the muscle
> driver.

He is one of the people from Identity Alliance. I believe Identity
Alliance was founded by David Corcoran. David's picture is on their web
site: http://www.identityalliance.com/ I believe he started Muscle as an
independent consultant. David has authored some of their PIV documents.
They have IdAlly, a Windows CSP, that can call PKCS#11 and  can work with
OpenSC. So Identity Alliance is closely tied to OpenSC. Having the
ompression code added would make sure PIV was compliant.

When I wrote the original PIV code, there was a one line reference to
compressing which I left undone, as it was not clear how this was to be
done, or if would ever be done, so I did not add it.

But based on the patch and notes from Kennith Carrera, Also a consultant,
I believe, it looks like some cards are being issued with compressed certificates.

> did you test the code? does it work for you? or did anyone else?

Yes, to the effect that OpenSC still worked with uncompressed certificates.
Yesterday. I don't have a card with a officaly compressed certificate, but
I think Kennith does. Yesterday I started writing the code to add to
piv-tool to compress a certificate, and I expect to try that today, (its
7:00AM and I am at home) test the patch with it, build OpenSC on MacOS,
send Kennith an updated libopensc, so he can try with his compressed cert.

> sorry that I have to ask, but > 10 test&respond cycles with the muscle
> guys got me nowhere, their driver still does not work.

I don't think Identity Alliance is interested in Muscle much any more,
but have moved on to consulting with PIV, as the U.S. federal government
is trying to implement PIV. There is a lot of consultant work going on
in Washington DC. It is not clear (to me st least) who is doing Muscle,
and what its future as a mainstream smart card applet is.

My part in all this, is we have a lot of open source Unix systems, as
desktops and for PIV to be use able it has to be on the desktop.
Microsoft and Apple will provide PIV support for their systems, but
no one was doing anything for the Open Source systems. I am also the
past chair of the IETF Kerberos working group, and using PIV cards via
PKCS#11 with the Heimdal or MIT Kerberos PKINIT is a great way to
authenticate, even to Active Directory.

So I feel that it is important to get the compressed code in to the
next release of OpenSC to keep itcompatable. So if you can give me a
few days to try and pull this together...

Thanks.


>
> Regards, Andreas
>
>

--

  Douglas E. Engert  <[hidden email]>
  Argonne National Laboratory
  9700 South Cass Avenue
  Argonne, Illinois  60439
  (630) 252-5444

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Andreas Jellinghaus-2
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
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Nils Larsch
In reply to this post by Douglas E. Engert
Douglas E. Engert wrote:

> Peter,
> I sent this to Andreas and Nils, but it might help answer your
> questions
>
>
> Andreas Jellinghaus wrote:
>> Am Montag, 5. März 2007 23:37 schrieben Sie:
>>> Any chance getting the patch for the PIV compression ticket #128
>>> into this release?
>>
>> I'm asking Nils for feedback. As far as I remember he had some comment
>> / change request for the code.
>>
>
> There where some issues with not testing for zlib, that would be easy to
> add the #ifdef's.

still someone needs to do it ;-)

> I think there where some comments about naming too.
> Nils would know more.

well, "do_decompress" is a bad name for a function which we want to export ...
(*if* we want to export this function at all ?)

Nils
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Douglas E. Engert
In reply to this post by Andreas Jellinghaus-2
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
> [hidden email]
> http://www.opensc-project.org/mailman/listinfo/opensc-devel
>
>
--

  Douglas E. Engert  <[hidden email]>
  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ä <[hidden email]>
  * Copyright (C) 2005, Douglas E. Engert <[hidden email]>
+ * Copyright (C) 2006, Identity Alliance, Thomas Harning <[hidden email]>
  *
  * 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 <[hidden email]>
  *               2004, Nils Larsch <[hidden email]>
  *
+ * Copyright (C) 2006, Identity Alliance,
+ *               Thomas Harning <[hidden email]>
+ *
  * 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
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Douglas E. Engert
One minor change, it looks like the #include "internal.h"
was removed from pkcs15-piv.c. I can add that back in
with any other changes you might want.


Douglas E. Engert wrote:

> 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
>> [hidden email]
>> http://www.opensc-project.org/mailman/listinfo/opensc-devel
>>
>>
>
>
> ------------------------------------------------------------------------
>
> 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ä <[hidden email]>
>   * Copyright (C) 2005, Douglas E. Engert <[hidden email]>
> + * Copyright (C) 2006, Identity Alliance, Thomas Harning <[hidden email]>
>   *
>   * 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 <[hidden email]>
>   *               2004, Nils Larsch <[hidden email]>
>   *
> + * Copyright (C) 2006, Identity Alliance,
> + *               Thomas Harning <[hidden email]>
> + *
>   * 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
> [hidden email]
> http://www.opensc-project.org/mailman/listinfo/opensc-devel

--

  Douglas E. Engert  <[hidden email]>
  Argonne National Laboratory
  9700 South Cass Avenue
  Argonne, Illinois  60439
  (630) 252-5444
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Douglas E. Engert
In reply to this post by Andreas Jellinghaus-2
While building on Windows from svn, the src/pkcs11/Makefile.mak has

all: install-headers install-headers-dir ...

install-headers-dir   should be removed,
as nmake gets an  error on the "for" command
because $(HEADERSDIRFROM2) is not defined.

Windows XP, VC 2005.


Andreas Jellinghaus wrote:

> It would be good to have opensc 0.11.2 soon, so I made another
> pre-release with current trunk available:
>
> http://www.opensc-project.org/files/opensc/testing/
> http://www.opensc-project.org/files/opensc/testing/opensc-0.11.2-pre4.tar.gz
>
> Please test this and give feedback.
>
> I'm sorry, currently I find next to no time for opensc.
>
> Regards, Andreas
> _______________________________________________
> opensc-devel mailing list
> [hidden email]
> http://www.opensc-project.org/mailman/listinfo/opensc-devel
>
>

--

  Douglas E. Engert  <[hidden email]>
  Argonne National Laboratory
  9700 South Cass Avenue
  Argonne, Illinois  60439
  (630) 252-5444
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Tarasov Viktor
In reply to this post by Andreas Jellinghaus-2
Andreas Jellinghaus a écrit :

> It would be good to have opensc 0.11.2 soon, so I made another
> pre-release with current trunk available:
>
> http://www.opensc-project.org/files/opensc/testing/
> http://www.opensc-project.org/files/opensc/testing/opensc-0.11.2-pre4.tar.gz
>
> Please test this and give feedback.
>
> I'm sorry, currently I find next to no time for opensc.
>  
There is a little patch for Oberthur card:
- some ACLs forgotten;
- in compute_signature() limit the Le to 256 bytes.

By the way,
for some libopensc card drivers, in compute_signature() procedure,
the output length is assigned to Le of the Compute Signature APDU.
So, when the length of the reserved output buffer is more then 256 bytes
(that's the case of tools/pkcs15-crypt),
the APDU is considered as invalid (libopensc/apdu.c +270)

I've tested crypto regression tests -- for me it's OK.


> Regards, Andreas
>  
Kind wishes,
Viktor.

>  
> _______________________________________________
> opensc-devel mailing list
> [hidden email]
> http://www.opensc-project.org/mailman/listinfo/opensc-devel
>
>  


--- src/libopensc/card-oberthur.c       (revision 3120)
+++ src/libopensc/card-oberthur.c       (working copy)
@@ -890,6 +890,10 @@
                ops[4] = SC_AC_OP_PIN_SET;  /* SC_AC_OP_SET_REFERENCE */
                ops[5] = SC_AC_OP_PIN_CHANGE;  /* SC_AC_OP_CHANGE_REFERENCE */
                ops[6] = SC_AC_OP_PIN_RESET;  /* SC_AC_OP_RESET_COUNTER */
+#else
+               ops[4] = SC_AC_OP_LIST_FILES;  /* SC_AC_OP_SET_REFERENCE */
+               ops[5] = SC_AC_OP_LIST_FILES;  /* SC_AC_OP_CHANGE_REFERENCE */
+               ops[6] = SC_AC_OP_LIST_FILES;  /* SC_AC_OP_RESET_COUNTER */
 #endif
        }
        else if (file->type == SC_FILE_TYPE_WORKING_EF)   {
@@ -1148,6 +1152,11 @@
                SC_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Illegal input length");
        }
 
+       if (olen > 256)   {
+               sc_debug(card->ctx, "Output length reduced to 256 bytes");
+               olen = 256;
+       }
+
        sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A);
        apdu.datalen = ilen;
        apdu.data = in;

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Douglas E. Engert


Tarasov Viktor wrote:

> Andreas Jellinghaus a écrit :
>> It would be good to have opensc 0.11.2 soon, so I made another
>> pre-release with current trunk available:
>>
>> http://www.opensc-project.org/files/opensc/testing/
>> http://www.opensc-project.org/files/opensc/testing/opensc-0.11.2-pre4.tar.gz
>>
>> Please test this and give feedback.
>>
>> I'm sorry, currently I find next to no time for opensc.
>>  
> There is a little patch for Oberthur card:
> - some ACLs forgotten;
> - in compute_signature() limit the Le to 256 bytes.

Are you sure that is an error?
It is possible for a card to return data with 61XX indicating there
is more data. The PIV cards can and some of our test cards are Oberthur
but don't use this code.

The original olen is also used in line 1157:
   apdu.resplen = olen;

The fix would be somethiung like line 1154:
   apdu.le = olen > 256 ? 256 : olen;



>
> By the way,
> for some libopensc card drivers, in compute_signature() procedure,
> the output length is assigned to Le of the Compute Signature APDU.
> So, when the length of the reserved output buffer is more then 256 bytes
> (that's the case of tools/pkcs15-crypt),
> the APDU is considered as invalid (libopensc/apdu.c +270)
>
> I've tested crypto regression tests -- for me it's OK.
>
>
>> Regards, Andreas
>>  
> Kind wishes,
> Viktor.
>
>>  
>> _______________________________________________
>> opensc-devel mailing list
>> [hidden email]
>> http://www.opensc-project.org/mailman/listinfo/opensc-devel
>>
>>  
>
>
> ------------------------------------------------------------------------
>
> --- src/libopensc/card-oberthur.c       (revision 3120)
> +++ src/libopensc/card-oberthur.c       (working copy)
> @@ -890,6 +890,10 @@
>                 ops[4] = SC_AC_OP_PIN_SET;  /* SC_AC_OP_SET_REFERENCE */
>                 ops[5] = SC_AC_OP_PIN_CHANGE;  /* SC_AC_OP_CHANGE_REFERENCE */
>                 ops[6] = SC_AC_OP_PIN_RESET;  /* SC_AC_OP_RESET_COUNTER */
> +#else
> +               ops[4] = SC_AC_OP_LIST_FILES;  /* SC_AC_OP_SET_REFERENCE */
> +               ops[5] = SC_AC_OP_LIST_FILES;  /* SC_AC_OP_CHANGE_REFERENCE */
> +               ops[6] = SC_AC_OP_LIST_FILES;  /* SC_AC_OP_RESET_COUNTER */
>  #endif
>         }
>         else if (file->type == SC_FILE_TYPE_WORKING_EF)   {
> @@ -1148,6 +1152,11 @@
>                 SC_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Illegal input length");
>         }
>  
> +       if (olen > 256)   {
> +               sc_debug(card->ctx, "Output length reduced to 256 bytes");
> +               olen = 256;
> +       }
> +
>         sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A);
>         apdu.datalen = ilen;
>         apdu.data = in;
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> opensc-devel mailing list
> [hidden email]
> http://www.opensc-project.org/mailman/listinfo/opensc-devel

--

  Douglas E. Engert  <[hidden email]>
  Argonne National Laboratory
  9700 South Cass Avenue
  Argonne, Illinois  60439
  (630) 252-5444
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Tarasov Viktor
Douglas E. Engert a écrit :

>
>
> Tarasov Viktor wrote:
>> Andreas Jellinghaus a écrit :
>>> It would be good to have opensc 0.11.2 soon, so I made another
>>> pre-release with current trunk available:
>>>
>>> http://www.opensc-project.org/files/opensc/testing/
>>> http://www.opensc-project.org/files/opensc/testing/opensc-0.11.2-pre4.tar.gz
>>>
>>>
>>> Please test this and give feedback.
>>> I'm sorry, currently I find next to no time for opensc.  
>> There is a little patch for Oberthur card:
>> - some ACLs forgotten;
>> - in compute_signature() limit the Le to 256 bytes.
>
> Are you sure that is an error?
> It is possible for a card to return data with 61XX indicating there
> is more data. The PIV cards can and some of our test cards are Oberthur
> but don't use this code.
The reason is in APDU validity checking by sc_check_apdu()
(libopensc/apdu.c +270) .
APDU is invalid, if it's Le value is greater then 256.
As far as I see, now, it concerns incrypto34, cardos, openpgp, ...

>
> The original olen is also used in line 1157:
>   apdu.resplen = olen;
>
> The fix would be somethiung like line 1154:
>   apdu.le = olen > 256 ? 256 : olen;
OK,
in this particular case it doesn't matter,
but I agree, your style will be cleaner.

I've committed to trunk a new version.


Kind wishes,
Viktor.


>
>
>
>>
>> By the way,
>> for some libopensc card drivers, in compute_signature() procedure,
>> the output length is assigned to Le of the Compute Signature APDU.
>> So, when the length of the reserved output buffer is more then 256 bytes
>> (that's the case of tools/pkcs15-crypt),
>> the APDU is considered as invalid (libopensc/apdu.c +270)
>>
>> I've tested crypto regression tests -- for me it's OK.
>>
>>
>>> Regards, Andreas
>>>  
>> Kind wishes,
>> Viktor.
>>
>>>   _______________________________________________
>>> opensc-devel mailing list
>>> [hidden email]
>>> http://www.opensc-project.org/mailman/listinfo/opensc-devel
>>>
>>>  
>>
>>
>> ------------------------------------------------------------------------
>>
>> --- src/libopensc/card-oberthur.c       (revision 3120)
>> +++ src/libopensc/card-oberthur.c       (working copy)
>> @@ -890,6 +890,10 @@
>>                 ops[4] = SC_AC_OP_PIN_SET;  /* SC_AC_OP_SET_REFERENCE */
>>                 ops[5] = SC_AC_OP_PIN_CHANGE;  /*
>> SC_AC_OP_CHANGE_REFERENCE */
>>                 ops[6] = SC_AC_OP_PIN_RESET;  /*
>> SC_AC_OP_RESET_COUNTER */
>> +#else
>> +               ops[4] = SC_AC_OP_LIST_FILES;  /*
>> SC_AC_OP_SET_REFERENCE */
>> +               ops[5] = SC_AC_OP_LIST_FILES;  /*
>> SC_AC_OP_CHANGE_REFERENCE */
>> +               ops[6] = SC_AC_OP_LIST_FILES;  /*
>> SC_AC_OP_RESET_COUNTER */
>>  #endif
>>         }         else if (file->type == SC_FILE_TYPE_WORKING_EF)   {
>> @@ -1148,6 +1152,11 @@
>>                 SC_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
>> "Illegal input length");
>>         }
>>  
>> +       if (olen > 256)   {
>> +               sc_debug(card->ctx, "Output length reduced to 256
>> bytes");
>> +               olen = 256;
>> +       }
>> +
>>         sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E,
>> 0x9A);
>>         apdu.datalen = ilen;
>>         apdu.data = in;
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> opensc-devel mailing list
>> [hidden email]
>> http://www.opensc-project.org/mailman/listinfo/opensc-devel
>

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Nils Larsch
In reply to this post by Douglas E. Engert
Douglas E. Engert wrote:
> One minor change, it looks like the #include "internal.h"
> was removed from pkcs15-piv.c. I can add that back in
> with any other changes you might want.

if it is not needed why included it ?

btw: the patch is imcomplete: at least the compression.c|h
files are missing.

Nils
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Douglas E. Engert


Nils Larsch wrote:
> Douglas E. Engert wrote:
>> One minor change, it looks like the #include "internal.h"
>> was removed from pkcs15-piv.c. I can add that back in
>> with any other changes you might want.
>
> if it is not needed why included it ?

It is needed to get the config.h so it could test for HAVE_ZLIB_H

By the way, every system I have has zlib. And the Windows
Smart Card Bundle also builds with zlib, so what system does not
have it?

>
> btw: the patch is imcomplete: at least the compression.c|h
> files are missing.

OK, I will send them. I sent the patch to the list and to
you the three of you, and it was 41k, over the limit for the
list. Did it get truncated?

Should I atache these to the ticket #128 as files?
>
> Nils
>
>

--

  Douglas E. Engert  <[hidden email]>
  Argonne National Laboratory
  9700 South Cass Avenue
  Argonne, Illinois  60439
  (630) 252-5444
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Andreas Jellinghaus-2
Am Donnerstag, 8. März 2007 00:03 schrieb Douglas E. Engert:
> By the way, every system I have has zlib. And the Windows
> Smart Card Bundle also builds with zlib, so what system does not
> have it?

new users on windows trying to compile it themself.

the scb procedure works, maybe even quite good. but somehow
some people manage to work with the raw source or prefer it that
way (or don't know about scb).

> OK, I will send them. I sent the patch to the list and to
> you the three of you, and it was 41k, over the limit for the
> list. Did it get truncated?

no, that only moderates it and one of us has to approve the
posting. which I did at 41 k (but usualy I don't with > 200k).

> Should I atache these to the ticket #128 as files?

that would work as well.

Regards, Andreas
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Douglas E. Engert
More in Windows and zlib.

Looking at the SCB trunk/Makefile.mak, lines 81-83:

perl -p -e "s/#ZLIB_DEF/ZLIB_DEF/g" -i~ win32\Make.rules.mak
perl -p -e "s/C:\\ZLIB\\INCLUDE/$(DESTP)\\include/g" -i~ win32\Make.rules.mak
perl -p -e "s/C:\\ZLIB\\LIB/$(DESTP)\\lib/g" -i~ win32\Make.rules.mak

I don't see these targets lines in the OpenSC win32\Make.rules/mak

Was there some uncommited change to OpenSC used to build the SCB?
I assume it looks similar to the  OPENSSL_DEF lines in Make.rules.mak.


>
>

--

  Douglas E. Engert  <[hidden email]>
  Argonne National Laboratory
  9700 South Cass Avenue
  Argonne, Illinois  60439
  (630) 252-5444
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Douglas E. Engert
Attached are changes to the win32/Make.rules.mak and
src/libopensc/Makefile.mak to add in the support to compile on Windows
with or without zlib This is similar to method used with OpenSSL already
in the these files. Previous code submissions include the
#ifdef HAVE_ZLIB_H in the source files.

I have compiled with VC 2005 and run on XP with and without zlib, and
the card-piv.c code acts as expected, only able to read a compressed
certificate if compiled with zlib.

(This should also work with the SCB make process, but I did not try it.)

So I hope I have addressed your concerns about being able to
compile with and without zlib on any platform


Thanks.

Douglas E. Engert wrote:

> More in Windows and zlib.
>
> Looking at the SCB trunk/Makefile.mak, lines 81-83:
>
> perl -p -e "s/#ZLIB_DEF/ZLIB_DEF/g" -i~ win32\Make.rules.mak
> perl -p -e "s/C:\\ZLIB\\INCLUDE/$(DESTP)\\include/g" -i~
> win32\Make.rules.mak
> perl -p -e "s/C:\\ZLIB\\LIB/$(DESTP)\\lib/g" -i~ win32\Make.rules.mak
>
> I don't see these targets lines in the OpenSC win32\Make.rules/mak
>
> Was there some uncommited change to OpenSC used to build the SCB?
> I assume it looks similar to the  OPENSSL_DEF lines in Make.rules.mak.
>
>
>>
>>
>
--

  Douglas E. Engert  <[hidden email]>
  Argonne National Laboratory
  9700 South Cass Avenue
  Argonne, Illinois  60439
  (630) 252-5444

Index: win32/Make.rules.mak
===================================================================
--- win32/Make.rules.mak (revision 3124)
+++ win32/Make.rules.mak (working copy)
@@ -21,7 +21,19 @@
 PROGRAMS_OPENSSL = pkcs15-init.exe cryptoflex-tool.exe netkey-tool.exe
 !ENDIF
 
-COPTS = /D_CRT_SECURE_NO_DEPRECATE /Zi /MD /nologo /DHAVE_CONFIG_H /I$(TOPDIR)\src\include /I$(TOPDIR)\src\include\opensc /I$(TOPDIR)\src\common $(OPENSSL_INCL_DIR) $(LIBLTDL_INCL) /D_WIN32_WINNT=0x0400 $(OPENSSL_DEF)
+# If you want support for zlib (Used for PIV, infocamere and actalis:
+# - Download zlib and build
+# - uncomment the line starting with ZLIB_DEF
+# - set the ZLIB_INCL_DIR below to the zlib include lib proceeded by "/I"
+# - set the ZLIB_LIB  below to your zlib lib file
+#ZLIB_DEF = /DHAVE_ZLIB_H
+!IF "$(ZLIB_DEF)" == "/DHAVE_ZLIB_H"
+ZLIB_INCL_DIR = /IC:\ZLIB\INCLUDE
+ZLIB_LIB = C:\ZLIB\LIB\zlib.lib
+!ENDIF
+
+
+COPTS = /D_CRT_SECURE_NO_DEPRECATE /Zi /MD /nologo /DHAVE_CONFIG_H /I$(TOPDIR)\src\include /I$(TOPDIR)\src\include\opensc /I$(TOPDIR)\src\common $(OPENSSL_INCL_DIR) $(ZLIB_INCL_DIR) $(LIBLTDL_INCL) /D_WIN32_WINNT=0x0400 $(OPENSSL_DEF) $(ZLIB_DEF)
 LINKFLAGS = /DEBUG /NOLOGO /INCREMENTAL:NO /MACHINE:IX86
 
 
Index: src/libopensc/Makefile.mak
===================================================================
--- src/libopensc/Makefile.mak (revision 3124)
+++ 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 \
@@ -43,5 +44,5 @@
 
 $(TARGET): $(OBJECTS) ..\scconf\scconf.lib ..\common\common.lib
  perl $(TOPDIR)\win32\makedef.pl $*.def $* $(OBJECTS)
- link $(LINKFLAGS) /dll /def:$*.def /implib:$*.lib /out:$(TARGET) $(OBJECTS) ..\scconf\scconf.lib ..\common\common.lib winscard.lib $(OPENSSL_LIB) gdi32.lib $(LIBLTDL_LIB) advapi32.lib ws2_32.lib
+ link $(LINKFLAGS) /dll /def:$*.def /implib:$*.lib /out:$(TARGET) $(OBJECTS) ..\scconf\scconf.lib ..\common\common.lib winscard.lib $(OPENSSL_LIB) $(ZLIB_LIB) gdi32.lib $(LIBLTDL_LIB) advapi32.lib ws2_32.lib
  if EXIST $(TARGET).manifest mt -manifest $(TARGET).manifest -outputresource:$(TARGET);2

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Martin Paljak-2
In reply to this post by Andreas Jellinghaus-2
On 08.03.2007, at 9:06, Andreas Jellinghaus wrote:
> new users on windows trying to compile it themself.
New *users* on windows should be directed cleanly and clearly to pre-
compiled solutions.

> the scb procedure works, maybe even quite good. but somehow
> some people manage to work with the raw source or prefer it that
> way (or don't know about scb).
New *developers* need also documentation and usually can either pick  
up from SCB or learn how to fulfill the requirement of 'zlib is  
required'.

m.
--
Martin Paljak


_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: new pre release for 0.11.2 available

Martin Paljak-2
In reply to this post by Andreas Jellinghaus-2
On 06.03.2007, at 0:05, Andreas Jellinghaus wrote:
> It would be good to have opensc 0.11.2 soon, so I made another
> pre-release with current trunk available:

It would be really good - especially becuase due to lack of time a  
year ago 0.11.1 has a regression that renders 0.11.1 linux packages  
unusable for Estonian eID ( changeset [3010] fixes that again)

> Please test this and give feedback.

All is nice but I'd like to have a small enhancement in 0.11.2 that  
has been available for .ee users for some time already. Please see  
#132. IMHO that ticket should not affect current situation and opensc  
users but improves some user experience scenarios a lot.

m.
--
Martin Paljak


_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
123