- fixed endianness problem with encoding/deconding of bit fields

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@1034 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
okir 2003-04-16 20:52:26 +00:00
parent 897e4a87ca
commit 98907b68f1
6 changed files with 69 additions and 14 deletions

View File

@ -469,6 +469,52 @@ static int encode_bit_string(const u8 * inbuf, size_t bits_left, u8 **outbuf,
return 0;
}
/*
* Bitfields are just bit strings, stored in an unsigned int
* (taking endianness into account)
*/
static int decode_bit_field(const u8 * inbuf, size_t inlen, void *outbuf, size_t outlen)
{
u8 data[sizeof(unsigned int)];
unsigned int field = 0;
int i, n;
if (outlen != sizeof(data))
return SC_ERROR_BUFFER_TOO_SMALL;
n = decode_bit_string(inbuf, inlen, data, sizeof(data), 1);
if (n < 0)
return n;
for (i = 0; i < n; i += 8) {
field |= (data[i/8] << i);
}
memcpy(outbuf, &field, outlen);
return 0;
}
static int encode_bit_field(const u8 *inbuf, size_t inlen,
u8 **outbuf, size_t *outlen)
{
u8 data[sizeof(unsigned int)];
unsigned int field = 0;
int i, bits;
if (inlen != sizeof(data))
return SC_ERROR_BUFFER_TOO_SMALL;
/* count the bits */
memcpy(&field, inbuf, inlen);
for (bits = 0; field; bits++)
field >>= 1;
memcpy(&field, inbuf, inlen);
for (i = 0; i < bits; i += 8)
data[i/8] = field >> i;
return encode_bit_string(data, bits, outbuf, outlen, 1);
}
int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out)
{
int i, a = 0;
@ -763,15 +809,15 @@ static int asn1_encode_p15_object(struct sc_context *ctx, const struct sc_asn1_p
int r;
const struct sc_pkcs15_object *p15_obj = obj->p15_obj;
struct sc_asn1_entry asn1_c_attr[6], asn1_p15_obj[5];
size_t flags_len;
size_t label_len = strlen(p15_obj->label);
size_t flags_len;
sc_copy_asn1_entry(c_asn1_com_obj_attr, asn1_c_attr);
sc_copy_asn1_entry(c_asn1_p15_obj, asn1_p15_obj);
if (label_len != 0)
sc_format_asn1_entry(asn1_c_attr + 0, (void *) p15_obj->label, &label_len, 1);
if (p15_obj->flags) {
flags_len = _sc_count_bit_string_size(&p15_obj->flags, sizeof(p15_obj->flags));
flags_len = sizeof(p15_obj->flags);
sc_format_asn1_entry(asn1_c_attr + 1, (void *) &p15_obj->flags, &flags_len, 1);
}
if (p15_obj->auth_id.len)
@ -860,6 +906,10 @@ static int asn1_decode_entry(struct sc_context *ctx, struct sc_asn1_entry *entry
}
}
break;
case SC_ASN1_BIT_FIELD:
if (parm != NULL)
r = decode_bit_field(obj, objlen, (u8 *) parm, *len);
break;
case SC_ASN1_OCTET_STRING:
if (parm != NULL) {
int c;
@ -1113,6 +1163,10 @@ static int asn1_encode_entry(struct sc_context *ctx, const struct sc_asn1_entry
else
r = encode_bit_string((const u8 *) parm, *len, &buf, &buflen, 0);
break;
case SC_ASN1_BIT_FIELD:
assert(len != NULL);
r = encode_bit_field((const u8 *) parm, *len, &buf, &buflen);
break;
case SC_ASN1_OCTET_STRING:
case SC_ASN1_UTF8STRING:
assert(len != NULL);

View File

@ -141,6 +141,7 @@ void sc_asn1_clear_algorithm_id(struct sc_algorithm_id *);
/* internal structures */
#define SC_ASN1_STRUCT 129
#define SC_ASN1_CHOICE 130
#define SC_ASN1_BIT_FIELD 131 /* bit string as integer */
/* 'complex' structures */
#define SC_ASN1_PATH 256

View File

@ -32,7 +32,7 @@ static const struct sc_asn1_entry c_asn1_com_ao_attr[] = {
{ NULL }
};
static const struct sc_asn1_entry c_asn1_pin_attr[] = {
{ "pinFlags", SC_ASN1_BIT_STRING, ASN1_BIT_STRING, 0, NULL },
{ "pinFlags", SC_ASN1_BIT_FIELD, ASN1_BIT_STRING, 0, NULL },
{ "pinType", SC_ASN1_ENUMERATED, ASN1_ENUMERATED, 0, NULL },
{ "minLength", SC_ASN1_INTEGER, ASN1_INTEGER, 0, NULL },
{ "storedLength", SC_ASN1_INTEGER, ASN1_INTEGER, 0, NULL },
@ -136,7 +136,7 @@ int sc_pkcs15_encode_aodf_entry(struct sc_context *ctx,
sc_format_asn1_entry(asn1_type_pin_attr + 0, asn1_pin_attr, NULL, 1);
flags_len = _sc_count_bit_string_size(&pin->flags, sizeof(pin->flags));
flags_len = sizeof(pin->flags);
sc_format_asn1_entry(asn1_pin_attr + 0, &pin->flags, &flags_len, 1);
sc_format_asn1_entry(asn1_pin_attr + 1, &pin->type, NULL, 1);
sc_format_asn1_entry(asn1_pin_attr + 2, &pin->min_length, NULL, 1);

View File

@ -29,9 +29,9 @@
static const struct sc_asn1_entry c_asn1_com_key_attr[] = {
{ "iD", SC_ASN1_PKCS15_ID, ASN1_OCTET_STRING, 0, NULL },
{ "usage", SC_ASN1_BIT_STRING, ASN1_BIT_STRING, 0, NULL },
{ "usage", SC_ASN1_BIT_FIELD, ASN1_BIT_STRING, 0, NULL },
{ "native", SC_ASN1_BOOLEAN, ASN1_BOOLEAN, SC_ASN1_OPTIONAL, NULL },
{ "accessFlags", SC_ASN1_BIT_STRING, ASN1_BIT_STRING, SC_ASN1_OPTIONAL, NULL },
{ "accessFlags", SC_ASN1_BIT_FIELD, ASN1_BIT_STRING, SC_ASN1_OPTIONAL, NULL },
{ "keyReference",SC_ASN1_INTEGER, ASN1_INTEGER, SC_ASN1_OPTIONAL, NULL },
{ NULL }
};
@ -219,12 +219,12 @@ int sc_pkcs15_encode_prkdf_entry(struct sc_context *ctx,
break;
}
sc_format_asn1_entry(asn1_com_key_attr + 0, &prkey->id, NULL, 1);
usage_len = _sc_count_bit_string_size(&prkey->usage, sizeof(prkey->usage));
usage_len = sizeof(prkey->usage);
sc_format_asn1_entry(asn1_com_key_attr + 1, &prkey->usage, &usage_len, 1);
if (prkey->native == 0)
sc_format_asn1_entry(asn1_com_key_attr + 2, &prkey->native, NULL, 1);
if (prkey->access_flags) {
af_len = _sc_count_bit_string_size(&prkey->access_flags, sizeof(prkey->access_flags));
af_len = sizeof(prkey->access_flags);
sc_format_asn1_entry(asn1_com_key_attr + 3, &prkey->access_flags, &af_len, 1);
}
if (prkey->key_reference >= 0)

View File

@ -29,9 +29,9 @@
static const struct sc_asn1_entry c_asn1_com_key_attr[] = {
{ "iD", SC_ASN1_PKCS15_ID, ASN1_OCTET_STRING, 0, NULL },
{ "usage", SC_ASN1_BIT_STRING, ASN1_BIT_STRING, 0, NULL },
{ "usage", SC_ASN1_BIT_FIELD, ASN1_BIT_STRING, 0, NULL },
{ "native", SC_ASN1_BOOLEAN, ASN1_BOOLEAN, SC_ASN1_OPTIONAL, NULL },
{ "accessFlags", SC_ASN1_BIT_STRING, ASN1_BIT_STRING, SC_ASN1_OPTIONAL, NULL },
{ "accessFlags", SC_ASN1_BIT_FIELD, ASN1_BIT_STRING, SC_ASN1_OPTIONAL, NULL },
{ "keyReference",SC_ASN1_INTEGER, ASN1_INTEGER, SC_ASN1_OPTIONAL, NULL },
{ NULL }
};
@ -185,12 +185,12 @@ int sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx,
}
sc_format_asn1_entry(asn1_com_key_attr + 0, &pubkey->id, NULL, 1);
usage_len = _sc_count_bit_string_size(&pubkey->usage, sizeof(pubkey->usage));
usage_len = sizeof(pubkey->usage);
sc_format_asn1_entry(asn1_com_key_attr + 1, &pubkey->usage, &usage_len, 1);
if (pubkey->native == 0)
sc_format_asn1_entry(asn1_com_key_attr + 2, &pubkey->native, NULL, 1);
if (pubkey->access_flags) {
af_len = _sc_count_bit_string_size(&pubkey->access_flags, sizeof(pubkey->access_flags));
af_len = sizeof(pubkey->access_flags);
sc_format_asn1_entry(asn1_com_key_attr + 3, &pubkey->access_flags, &af_len, 1);
}
if (pubkey->key_reference >= 0)

View File

@ -63,7 +63,7 @@ static const struct sc_asn1_entry c_asn1_toki[] = {
{ "serialNumber", SC_ASN1_OCTET_STRING, ASN1_OCTET_STRING, 0, NULL },
{ "manufacturerID", SC_ASN1_UTF8STRING, ASN1_UTF8STRING, SC_ASN1_OPTIONAL, NULL },
{ "label", SC_ASN1_UTF8STRING, SC_ASN1_CTX | 0, SC_ASN1_OPTIONAL, NULL },
{ "tokenflags", SC_ASN1_BIT_STRING, ASN1_BIT_STRING, 0, NULL },
{ "tokenflags", SC_ASN1_BIT_FIELD, ASN1_BIT_STRING, 0, NULL },
{ "seInfo", SC_ASN1_SEQUENCE, SC_ASN1_CONS | ASN1_SEQUENCE, SC_ASN1_OPTIONAL, NULL },
{ "recordInfo", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_CTX | 1, SC_ASN1_OPTIONAL, NULL },
{ "supportedAlgorithms", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_CTX | 2, SC_ASN1_OPTIONAL, NULL },
@ -168,7 +168,7 @@ int sc_pkcs15_encode_tokeninfo(struct sc_context *ctx,
sc_format_asn1_entry(asn1_toki + 3, card->label, &label_len, 1);
}
if (card->flags) {
flags_len = _sc_count_bit_string_size(&card->flags, sizeof(card->flags));
flags_len = sizeof(card->flags);
sc_format_asn1_entry(asn1_toki + 4, &card->flags, &flags_len, 1);
}
sc_format_asn1_entry(asn1_tokeninfo, asn1_toki, NULL, 1);