Ticket #128: new_piv.patch
| File new_piv.patch, 54.8 KB (added by harningt, 2 years ago) |
|---|
-
src/libopensc/compression.c
1 /* 2 * compression.c: Generic wrapper for compression of data 3 * 4 * Copyright (C) 2006, Identity Alliance, Thomas Harning <thomas.harning@identityalliance.com> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 #include "compression.h" 21 22 #include <zlib.h> 23 #include <memory.h> 24 #include <stdlib.h> 25 #include "errors.h" 26 27 static int zerr_to_opensc(int err) { 28 switch(err) { 29 case Z_OK: 30 case Z_STREAM_END: 31 return SC_SUCCESS; 32 case Z_UNKNOWN: 33 return SC_ERROR_UNKNOWN; 34 case Z_BUF_ERROR: 35 case Z_MEM_ERROR: 36 return SC_ERROR_MEMORY_FAILURE; 37 case Z_VERSION_ERROR: 38 case Z_DATA_ERROR: 39 case Z_STREAM_ERROR: 40 //case Z_NEED_DICT: 41 default: 42 return SC_ERROR_INTERNAL; 43 } 44 } 45 static int detect_method(const u8* in, size_t inLen) { 46 if(inLen > 2 && in[0] == 0x1f && in[1] == 0x8b) { /* GZIP */ 47 return COMPRESSION_GZIP; 48 } else if(inLen > 1 /*&& (in[0] & 0x10) == Z_DEFLATED*/) { 49 /* REALLY SIMPLE ZLIB TEST -- 50 * Check for the compression method to be set to 8... 51 * many things can spoof this, but this is ok for now 52 * */ 53 return COMPRESSION_ZLIB; 54 } else { 55 return COMPRESSION_UNKNOWN; 56 } 57 } 58 59 static int do_decompress_gzip(u8* out, size_t* outLen, const u8* in, size_t inLen) { 60 /* Since uncompress does not offer a way to make it uncompress gzip... manually set it up */ 61 z_stream gz; 62 int err; 63 int window_size = 15 + 0x20; 64 memset(&gz, 0, sizeof(gz)); 65 66 gz.next_in = (u8*)in; 67 gz.avail_in = inLen; 68 gz.next_out = out; 69 gz.avail_out = *outLen; 70 71 err = inflateInit2(&gz, window_size); 72 if(err != Z_OK) return zerr_to_opensc(err); 73 err = inflate(&gz, Z_FINISH); 74 if(err != Z_STREAM_END) { 75 inflateEnd(&gz); 76 return zerr_to_opensc(err); 77 } 78 *outLen = gz.total_out; 79 80 err = inflateEnd(&gz); 81 return zerr_to_opensc(err); 82 } 83 84 int do_decompress(u8* out, size_t* outLen, const u8* in, size_t inLen, int method) { 85 if(method == COMPRESSION_AUTO) { 86 method = detect_method(in, inLen); 87 if(method == COMPRESSION_UNKNOWN) { 88 return SC_ERROR_UNKNOWN_DATA_RECEIVED; 89 } 90 } 91 switch(method) { 92 case COMPRESSION_ZLIB: 93 return zerr_to_opensc(uncompress(out, outLen, in, inLen)); 94 case COMPRESSION_GZIP: 95 return do_decompress_gzip(out, outLen, in, inLen); 96 default: 97 return SC_ERROR_INVALID_ARGUMENTS; 98 } 99 } 100 101 static int do_decompress_zlib_alloc(u8** out, size_t* outLen, const u8* in, size_t inLen, int gzip) { 102 /* Since uncompress does not offer a way to make it uncompress gzip... manually set it up */ 103 z_stream gz; 104 int err; 105 int window_size = 15; 106 const int startSize = inLen < 1024 ? 2048 : inLen * 2; 107 const int blockSize = inLen < 1024 ? 512 : inLen / 2; 108 int bufferSize = startSize; 109 if(gzip) 110 window_size += 0x20; 111 memset(&gz, 0, sizeof(gz)); 112 113 gz.next_in = (u8*)in; 114 gz.avail_in = inLen; 115 116 err = inflateInit2(&gz, window_size); 117 if(err != Z_OK) return zerr_to_opensc(err); 118 119 *outLen = 0; 120 121 while(1) { 122 /* Setup buffer... */ 123 int num; 124 u8* buf = realloc(*out, bufferSize); 125 if(!buf) { 126 if(*out) 127 free(*out); 128 *out = NULL; 129 return Z_MEM_ERROR; 130 } 131 *out = buf; 132 gz.next_out = buf + *outLen; 133 gz.avail_out = bufferSize - *outLen; 134 135 err = inflate(&gz, Z_FULL_FLUSH); 136 if(err != Z_STREAM_END && err != Z_OK) { 137 if(*out) 138 free(*out); 139 *out = NULL; 140 break; 141 } 142 num = bufferSize - *outLen - gz.avail_out; 143 if(num > 0) { 144 *outLen += num; 145 bufferSize += num + blockSize; 146 } 147 if(err == Z_STREAM_END) { 148 buf = realloc(buf, *outLen); /* Shrink it down, if it fails, just use old data */ 149 if(buf) { 150 *out = buf; 151 } 152 break; 153 } 154 } 155 inflateEnd(&gz); 156 return zerr_to_opensc(err); 157 } 158 int do_decompress_alloc(u8** out, size_t* outLen, const u8* in, size_t inLen, int method) { 159 if(method == COMPRESSION_AUTO) { 160 method = detect_method(in, inLen); 161 if(method == COMPRESSION_UNKNOWN) { 162 return SC_ERROR_UNKNOWN_DATA_RECEIVED; 163 } 164 } 165 switch(method) { 166 case COMPRESSION_ZLIB: 167 return do_decompress_zlib_alloc(out, outLen, in, inLen, 0); 168 case COMPRESSION_GZIP: 169 return do_decompress_zlib_alloc(out, outLen, in, inLen, 1); 170 default: 171 return SC_ERROR_INVALID_ARGUMENTS; 172 } 173 } -
src/libopensc/card-piv.c
4 4 * 5 5 * Copyright (C) 2001, 2002 Juha YrjölÀ <juha.yrjola@iki.fi> 6 6 * Copyright (C) 2005, Douglas E. Engert <deengert@anl.gov> 7 * Copyright (C) 2006, Identity Alliance, Thomas Harning <thomas.harning@identityalliance.com> 7 8 * 8 9 * This library is free software; you can redistribute it and/or 9 10 * modify it under the terms of the GNU Lesser General Public … … 29 30 #include <openssl/rsa.h> 30 31 #include "asn1.h" 31 32 #include "cardctl.h" 33 #include "compression.h" 32 34 33 struct piv_private_data { 35 typedef struct { 36 u8* data; 37 size_t length; 38 int enumtag; 39 } piv_cache_item; 40 41 typedef struct piv_private_data { 34 42 struct sc_pin_cmd_pin pin_info; 35 43 sc_file_t *aid_file; 36 44 int enumtag; … … 39 47 size_t max_recv_size; /* saved size, need to lie to pkcs15_read_file */ 40 48 size_t max_send_size; 41 49 int key_ref; /* saved from set_security_env and */ 42 int alg_id; /* used in decrypy, signature */ 43 }; 50 int alg_id; /* used in decrypt, signature */ 51 piv_cache_item* cache; 52 int cacheLen; 53 piv_cache_item* current_item; 54 } piv_private_data_t; 44 55 56 #define PIV_DATA(card) ((piv_private_data_t*)card->drv_data) 57 58 static int add_cache_item(piv_private_data_t* priv, int enumtag, u8* data, size_t length) { 59 int idx, len = priv->cacheLen; 60 piv_cache_item* cache = priv->cache; 61 for(idx = 0; idx < len; idx++) { 62 if(!cache[idx].data) 63 break; 64 if(cache[idx].enumtag == enumtag) /* Found matching tag */ 65 break; 66 } 67 if(idx == len) 68 return -1; /* FAILED NO FREE ROOM */ 69 if(cache[idx].data) 70 free(cache[idx].data); 71 cache[idx].data = data; 72 cache[idx].length = length; 73 cache[idx].enumtag = enumtag; 74 return 0; 75 } 76 77 static piv_cache_item* get_cache_item(piv_private_data_t* priv, int enumtag) { 78 int idx, len = priv->cacheLen; 79 piv_cache_item* cache = priv->cache; 80 for(idx = 0; idx < len; idx++) { 81 if(cache[idx].enumtag == enumtag) 82 return &cache[idx]; 83 } 84 return NULL; 85 } 86 87 static void free_cache_items(piv_private_data_t* priv) { 88 int idx, len = priv->cacheLen; 89 piv_cache_item* cache = priv->cache; 90 for(idx = 0; idx < len; idx++) { 91 if(cache[idx].data) { 92 free(cache[idx].data); 93 cache[idx].data = NULL; 94 } 95 } 96 } 97 45 98 struct piv_aid { 46 99 int enumtag; 47 100 size_t len_short; /* min lenght without version */ … … 71 124 PIV_OBJ_X509_CARD_AUTH, 72 125 PIV_OBJ_SEC_OBJ, 73 126 PIV_OBJ_9B03, 74 PIV_OBJ_9A06 127 PIV_OBJ_9A06, 128 PIV_CACHE_SIZE 75 129 }; 76 130 77 131 struct piv_object { … … 88 142 { PIV_OBJ_CCC, "Card Capability Container", 89 143 "2.16.840.1.101.3.7.1.219.0", 3, "\x5F\xC1\x07", "\xDB\x00", 266}, 90 144 { PIV_OBJ_CHUI, "Card Holder Unique Identifier", 91 "2.16.840.1.101.3.7.2.48.0", 3, "\x5F\xC1\x02", "\x30\x00", 337 7},145 "2.16.840.1.101.3.7.2.48.0", 3, "\x5F\xC1\x02", "\x30\x00", 3379}, /* Updated per SP800-73-1 Errata */ 92 146 { PIV_OBJ_X509_PIV_AUTH, "X.509 Certificate for PIV Authentication", 93 147 "2.16.840.1.101.3.7.2.1.1", 3, "\x5F\xC1\x05", "\x01\x01", 1856+4+400} , 94 148 /* extra 400 is hack for MultOS card which returns 2200 bytes */ 95 { PIV_OBJ_CHF1, "Card Holder Fingerprint I", 96 "2.16.840.1.101.3.7.2.96.16", 3, "\x5F\xC1\x03", "\x60\x01", 7768}, 97 { PIV_OBJ_CHF2, "Card Holder Fingerprint II", 98 "2.16.840.1.101.3.7.2.96.17", 3, "\x5F\xC1\x04", "\x60\x11", 7768}, 149 { PIV_OBJ_CHF1, "Card Holder Fingerprints", 150 "2.16.840.1.101.3.7.2.96.16", 3, "\x5F\xC1\x03", "\x60\x10", 7768}, 99 151 { PIV_OBJ_PI, "Printed Information", 100 152 "2.16.840.1.101.3.7.2.48.1", 3, "\x5F\xC1\x09", "\x30\x01", 106}, 101 153 { PIV_OBJ_CHFI, "Card Holder Facial Image", … … 184 236 const u8 * sendbuf, size_t sendbuflen, u8 ** recvbuf, 185 237 size_t * recvbuflen) 186 238 { 187 struct piv_private_data * priv = (struct piv_private_data *) card->drv_data;239 piv_private_data_t * priv = PIV_DATA(card); 188 240 int r; 189 241 sc_apdu_t apdu; 190 242 u8 rbufinitbuf[20000]; /* crude way to do this see above comments */ … … 502 554 static int piv_get_data(sc_card_t * card, unsigned int enumtag, 503 555 u8 **buf, size_t *buf_len) 504 556 { 505 struct piv_private_data * priv = (struct piv_private_data *) card->drv_data;557 piv_private_data_t * priv = PIV_DATA(card); 506 558 u8 *p; 507 559 int r = 0; 508 560 u8 tagbuf[8]; 509 561 size_t tag_len; 510 562 511 563 SC_FUNC_CALLED(card->ctx,1); 512 564 sc_debug(card->ctx, "get_data: tag=%d \n", enumtag); 513 565 … … 599 651 600 652 SC_FUNC_RETURN(card->ctx, 1, r); 601 653 } 602 654 655 656 static int piv_handle_certificate_data(sc_card_t *card, 657 int enumtag, 658 unsigned idx, u8* buf, size_t count, 659 u8* data, size_t length) { 660 piv_private_data_t * priv = PIV_DATA(card); 661 u8* tag; 662 size_t taglen; 663 int compressed = 0; 664 piv_cache_item* item; 665 /* get the certificate out */ 666 tag = (u8 *) sc_asn1_find_tag(card->ctx, data, length, 0x71, &taglen); 667 if (tag && (((*tag) & 0x80) || ((*tag) & 0x01))) { 668 compressed = 1; 669 } 670 tag = (u8 *) sc_asn1_find_tag(card->ctx, data, length, 0x70, &taglen); 671 if (tag == NULL) { 672 return SC_ERROR_OBJECT_NOT_VALID; 673 } 674 /* Potential truncation */ 675 if(compressed) { 676 size_t len = count; 677 u8* newBuf = NULL; 678 if(SC_SUCCESS != do_decompress_alloc(&newBuf, &len, tag, taglen, COMPRESSION_AUTO)) { 679 return SC_ERROR_OBJECT_NOT_VALID; 680 } else { 681 if(len < count + idx) 682 count = len - idx; 683 if(count <= 0) 684 return 0; 685 memcpy(buf, newBuf + idx, count); 686 if(0 != add_cache_item(priv, enumtag, newBuf, len)) { 687 /* Failed to cache item */ 688 free(newBuf); 689 } 690 priv->current_item = get_cache_item(priv, enumtag); 691 } 692 return count; 693 } 694 if(taglen < count + idx) 695 count = taglen - idx; 696 if(count <= 0) 697 return 0; 698 memcpy(buf, tag, count); 699 if(0 == add_cache_item(priv, enumtag, NULL, 0)) { 700 /* Space available in the cache array, use it */ 701 item = get_cache_item(priv, enumtag); 702 if(item) { 703 item->data = malloc(taglen); 704 if(item->data) { 705 item->length = taglen; 706 memcpy(item->data, tag, taglen); 707 } 708 priv->current_item = item; 709 } 710 } 711 return count; 712 } 713 714 static int piv_handle_data(sc_card_t *card, int enumtag, 715 unsigned idx, u8* buf, size_t count, u8* data, size_t length) { 716 /* For now get the first tag, and return the data */ 717 piv_private_data_t * priv = PIV_DATA(card); 718 u8* tag; 719 size_t taglen; 720 piv_cache_item* item; 721 722 tag = (u8 *) sc_asn1_find_tag(card->ctx, data, length, *data, &taglen); 723 if (tag == NULL) { 724 return SC_ERROR_OBJECT_NOT_VALID; 725 } 726 if(taglen < count + idx) 727 count = taglen - idx; 728 if(count <= 0) 729 return 0; 730 memcpy(buf, tag + idx, count); 731 if(0 == add_cache_item(priv, enumtag, NULL, 0)) { 732 item = get_cache_item(priv, enumtag); 733 if(item) { 734 item->data = malloc(taglen); 735 if(item->data) { 736 item->length = taglen; 737 memcpy(item->data, tag, taglen); 738 } 739 priv->current_item = item; 740 } 741 } 742 return count; 743 } 603 744 /* 604 745 * Callers of this are expecting a file without tags, 605 746 * So we need to know what type of file this is, so we can get the … … 609 750 static int piv_read_binary(sc_card_t *card, unsigned int idx, 610 751 unsigned char *buf, size_t count, unsigned long flags) 611 752 { 612 struct piv_private_data * priv = (struct piv_private_data *) card->drv_data; 753 piv_private_data_t * priv = PIV_DATA(card); 754 piv_cache_item* item = NULL; 755 int enumtag; 613 756 int r; 614 757 u8 *rbuf = NULL; 615 758 size_t rbuflen = 0; 616 u8 *tag;617 size_t taglen;618 759 u8 *body; 619 760 size_t bodylen; 620 761 621 762 SC_FUNC_CALLED(card->ctx,1); 622 763 if (priv->selected_obj < 0) 623 764 SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INTERNAL); 765 enumtag = piv_objects[priv->selected_obj].enumtag; 624 766 767 /* Hit the cache */ 768 if(priv->current_item) { 769 item = priv->current_item; 770 if(idx + count > item->length) { 771 count = item->length - idx; 772 } 773 if(count <= 0) 774 return 0; 775 memcpy(buf, item->data + idx, count); 776 return count; 777 } 778 625 779 if (priv->eof == 1) 626 780 return 0; 627 781 … … 629 783 630 784 if (r >=0) { 631 785 /* if tag is 0, assume card is telling us no object on card */ 632 if ( rbuf[0] == '0') {786 if (!rbuf || rbuf[0] == '0') { 633 787 r = SC_ERROR_FILE_NOT_FOUND; 634 788 goto err; 635 789 } … … 639 793 /* if missing, assume its the body */ 640 794 /* DEE bug in the beta card */ 641 795 sc_debug(card->ctx," ***** tag 0x53 MISSING \n"); 642 body = rbuf;643 bodylen = rbuflen;644 #if 0645 796 r = SC_ERROR_INVALID_DATA; 646 797 goto err; 647 #endif648 798 } 649 switch ( piv_objects[priv->selected_obj].enumtag) {799 switch (enumtag) { 650 800 case PIV_OBJ_X509_PIV_AUTH: 651 801 case PIV_OBJ_X509_DS: 652 802 case PIV_OBJ_X509_KM: 653 803 case PIV_OBJ_X509_CARD_AUTH: 654 /* get the certificate out */ 655 tag = (u8 *) sc_asn1_find_tag(card->ctx, body, bodylen, 0x70, &taglen); 656 if (tag == NULL) { 657 r = SC_ERROR_OBJECT_NOT_VALID; 658 break; 659 } 660 memcpy(buf, tag, taglen); /*DEE should check lengths */ 661 r = taglen; 662 tag = (u8 *) sc_asn1_find_tag(card->ctx, body, bodylen, 0x71, &taglen); 663 if (tag && ((*tag) & 0x80)) { 664 sc_debug(card->ctx,0,"Cert is gziped! %0x2.2x\n",*tag); 665 } 804 r = piv_handle_certificate_data(card, enumtag, idx, buf, count, body, bodylen); 666 805 break; 667 806 default: 668 /* For now get the first tag, and return the data */ 669 tag = (u8 *) sc_asn1_find_tag(card->ctx, body, bodylen, *body, &taglen); 670 if (tag == NULL) { 671 r = SC_ERROR_OBJECT_NOT_VALID; 672 break; 673 } 674 memcpy(buf, tag, taglen); /*DEE should check lengths */ 675 r = taglen; 807 r = piv_handle_data(card, enumtag, idx, buf, count, body, bodylen); 676 808 break; 677 809 } 678 810 } … … 720 852 SC_FUNC_RETURN(card->ctx, 1, r); 721 853 } 722 854 855 static int piv_write_certificate(sc_card_t *card, 856 unsigned idx, const u8* buf, size_t count) { 857 piv_private_data_t * priv = PIV_DATA(card); 858 int r = SC_SUCCESS; 859 u8 *sbuf = NULL; 860 u8 *p; 861 size_t sbuflen; 862 size_t taglen; 723 863 864 sc_debug(card->ctx,"DEE cert len=%d",count); 865 taglen = put_tag_and_len(0x70, count, NULL) 866 + put_tag_and_len(0x71, 1, NULL); 867 868 sbuflen = put_tag_and_len(0x53, taglen, NULL); 869 870 sbuf = (u8*) malloc(sbuflen); 871 if (sbuf == NULL) 872 SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_OUT_OF_MEMORY); 873 p = sbuf; 874 put_tag_and_len(0x53, taglen, &p); 875 876 put_tag_and_len(0x70, count, &p); 877 memcpy(p, buf, count); 878 p += count; 879 put_tag_and_len(0x71, 1, &p); 880 *p++ = 0x00; /* certinfo, i.e. not gziped */ 881 sc_debug(card->ctx,"DEE buf %p len %d %d", sbuf, p -sbuf, sbuflen); 882 883 r = piv_put_data(card, priv->selected_obj, sbuf, sbuflen); 884 if (sbuf) 885 free(sbuf); 886 887 return r; 888 } 724 889 /* 725 890 * We need to add the 0x53 tag and other specific tags, 726 891 * and call the piv_put_data … … 730 895 static int piv_write_binary(sc_card_t *card, unsigned int idx, 731 896 const u8 *buf, size_t count, unsigned long flags) 732 897 { 733 struct piv_private_data * priv = (struct piv_private_data *) card->drv_data; 734 int r = 0; 735 u8 *sbuf = NULL; 736 u8 *p; 737 size_t sbuflen; 738 size_t taglen; 739 898 piv_private_data_t * priv = PIV_DATA(card); 899 /* TODO: Add cache hooks */ 740 900 SC_FUNC_CALLED(card->ctx,1); 741 901 742 902 if (priv->selected_obj < 0) … … 749 909 case PIV_OBJ_X509_DS: 750 910 case PIV_OBJ_X509_KM: 751 911 case PIV_OBJ_X509_CARD_AUTH: 752 sc_debug(card->ctx,"DEE cert len=%d",count); 753 754 taglen = put_tag_and_len(0x70, count, NULL) 755 + put_tag_and_len(0x71, 1, NULL); 756 757 sbuflen = put_tag_and_len(0x53, taglen, NULL); 758 759 sbuf = (u8*) malloc(sbuflen); 760 if (sbuf == NULL) 761 SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_OUT_OF_MEMORY); 762 p = sbuf; 763 put_tag_and_len(0x53, taglen, &p); 764 765 put_tag_and_len(0x70, count, &p); 766 memcpy(p, buf, count); 767 p += count; 768 put_tag_and_len(0x71, 1, &p); 769 *p++ = 0x00; /* certinfo, i.e. not gziped */ 770 sc_debug(card->ctx,"DEE buf %p len %d %d", sbuf, p -sbuf, sbuflen); 771 break; 772 912 SC_FUNC_RETURN(card->ctx, 1, piv_write_certificate(card, idx, buf, count)); 773 913 default: 774 914 sc_debug(card->ctx, "Don't know how to write object %s\n", 775 915 piv_objects[priv->selected_obj].name); 776 r = SC_ERROR_NOT_SUPPORTED; 777 break; 916 SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); 778 917 } 779 780 if (r == 0)781 r = piv_put_data(card, priv->selected_obj, sbuf, sbuflen);782 if (sbuf)783 free(sbuf);784 785 SC_FUNC_RETURN(card->ctx, 1, r);786 918 } 787 919 788 920 /* … … 955 1087 static int piv_general_external_authenticate(sc_card_t *card, 956 1088 unsigned int key_ref, unsigned int alg_id) 957 1089 { 958 struct piv_private_data * priv = (struct piv_private_data *) card->drv_data;1090 piv_private_data_t * priv = PIV_DATA(card); 959 1091 int r; 960 1092 u8 *rbuf = NULL; 961 1093 size_t rbuflen; … … 1049 1181 return piv_generate_key(card, 1050 1182 (struct sc_cardctl_cryptoflex_genkey_info *) ptr); 1051 1183 break; 1184 case SC_CARDCTL_PIV_GET_FULL_DATA: { 1185 int ret; 1186 piv_private_data_t * priv = PIV_DATA(card); 1187 sc_cardctl_piv_get_full_data_t* data = (sc_cardctl_piv_get_full_data_t*)ptr; 1188 /* Clear out the data so that failure returns leave data in a clean state */ 1189 memset(data, 0, sizeof(sc_cardctl_piv_get_full_data_t)); 1190 /* Make sure the cache item is fresh */ 1191 { 1192 /* In order for sc_read_binary to actually call into the card, 1 byte must be read... */ 1193 u8 buf[1]; 1194 ret = sc_read_binary(card, 0, buf, 1, 0); 1195 if(ret < 0) return ret; 1196 } 1197 /* No cached item or the cached item is forcibly marked as non-existent */ 1198 if(!priv->current_item || priv->current_item->length == -1) 1199 return SC_ERROR_FILE_NOT_FOUND; 1200 data->buf = priv->current_item->data; 1201 data->length = priv->current_item->length; 1202 data->should_free = 0; 1203 return SC_SUCCESS; 1204 } 1052 1205 } 1053 1206 1054 1207 return SC_ERROR_NOT_SUPPORTED; … … 1108 1261 const sc_security_env_t *env, 1109 1262 int se_num) 1110 1263 { 1111 struct piv_private_data * priv = (struct piv_private_data*) card->drv_data;1264 piv_private_data_t * priv = (piv_private_data_t *) card->drv_data; 1112 1265 1113 1266 SC_FUNC_CALLED(card->ctx,1); 1114 1267 … … 1138 1291 const u8 * data, size_t datalen, 1139 1292 u8 * out, size_t outlen) 1140 1293 { 1141 struct piv_private_data * priv = (struct piv_private_data*) card->drv_data;1294 piv_private_data_t * priv = (piv_private_data_t *) card->drv_data; 1142 1295 int r; 1143 1296 u8 *p; 1144 1297 u8 *tag; … … 1227 1380 static int piv_select_file(sc_card_t *card, const sc_path_t *in_path, 1228 1381 sc_file_t **file_out) 1229 1382 { 1230 str
