- 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:
parent
897e4a87ca
commit
98907b68f1
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue