Hi,
I propose the attached patch for iso7816.c.

It looks like your patch is correct (according to ISO 7816-4 2003,
page 54, 7.5.11 MANAGE SECURITY ENVIRONMENT command)

Any objection from other list members?

almost every card driver has it's own set_security_env implementation,
so this change will not break any card, so it looks good to me.

maybe we can obsolete some of those card specific implementations,
if the only difference was this value?

Thanks
diff -u -r opensc-trunk-r3695/src/libopensc/iso7816.c 
new/opensc-trunk-r3695/src/libopensc/iso7816.c
--- opensc-trunk-r3695/src/libopensc/iso7816.c  2008-12-27 19:15:30.000000000 
+0300
+++ new/opensc-trunk-r3695/src/libopensc/iso7816.c      2009-06-23 
15:46:32.000000000 +0400
@@ -449,7 +449,7 @@
        } else {
                apdu.resplen = 0;
                apdu.le = 0;
-               apdu.cse = SC_APDU_CASE_3_SHORT;
+               apdu.cse = (apdu.lc == 0) ? SC_APDU_CASE_1 : 
SC_APDU_CASE_3_SHORT;
        }
        r = sc_transmit_apdu(card, &apdu);
        SC_TEST_RET(card->ctx, r, "APDU transmit failed");
@@ -463,6 +463,8 @@
        if (r)
                SC_FUNC_RETURN(card->ctx, 2, r);
 
+       if (apdu.resplen <= 1)
+               SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_UNKNOWN_DATA_RECEIVED);
        switch (apdu.resp[0]) {
        case 0x6F:
                file = sc_file_new();
@@ -473,7 +475,7 @@
                        sc_file_free(file);
                        SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
                }
-               if (apdu.resp[1] <= apdu.resplen)
+               if ((size_t)apdu.resp[1] + 2 <= apdu.resplen)
                        card->ops->process_fci(card, file, apdu.resp+2, 
apdu.resp[1]);
                *file_out = file;
                break;
@@ -519,17 +521,21 @@
 {
        u8 *p = out;
        u8 buf[64];
-       
+
+       if (*outlen < 2)
+               return SC_ERROR_BUFFER_TOO_SMALL;
        *p++ = 0x6F;
        p++;
        
        buf[0] = (file->size >> 8) & 0xFF;
        buf[1] = file->size & 0xFF;
-       sc_asn1_put_tag(0x81, buf, 2, p, 16, &p);
+       sc_asn1_put_tag(0x81, buf, 2, p, *outlen - (p - out), &p);
 
        if (file->type_attr_len) {
+               assert(sizeof(buf) >= file->type_attr_len);
                memcpy(buf, file->type_attr, file->type_attr_len);
-               sc_asn1_put_tag(0x82, buf, file->type_attr_len, p, 16, &p);
+               sc_asn1_put_tag(0x82, buf, file->type_attr_len,
+                               p, *outlen - (p - out), &p);
        } else {
                buf[0] = file->shareable ? 0x40 : 0;
                switch (file->type) {
@@ -544,19 +550,23 @@
                default:
                        return SC_ERROR_NOT_SUPPORTED;
                }
-               sc_asn1_put_tag(0x82, buf, 1, p, 16, &p);
+               sc_asn1_put_tag(0x82, buf, 1, p, *outlen - (p - out), &p);
        }
        buf[0] = (file->id >> 8) & 0xFF;
        buf[1] = file->id & 0xFF;
-       sc_asn1_put_tag(0x83, buf, 2, p, 16, &p);
+       sc_asn1_put_tag(0x83, buf, 2, p, *outlen - (p - out), &p);
        /* 0x84 = DF name */
        if (file->prop_attr_len) {
+               assert(sizeof(buf) >= file->prop_attr_len);
                memcpy(buf, file->prop_attr, file->prop_attr_len);
-               sc_asn1_put_tag(0x85, buf, file->prop_attr_len, p, 18, &p);
+               sc_asn1_put_tag(0x85, buf, file->prop_attr_len,
+                               p, *outlen - (p - out), &p);
        }
        if (file->sec_attr_len) {
+               assert(sizeof(buf) >= file->sec_attr_len);
                memcpy(buf, file->sec_attr, file->sec_attr_len);
-               sc_asn1_put_tag(0x86, buf, file->sec_attr_len, p, 18, &p);
+               sc_asn1_put_tag(0x86, buf, file->sec_attr_len,
+                               p, *outlen - (p - out), &p);
        }
        out[1] = p - out - 2;
 
@@ -664,14 +674,12 @@
        int r, locked = 0;
 
        assert(card != NULL && env != NULL);
-       sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0);
+       sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0);
        switch (env->operation) {
        case SC_SEC_OPERATION_DECIPHER:
-               apdu.p1 = 0x81;
                apdu.p2 = 0xB8;
                break;
        case SC_SEC_OPERATION_SIGN:
-               apdu.p1 = 0x41;
                apdu.p2 = 0xB6;
                break;
        default:
@@ -687,6 +695,7 @@
        if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) {
                *p++ = 0x81;
                *p++ = env->file_ref.len;
+               assert(sizeof(sbuf) - (p - sbuf) >= env->file_ref.len);
                memcpy(p, env->file_ref.value, env->file_ref.len);
                p += env->file_ref.len;
        }
@@ -696,6 +705,7 @@
                else
                        *p++ = 0x84;
                *p++ = env->key_ref_len;
+               assert(sizeof(sbuf) - (p - sbuf) >= env->key_ref_len);
                memcpy(p, env->key_ref, env->key_ref_len);
                p += env->key_ref_len;
        }
@@ -1024,3 +1034,4 @@
 {
        return &iso_driver;
 }
+
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to