- ported certificate reading to new ASN.1 code

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@119 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
jey 2001-12-29 19:03:46 +00:00
parent da88fb7d62
commit 3e96a893ec
7 changed files with 184 additions and 139 deletions

2
NEWS
View File

@ -1,6 +1,6 @@
NEWS for OpenSC -- History of user visible changes
New in 0.4.0; 2001-12-xx; Juha Yrjölä:
New in 0.4.0; 2001-12-29; Juha Yrjölä:
* Finished migrating to Autotools
* Rewritten ASN.1 decoder (should work better on all PKCS #15 cards)
* Abstracted card handling, so adding support for new cards is a whiz,

View File

@ -248,9 +248,11 @@ void sc_asn1_print_tags(const u8 * buf, int buflen)
print_tags_recursive(buf, buf, buflen, 0);
}
const u8 *sc_asn1_find_tag(const u8 * buf, int buflen, int tag_in, int *taglen_in)
const u8 *sc_asn1_find_tag(struct sc_context *ctx, const u8 * buf,
size_t buflen, unsigned int tag_in, size_t *taglen_in)
{
int left = buflen, cla, tag, taglen;
size_t left = buflen, taglen;
unsigned int cla, tag;
const u8 *p = buf;
*taglen_in = 0;
@ -265,40 +267,18 @@ const u8 *sc_asn1_find_tag(const u8 * buf, int buflen, int tag_in, int *taglen_i
*taglen_in = taglen;
return p;
}
if ((cla | tag) == 0xF0) { /* skip 0xF0 foobar tags */
fprintf(stderr, "Foobar tag skipped\n");
taglen = 0;
}
left -= taglen;
p += taglen;
}
return NULL;
}
const u8 *sc_asn1_skip_tag(const u8 ** buf, int *buflen, int tag_in, int *taglen_out)
const u8 *sc_asn1_skip_tag(struct sc_context *ctx, const u8 ** buf, size_t *buflen,
unsigned int tag_in, size_t *taglen_out)
{
const u8 *p = *buf;
int len = *buflen, cla, tag, taglen;
if (read_tag((const u8 **) &p, len, &cla, &tag, &taglen) != 1)
return NULL;
if ((tag | cla) != tag_in)
return NULL;
len -= (p - *buf); /* header size */
if (taglen > len) {
fprintf(stderr, "skip_tag(): too long tag\n");
return NULL;
}
*buflen -= (p - *buf) + taglen;
*buf = p + taglen; /* point to next tag */
*taglen_out = taglen;
return p;
}
static const u8 *sc_asn1_skip_tag2(struct sc_context *ctx, const u8 ** buf, int *buflen, unsigned int tag_in, int *taglen_out)
{
const u8 *p = *buf;
int len = *buflen, cla, tag, taglen;
size_t len = *buflen, taglen;
unsigned int cla, tag;
if (read_tag((const u8 **) &p, len, &cla, &tag, &taglen) != 1)
return NULL;
@ -340,9 +320,10 @@ static const u8 *sc_asn1_skip_tag2(struct sc_context *ctx, const u8 ** buf, int
return p;
}
const u8 *sc_asn1_verify_tag(const u8 * buf, int buflen, int tag_in, int *taglen_out)
const u8 *sc_asn1_verify_tag(struct sc_context *ctx, const u8 * buf, size_t buflen,
unsigned int tag_in, size_t *taglen_out)
{
return sc_asn1_skip_tag(&buf, &buflen, tag_in, taglen_out);
return sc_asn1_skip_tag(ctx, &buf, &buflen, tag_in, taglen_out);
}
static int decode_bit_string(const u8 * inbuf, int inlen, void *outbuf,
@ -523,10 +504,13 @@ static int asn1_parse_p15_object(struct sc_context *ctx, const u8 *in, int len,
}
static int asn1_decode_entry(struct sc_context *ctx, struct sc_asn1_struct *entry,
const u8 *obj, int objlen, int depth)
const u8 *obj, size_t objlen, int depth)
{
void *parm = entry->parm;
int *len = entry->len;
int (*callback_func)(struct sc_context *ctx, void *arg, const u8 *obj,
size_t objlen, int depth) =
(int (*)(struct sc_context *, void *, const u8 *, size_t, int)) parm;
int *len = (int *) entry->arg;
int r = 0;
if (ctx->debug >= 3) {
@ -562,9 +546,22 @@ static int asn1_decode_entry(struct sc_context *ctx, struct sc_asn1_struct *entr
if (parm != NULL)
r = sc_asn1_decode_integer(obj, objlen, (int *) entry->parm);
break;
case SC_ASN1_BIT_STRING_NI:
case SC_ASN1_BIT_STRING:
if (parm != NULL && len != NULL) {
r = sc_asn1_decode_bit_string(obj, objlen, (u8 *) parm, *len);
if (parm != NULL) {
int invert = entry->type == SC_ASN1_BIT_STRING ? 1 : 0;
assert(len != NULL);
if (entry->flags & SC_ASN1_ALLOC) {
u8 **buf = (u8 **) parm;
*buf = malloc(objlen-1);
if (*buf == NULL) {
r = SC_ERROR_OUT_OF_MEMORY;
break;
}
*len = objlen-1;
parm = *buf;
}
r = decode_bit_string(obj, objlen, (u8 *) parm, *len, invert);
if (r >= 0) {
*len = r;
r = 0;
@ -575,7 +572,17 @@ static int asn1_decode_entry(struct sc_context *ctx, struct sc_asn1_struct *entr
if (parm != NULL) {
int c;
assert(len != NULL);
c = objlen > *len ? *len : objlen;
if (entry->flags & SC_ASN1_ALLOC) {
u8 **buf = (u8 **) parm;
*buf = malloc(objlen);
if (*buf == NULL) {
r = SC_ERROR_OUT_OF_MEMORY;
break;
}
c = *len = objlen;
parm = *buf;
} else
c = objlen > *len ? *len : objlen;
memcpy(parm, obj, c);
*len = c;
@ -588,6 +595,16 @@ static int asn1_decode_entry(struct sc_context *ctx, struct sc_asn1_struct *entr
case SC_ASN1_UTF8STRING:
if (parm != NULL) {
assert(len != NULL);
if (entry->flags & SC_ASN1_ALLOC) {
u8 **buf = (u8 **) parm;
*buf = malloc(objlen-1);
if (*buf == NULL) {
r = SC_ERROR_OUT_OF_MEMORY;
break;
}
*len = objlen-1;
parm = *buf;
}
r = sc_asn1_decode_utf8string(obj, objlen, parm, len);
}
break;
@ -608,6 +625,10 @@ static int asn1_decode_entry(struct sc_context *ctx, struct sc_asn1_struct *entr
if (entry->parm != NULL)
r = asn1_parse_p15_object(ctx, obj, objlen, (struct sc_pkcs15_object *) parm, depth);
break;
case SC_ASN1_CALLBACK:
if (entry->parm != NULL)
r = callback_func(ctx, entry->arg, obj, objlen, depth);
break;
default:
error(ctx, "invalid ASN.1 type: %d\n", entry->type);
assert(0);
@ -639,7 +660,7 @@ static int asn1_parse(struct sc_context *ctx, struct sc_asn1_struct *asn1,
for (idx = 0; asn1[idx].name != NULL; idx++) {
entry = &asn1[idx];
r = 0;
obj = sc_asn1_skip_tag2(ctx, &p, &left, entry->tag, &objlen);
obj = sc_asn1_skip_tag(ctx, &p, &left, entry->tag, &objlen);
if (obj == NULL) {
if (choice)
continue;

View File

@ -30,7 +30,7 @@ struct sc_asn1_struct {
unsigned int tag;
unsigned int flags;
void *parm;
int *len;
void *arg;
};
struct sc_pkcs15_object {
@ -47,9 +47,12 @@ int sc_asn1_parse(struct sc_context *ctx, struct sc_asn1_struct *asn1,
int sc_asn1_parse_choice(struct sc_context *ctx, struct sc_asn1_struct *asn1,
const u8 *in, int len, const u8 **newp, int *left);
const u8 *sc_asn1_find_tag(const u8 * buf, int buflen, int tag, int *taglen);
const u8 *sc_asn1_verify_tag(const u8 * buf, int buflen, int tag, int *taglen);
const u8 *sc_asn1_skip_tag(const u8 ** buf, int *buflen, int tag, int *taglen);
const u8 *sc_asn1_find_tag(struct sc_context *ctx, const u8 * buf,
size_t buflen, unsigned int tag, size_t *taglen);
const u8 *sc_asn1_verify_tag(struct sc_context *ctx, const u8 * buf,
size_t buflen, unsigned int tag, size_t *taglen);
const u8 *sc_asn1_skip_tag(struct sc_context *ctx, const u8 ** buf,
size_t *buflen, unsigned int tag, size_t *taglen);
/* DER encoding */
@ -82,10 +85,12 @@ int sc_asn1_decode_object_id(const u8 * inbuf, int inlen,
#define SC_ASN1_PRESENT 0x00000001
#define SC_ASN1_OPTIONAL 0x00000002
#define SC_ASN1_ALLOC 0x00000004
#define SC_ASN1_BOOLEAN 1
#define SC_ASN1_INTEGER 2
#define SC_ASN1_BIT_STRING 3
#define SC_ASN1_BIT_STRING_NI 128
#define SC_ASN1_OCTET_STRING 4
#define SC_ASN1_NULL 5
#define SC_ASN1_OBJECT 6
@ -98,14 +103,17 @@ int sc_asn1_decode_object_id(const u8 * inbuf, int inlen,
#define SC_ASN1_GENERALIZEDTIME 24
/* internal structures */
#define SC_ASN1_STRUCT 128
#define SC_ASN1_CHOICE 129
#define SC_ASN1_STRUCT 129
#define SC_ASN1_CHOICE 130
/* 'complex' structures */
#define SC_ASN1_PATH 256
#define SC_ASN1_PKCS15_ID 257
#define SC_ASN1_PKCS15_OBJECT 258
/* use callback function */
#define SC_ASN1_CALLBACK 384
#define ASN1_TAG_CLASS 0xC0
#define ASN1_TAG_UNIVERSAL 0x00
#define ASN1_TAG_APPLICATION 0x40

View File

@ -103,28 +103,28 @@ static void parse_sec_attr(struct sc_file *file, const u8 *buf, size_t len)
}
static void process_fci(struct sc_context *ctx, struct sc_file *file,
const u8 *buf, int buflen)
const u8 *buf, size_t buflen)
{
int taglen, len = buflen;
size_t taglen, len = buflen;
const u8 *tag = NULL, *p = buf;
if (ctx->debug >= 3)
debug(ctx, "processing FCI bytes\n");
tag = sc_asn1_find_tag(p, len, 0x83, &taglen);
tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen);
if (tag != NULL && taglen == 2) {
file->id = (tag[0] << 8) | tag[1];
if (ctx->debug >= 3)
debug(ctx, " file identifier: 0x%02X%02X\n", tag[0],
tag[1]);
}
tag = sc_asn1_find_tag(p, len, 0x81, &taglen);
tag = sc_asn1_find_tag(ctx, p, len, 0x81, &taglen);
if (tag != NULL && taglen >= 2) {
int bytes = (tag[0] << 8) + tag[1];
if (ctx->debug >= 3)
debug(ctx, " bytes in file: %d\n", bytes);
file->size = bytes;
}
tag = sc_asn1_find_tag(p, len, 0x82, &taglen);
tag = sc_asn1_find_tag(ctx, p, len, 0x82, &taglen);
if (tag != NULL) {
if (taglen > 0) {
unsigned char byte = tag[0];
@ -159,7 +159,7 @@ static void process_fci(struct sc_context *ctx, struct sc_file *file,
}
}
}
tag = sc_asn1_find_tag(p, len, 0x84, &taglen);
tag = sc_asn1_find_tag(ctx, p, len, 0x84, &taglen);
if (tag != NULL && taglen > 0 && taglen <= 16) {
char name[17];
int i;
@ -178,18 +178,18 @@ static void process_fci(struct sc_context *ctx, struct sc_file *file,
if (ctx->debug >= 3)
debug(ctx, "File name: %s\n", name);
}
tag = sc_asn1_find_tag(p, len, 0x85, &taglen);
tag = sc_asn1_find_tag(ctx, p, len, 0x85, &taglen);
if (tag != NULL && taglen && taglen <= SC_MAX_PROP_ATTR_SIZE) {
memcpy(file->prop_attr, tag, taglen);
file->prop_attr_len = taglen;
} else
file->prop_attr_len = 0;
tag = sc_asn1_find_tag(p, len, 0xA5, &taglen);
tag = sc_asn1_find_tag(ctx, p, len, 0xA5, &taglen);
if (tag != NULL && taglen && taglen <= SC_MAX_PROP_ATTR_SIZE) {
memcpy(file->prop_attr, tag, taglen);
file->prop_attr_len = taglen;
}
tag = sc_asn1_find_tag(p, len, 0x86, &taglen);
tag = sc_asn1_find_tag(ctx, p, len, 0x86, &taglen);
if (tag != NULL && taglen && taglen <= SC_MAX_SEC_ATTR_SIZE)
parse_sec_attr(file, tag, taglen);
else

View File

@ -31,98 +31,106 @@
#undef CACHE_CERTS
static int parse_rsa_pubkey(const u8 *buf, int buflen, struct sc_pkcs15_rsa_pubkey *key)
static int parse_rsa_pubkey(struct sc_context *ctx, struct sc_pkcs15_rsa_pubkey *key)
{
const u8 *tag;
int taglen;
buf = sc_asn1_verify_tag(buf, buflen, 0x30, &buflen);
if (buf == NULL)
return -1;
tag = sc_asn1_verify_tag(buf, buflen, 0x02, &taglen);
if (tag == NULL)
return -1;
key->modulus = malloc(taglen);
memcpy(key->modulus, tag, taglen);
key->modulus_len = taglen;
tag += taglen;
buflen -= tag - buf;
tag = sc_asn1_verify_tag(tag, buflen, 0x02, &taglen);
if (sc_asn1_decode_integer(tag, taglen, (int *) &key->exponent)) {
free(key->modulus);
struct sc_asn1_struct asn1_rsa_pubkey[] = {
{ "modulus", SC_ASN1_OCTET_STRING, ASN1_INTEGER, SC_ASN1_ALLOC, &key->modulus, &key->modulus_len },
{ "publicExponent", SC_ASN1_INTEGER, ASN1_INTEGER, 0, &key->exponent },
{ NULL }
};
const u8 *obj;
size_t objlen;
int r;
obj = sc_asn1_verify_tag(ctx, key->data, key->data_len, ASN1_SEQUENCE | SC_ASN1_CONS,
&objlen);
if (obj == NULL) {
error(ctx, "RSA public key not found\n");
return SC_ERROR_INVALID_ASN1_OBJECT;
}
r = sc_asn1_parse(ctx, asn1_rsa_pubkey, obj, objlen, NULL, NULL);
SC_TEST_RET(ctx, r, "ASN.1 parsing failed");
return 0;
}
static int parse_cert(const u8 *buf, int buflen, struct sc_pkcs15_cert *cert)
struct asn1_algorithm_id {
struct sc_object_id id;
};
static int parse_algorithm_id(struct sc_context *ctx, void *arg, const u8 *obj,
size_t objlen, int depth)
{
const u8 *tag, *p;
u8 *tmpbuf;
int taglen, left, r;
struct sc_pkcs15_rsa_pubkey *key = &cert->key;
const u8 *buf0 = buf;
struct asn1_algorithm_id *alg_id = (struct asn1_algorithm_id *) arg;
struct sc_asn1_struct asn1_alg_id[] = {
{ "algorithm", SC_ASN1_OBJECT, ASN1_OBJECT, 0, &alg_id->id },
{ "parameters", SC_ASN1_STRUCT, 0, SC_ASN1_OPTIONAL, NULL },
{ NULL }
};
int r;
buf = sc_asn1_verify_tag(buf, buflen, 0x30, &buflen); /* SEQUENCE */
if (buf == NULL) /* Certificate */
return SC_ERROR_INVALID_ASN1_OBJECT;
cert->data_len = (buf - buf0) + buflen;
p = sc_asn1_skip_tag(&buf, &buflen, 0x30, &left); /* SEQUENCE */
if (p == NULL) /* tbsCertificate */
return SC_ERROR_INVALID_ASN1_OBJECT;
cert->version = 0;
tag = sc_asn1_skip_tag(&p, &left, 0xA0, &taglen); /* Version */
if (tag != NULL) {
tag = sc_asn1_verify_tag(tag, taglen, 0x02, &taglen);
if (tag != NULL) {
sc_asn1_decode_integer(tag, taglen, &cert->version);
cert->version++;
}
}
tag = sc_asn1_skip_tag(&p, &left, 0x02, &taglen); /* INTEGER */
if (tag == NULL)
return SC_ERROR_INVALID_ASN1_OBJECT;
sc_asn1_decode_integer(tag, taglen, (int *) &cert->serial);
r = sc_asn1_parse(ctx, asn1_alg_id, obj, objlen, NULL, NULL);
SC_TEST_RET(ctx, r, "ASN.1 parsing failed");
return 0;
}
tag = sc_asn1_skip_tag(&p, &left, 0x30, &taglen); /* signatureId */
if (tag == NULL)
return SC_ERROR_INVALID_ASN1_OBJECT;
tag = sc_asn1_skip_tag(&p, &left, 0x30, &taglen); /* issuer */
if (tag == NULL)
return SC_ERROR_INVALID_ASN1_OBJECT;
tag = sc_asn1_skip_tag(&p, &left, 0x30, &taglen); /* validity */
if (tag == NULL)
return SC_ERROR_INVALID_ASN1_OBJECT;
tag = sc_asn1_skip_tag(&p, &left, 0x30, &taglen); /* subject */
if (tag == NULL)
return SC_ERROR_INVALID_ASN1_OBJECT;
tag = sc_asn1_skip_tag(&p, &left, 0x30, &taglen); /* subjectPKInfo */
if (tag == NULL)
return SC_ERROR_INVALID_ASN1_OBJECT;
/* FIXME: get the algorithm ID */
tag = sc_asn1_find_tag(tag, taglen, 0x03, &taglen); /* subjectPubKey */
if (tag == NULL)
return SC_ERROR_INVALID_ASN1_OBJECT;
tmpbuf = malloc(taglen-1);
r = sc_asn1_decode_bit_string_ni(tag, taglen, tmpbuf, taglen-1);
if (r < 0) {
free(tmpbuf);
static int parse_x509_cert(struct sc_context *ctx, const u8 *buf, size_t buflen, struct sc_pkcs15_cert *cert)
{
int r;
struct sc_pkcs15_rsa_pubkey *key = &cert->key;
struct asn1_algorithm_id pk_alg, sig_alg;
u8 *pk = NULL;
size_t pklen = 0;
struct sc_asn1_struct asn1_version[] = {
{ "version", SC_ASN1_INTEGER, ASN1_INTEGER, 0, &cert->version },
{ NULL }
};
struct sc_asn1_struct asn1_pkinfo[] = {
{ "algorithm", SC_ASN1_CALLBACK, ASN1_SEQUENCE | SC_ASN1_CONS, 0, parse_algorithm_id, &pk_alg },
{ "subjectPublicKey", SC_ASN1_BIT_STRING_NI, ASN1_BIT_STRING, SC_ASN1_ALLOC, &pk, &pklen },
{ NULL }
};
struct sc_asn1_struct asn1_tbscert[] = {
{ "version", SC_ASN1_STRUCT, SC_ASN1_CTX | 0 | SC_ASN1_CONS, 0, asn1_version },
{ "serialNumber", SC_ASN1_INTEGER, ASN1_INTEGER, 0, &cert->serial },
{ "signature", SC_ASN1_STRUCT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, NULL },
{ "issuer", SC_ASN1_STRUCT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, NULL },
{ "validity", SC_ASN1_STRUCT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, NULL },
{ "subject", SC_ASN1_STRUCT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, NULL },
{ "subjectPublicKeyInfo",SC_ASN1_STRUCT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, asn1_pkinfo },
{ NULL }
};
struct sc_asn1_struct asn1_cert[] = {
{ "tbsCertificate", SC_ASN1_STRUCT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, asn1_tbscert },
{ "signatureAlgorithm", SC_ASN1_CALLBACK, ASN1_SEQUENCE | SC_ASN1_CONS, 0, parse_algorithm_id, &sig_alg },
{ "signatureValue", SC_ASN1_BIT_STRING,ASN1_BIT_STRING, 0, NULL, 0 },
{ NULL }
};
const u8 *obj;
size_t objlen;
obj = sc_asn1_verify_tag(ctx, buf, buflen, ASN1_SEQUENCE | SC_ASN1_CONS,
&objlen);
if (obj == NULL) {
error(ctx, "X.509 certificate not found\n");
return SC_ERROR_INVALID_ASN1_OBJECT;
}
r >>= 3;
key->data = tmpbuf;
key->data_len = taglen-1;
r = parse_rsa_pubkey(tmpbuf, r, key);
cert->data_len = objlen + (obj - buf);
r = sc_asn1_parse(ctx, asn1_cert, obj, objlen, NULL, NULL);
SC_TEST_RET(ctx, r, "ASN.1 parsing failed");
cert->version++;
pklen >>= 3; /* convert number of bits to bytes */
key->data = pk;
key->data_len = pklen;
/* FIXME: ignore the object id for now, and presume it's RSA */
r = parse_rsa_pubkey(ctx, key);
if (r) {
free(tmpbuf);
free(key->data);
return SC_ERROR_INVALID_ASN1_OBJECT;
}
return 0;
}
@ -259,7 +267,7 @@ int sc_pkcs15_read_certificate(struct sc_pkcs15_card *p15card,
return SC_ERROR_OUT_OF_MEMORY;
}
memset(cert, 0, sizeof(struct sc_pkcs15_cert));
if (parse_cert(data, len, cert)) {
if (parse_x509_cert(p15card->card->ctx, data, len, cert)) {
free(data);
free(cert);
return SC_ERROR_INVALID_ASN1_OBJECT;

View File

@ -76,7 +76,7 @@ void parse_tokeninfo(struct sc_pkcs15_card *card, const u8 * buf, int buflen)
{ NULL }
};
buf = sc_asn1_verify_tag(buf, buflen, 0x30, &buflen); /* SEQUENCE */
buf = sc_asn1_verify_tag(card->card->ctx, buf, buflen, SC_ASN1_CONS | ASN1_SEQUENCE, &buflen);
if (buf == NULL) {
error(card->card->ctx, "invalid EF(TokenInfo)\n");
goto err;
@ -134,7 +134,7 @@ static int parse_dir(const u8 * buf, int buflen, struct sc_pkcs15_card *card)
{ NULL }
};
buf = sc_asn1_verify_tag(buf, buflen, 0x61, &buflen);
buf = sc_asn1_verify_tag(card->card->ctx, buf, buflen, SC_ASN1_APP | 1 | SC_ASN1_CONS, &buflen);
if (buf == NULL) {
error(card->card->ctx, "No [APPLICATION 1] tag in EF(DIR)\n");
return -1;

View File

@ -30,7 +30,7 @@ struct sc_asn1_struct {
unsigned int tag;
unsigned int flags;
void *parm;
int *len;
void *arg;
};
struct sc_pkcs15_object {
@ -47,9 +47,12 @@ int sc_asn1_parse(struct sc_context *ctx, struct sc_asn1_struct *asn1,
int sc_asn1_parse_choice(struct sc_context *ctx, struct sc_asn1_struct *asn1,
const u8 *in, int len, const u8 **newp, int *left);
const u8 *sc_asn1_find_tag(const u8 * buf, int buflen, int tag, int *taglen);
const u8 *sc_asn1_verify_tag(const u8 * buf, int buflen, int tag, int *taglen);
const u8 *sc_asn1_skip_tag(const u8 ** buf, int *buflen, int tag, int *taglen);
const u8 *sc_asn1_find_tag(struct sc_context *ctx, const u8 * buf,
size_t buflen, unsigned int tag, size_t *taglen);
const u8 *sc_asn1_verify_tag(struct sc_context *ctx, const u8 * buf,
size_t buflen, unsigned int tag, size_t *taglen);
const u8 *sc_asn1_skip_tag(struct sc_context *ctx, const u8 ** buf,
size_t *buflen, unsigned int tag, size_t *taglen);
/* DER encoding */
@ -82,10 +85,12 @@ int sc_asn1_decode_object_id(const u8 * inbuf, int inlen,
#define SC_ASN1_PRESENT 0x00000001
#define SC_ASN1_OPTIONAL 0x00000002
#define SC_ASN1_ALLOC 0x00000004
#define SC_ASN1_BOOLEAN 1
#define SC_ASN1_INTEGER 2
#define SC_ASN1_BIT_STRING 3
#define SC_ASN1_BIT_STRING_NI 128
#define SC_ASN1_OCTET_STRING 4
#define SC_ASN1_NULL 5
#define SC_ASN1_OBJECT 6
@ -98,14 +103,17 @@ int sc_asn1_decode_object_id(const u8 * inbuf, int inlen,
#define SC_ASN1_GENERALIZEDTIME 24
/* internal structures */
#define SC_ASN1_STRUCT 128
#define SC_ASN1_CHOICE 129
#define SC_ASN1_STRUCT 129
#define SC_ASN1_CHOICE 130
/* 'complex' structures */
#define SC_ASN1_PATH 256
#define SC_ASN1_PKCS15_ID 257
#define SC_ASN1_PKCS15_OBJECT 258
/* use callback function */
#define SC_ASN1_CALLBACK 384
#define ASN1_TAG_CLASS 0xC0
#define ASN1_TAG_UNIVERSAL 0x00
#define ASN1_TAG_APPLICATION 0x40