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:
parent
7f5ea5b013
commit
66412d6e53
|
@ -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] = {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue