asn1: accept long tag ...

According to X.690-0207 ch.8.1.2.4


git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@5088 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
vtarasov 2011-01-13 13:59:22 +00:00
parent 7f5ea5b013
commit 66412d6e53
2 changed files with 37 additions and 10 deletions

View File

@ -724,18 +724,37 @@ int sc_asn1_put_tag(int tag, const u8 * data, size_t datalen, u8 * out, size_t o
return 0;
}
static int asn1_write_element(sc_context_t *ctx, unsigned int tag,
const u8 * data, size_t datalen, u8 ** out, size_t * outlen)
{
u8 t;
u8 *buf, *p;
int c = 0;
unsigned char t;
unsigned char *buf, *p;
int c = 0, ii;
unsigned short_tag;
unsigned char tag_char[3] = {0, 0, 0};
size_t tag_len;
t = tag & 0x1F;
if (t != (tag & SC_ASN1_TAG_MASK)) {
sc_debug(ctx, SC_LOG_DEBUG_ASN1, "Long tags not supported\n");
return SC_ERROR_INVALID_ARGUMENTS;
short_tag = tag & SC_ASN1_TAG_MASK;
for (tag_len = 0; short_tag >> (8 * tag_len); tag_len++)
tag_char[tag_len] = (short_tag >> (8 * tag_len)) & 0xFF;
if (!tag_len)
tag_len = 1;
if (tag_len > 1) {
if ((tag_char[tag_len - 1] & SC_ASN1_TAG_PRIMITIVE) != SC_ASN1_TAG_ESCAPE_MARKER)
SC_TEST_RET(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_INVALID_DATA, "First byte of the long tag is not 'espace marker'");
for (ii = 1; ii < tag_len - 1; ii++)
if (!(tag_char[ii] & 0x80))
SC_TEST_RET(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_INVALID_DATA, "MS bit exected to be 'one'");
if (tag_char[0] & 0x80)
SC_TEST_RET(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_INVALID_DATA, "MS bit of the last byte exected to be 'zero'");
}
t = tag_char[tag_len - 1] & 0x1F;
switch (tag & SC_ASN1_CLASS_MASK) {
case SC_ASN1_UNI:
break;
@ -756,21 +775,28 @@ static int asn1_write_element(sc_context_t *ctx, unsigned int tag,
while (datalen >> (c << 3))
c++;
}
*outlen = 2 + c + datalen;
*outlen = tag_len + 1 + c + datalen;
buf = malloc(*outlen);
if (buf == NULL)
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_OUT_OF_MEMORY);
*out = p = buf;
*p++ = t;
for (ii=1;ii<tag_len;ii++)
*p++ = tag_char[tag_len - ii - 1];
if (c) {
*p++ = 0x80 | c;
while (c--)
*p++ = (datalen >> (c << 3)) & 0xFF;
} else
}
else {
*p++ = datalen & 0x7F;
}
memcpy(p, data, datalen);
return 0;
return SC_SUCCESS;
}
static const struct sc_asn1_entry c_asn1_path_ext[3] = {

View File

@ -193,6 +193,7 @@ void sc_asn1_clear_algorithm_id(struct sc_algorithm_id *);
#define SC_ASN1_TAG_GENERALSTRING 27
#define SC_ASN1_TAG_UNIVERSALSTRING 28
#define SC_ASN1_TAG_BMPSTRING 30
#define SC_ASN1_TAG_ESCAPE_MARKER 31
#ifdef __cplusplus
}