pkcs15: decode 'seInfo', 'profileIndication', 'lastUpdate'
Encode,decode 'lastUpdate', 'seInfo', 'profileIndication' of TokenInfo (CIAInfo). Trailing whitespaces.
This commit is contained in:
parent
be81263d8e
commit
6337149ef7
|
@ -86,7 +86,7 @@ int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out,
|
|||
/* either an invalid tag or it doesn't fit in
|
||||
* unsigned int */
|
||||
return SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
|
||||
|
||||
}
|
||||
if (left == 0)
|
||||
return SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
|
@ -216,7 +216,7 @@ static void sc_asn1_print_object_id(const u8 * buf, size_t buflen)
|
|||
sbuf[0] = 0;
|
||||
while (oid.value[i] >= 0) {
|
||||
char tmp[12];
|
||||
|
||||
|
||||
if (i)
|
||||
strcat(sbuf, ".");
|
||||
sprintf(tmp, "%d", oid.value[i]);
|
||||
|
@ -226,6 +226,13 @@ static void sc_asn1_print_object_id(const u8 * buf, size_t buflen)
|
|||
printf("%s", sbuf);
|
||||
}
|
||||
|
||||
static void sc_asn1_print_generalizedtime(const u8 * buf, size_t buflen)
|
||||
{
|
||||
size_t ii;
|
||||
for (ii=0; ii<buflen; ii++)
|
||||
printf("%c", *(buf + ii));
|
||||
}
|
||||
|
||||
static void print_tags_recursive(const u8 * buf0, const u8 * buf,
|
||||
size_t buflen, int depth)
|
||||
{
|
||||
|
@ -295,6 +302,9 @@ static void print_tags_recursive(const u8 * buf0, const u8 * buf,
|
|||
case SC_ASN1_TAG_BOOLEAN:
|
||||
sc_asn1_print_boolean(tagp, len);
|
||||
break;
|
||||
case SC_ASN1_GENERALIZEDTIME:
|
||||
sc_asn1_print_generalizedtime(tagp, len);
|
||||
break;
|
||||
}
|
||||
printf("]");
|
||||
}
|
||||
|
@ -473,7 +483,7 @@ static int encode_bit_string(const u8 * inbuf, size_t bits_left, u8 **outbuf,
|
|||
u8 *out;
|
||||
size_t bytes;
|
||||
int skipped = 0;
|
||||
|
||||
|
||||
bytes = (bits_left + 7)/8 + 1;
|
||||
*outbuf = out = malloc(bytes);
|
||||
if (out == NULL)
|
||||
|
@ -482,7 +492,7 @@ static int encode_bit_string(const u8 * inbuf, size_t bits_left, u8 **outbuf,
|
|||
out += 1;
|
||||
while (bits_left) {
|
||||
int i, bits_to_go = 8;
|
||||
|
||||
|
||||
*out = 0;
|
||||
if (bits_left < 8) {
|
||||
bits_to_go = bits_left;
|
||||
|
@ -630,7 +640,7 @@ int sc_asn1_decode_object_id(const u8 * inbuf, size_t inlen,
|
|||
int i, a;
|
||||
const u8 *p = inbuf;
|
||||
int *octet;
|
||||
|
||||
|
||||
if (inlen == 0 || inbuf == NULL || id == NULL)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
octet = id->value;
|
||||
|
@ -640,7 +650,7 @@ int sc_asn1_decode_object_id(const u8 * inbuf, size_t inlen,
|
|||
*octet++ = a / 40;
|
||||
*octet++ = a % 40;
|
||||
inlen--;
|
||||
|
||||
|
||||
while (inlen) {
|
||||
p++;
|
||||
a = *p & 0x7F;
|
||||
|
@ -655,7 +665,7 @@ int sc_asn1_decode_object_id(const u8 * inbuf, size_t inlen,
|
|||
if (octet - id->value >= SC_MAX_OBJECT_ID_OCTETS-1)
|
||||
return SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
};
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -700,7 +710,7 @@ int sc_asn1_encode_object_id(u8 **buf, size_t *buflen,
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (i == 1)
|
||||
if (i == 1)
|
||||
/* an OID must have at least two components */
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
*buflen = count = p - temp;
|
||||
|
@ -736,7 +746,7 @@ int sc_asn1_put_tag(int tag, const u8 * data, size_t datalen, u8 * out, size_t o
|
|||
outlen--;
|
||||
if (outlen < datalen)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
|
||||
memcpy(p, data, datalen);
|
||||
p += datalen;
|
||||
if (ptr != NULL)
|
||||
|
@ -753,7 +763,7 @@ static int asn1_write_element(sc_context_t *ctx, unsigned int tag,
|
|||
unsigned short_tag;
|
||||
unsigned char tag_char[3] = {0, 0, 0};
|
||||
size_t tag_len, ii;
|
||||
|
||||
|
||||
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;
|
||||
|
@ -809,12 +819,12 @@ static int asn1_write_element(sc_context_t *ctx, unsigned int tag,
|
|||
*p++ = 0x80 | c;
|
||||
while (c--)
|
||||
*p++ = (datalen >> (c << 3)) & 0xFF;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*p++ = datalen & 0x7F;
|
||||
}
|
||||
memcpy(p, data, datalen);
|
||||
|
||||
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -827,10 +837,10 @@ static const struct sc_asn1_entry c_asn1_path[5] = {
|
|||
{ "path", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
{ "index", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
{ "length", SC_ASN1_INTEGER, SC_ASN1_CTX | 0, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
/* For some multi-applications PKCS#15 card the ODF records can hold the references to
|
||||
/* For some multi-applications PKCS#15 card the ODF records can hold the references to
|
||||
* the xDF files and objects placed elsewhere then under the application DF of the ODF itself.
|
||||
* In such a case the 'path' ASN1 data includes also the ID of the target application (AID).
|
||||
* This path extension do not make a part of PKCS#15 standard.
|
||||
* This path extension do not make a part of PKCS#15 standard.
|
||||
*/
|
||||
{ "pathExtended", SC_ASN1_STRUCT, SC_ASN1_CTX | 1 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL }
|
||||
|
@ -843,7 +853,7 @@ static int asn1_decode_path(sc_context_t *ctx, const u8 *in, size_t len,
|
|||
struct sc_asn1_entry asn1_path_ext[3], asn1_path[5];
|
||||
unsigned char path_value[SC_MAX_PATH_SIZE], aid_value[SC_MAX_AID_SIZE];
|
||||
size_t path_len = sizeof(path_value), aid_len = sizeof(aid_value);
|
||||
|
||||
|
||||
memset(path, 0, sizeof(struct sc_path));
|
||||
|
||||
sc_copy_asn1_entry(c_asn1_path_ext, asn1_path_ext);
|
||||
|
@ -889,7 +899,7 @@ static int asn1_decode_path(sc_context_t *ctx, const u8 *in, size_t len,
|
|||
if ((asn1_path[1].flags & SC_ASN1_PRESENT) && (asn1_path[2].flags & SC_ASN1_PRESENT)) {
|
||||
path->index = idx;
|
||||
path->count = count;
|
||||
}
|
||||
}
|
||||
else {
|
||||
path->index = 0;
|
||||
path->count = -1;
|
||||
|
@ -914,82 +924,129 @@ static int asn1_encode_path(sc_context_t *ctx, const sc_path_t *path,
|
|||
sc_format_asn1_entry(asn1_path + 2, (void *) &tpath.count, NULL, 1);
|
||||
}
|
||||
r = asn1_encode(ctx, asn1_path, buf, bufsize, depth + 1);
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static const struct sc_asn1_entry c_asn1_se[2] = {
|
||||
{ "seInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct sc_asn1_entry c_asn1_se_info[4] = {
|
||||
{ "se", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
|
||||
{ "owner", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
{ "aid", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
{ "se", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
|
||||
{ "owner",SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
{ "aid", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static int asn1_decode_se_info(sc_context_t *ctx, const u8 *obj, size_t objlen,
|
||||
sc_pkcs15_sec_env_info_t ***se, size_t *num, int depth)
|
||||
{
|
||||
sc_pkcs15_sec_env_info_t **ses;
|
||||
struct sc_pkcs15_sec_env_info **ses;
|
||||
const unsigned char *ptr = obj;
|
||||
size_t i, idx, ptrlen = objlen;
|
||||
int ret;
|
||||
|
||||
const unsigned char *p;
|
||||
size_t plen, idx = 0, size = 8, left = size;
|
||||
int ret = SC_SUCCESS;
|
||||
|
||||
p = sc_asn1_find_tag(ctx, obj, objlen, 0x30, &plen);
|
||||
if (p == NULL)
|
||||
return SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
|
||||
ses = calloc(size, sizeof(sc_pkcs15_sec_env_info_t *));
|
||||
ses = calloc(SC_MAX_SE_NUM, sizeof(sc_pkcs15_sec_env_info_t *));
|
||||
if (ses == NULL)
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
while (plen != 0) {
|
||||
for (idx=0; idx < SC_MAX_SE_NUM && ptrlen; ) {
|
||||
struct sc_asn1_entry asn1_se[2];
|
||||
struct sc_asn1_entry asn1_se_info[4];
|
||||
struct sc_pkcs15_sec_env_info si;
|
||||
|
||||
sc_pkcs15_sec_env_info_t *si = calloc(1, sizeof(sc_pkcs15_sec_env_info_t));
|
||||
if (si == NULL) {
|
||||
sc_copy_asn1_entry(c_asn1_se, asn1_se);
|
||||
sc_copy_asn1_entry(c_asn1_se_info, asn1_se_info);
|
||||
|
||||
si.aid.len = sizeof(si.aid.value);
|
||||
sc_format_asn1_entry(asn1_se_info + 0, &si.se, NULL, 0);
|
||||
sc_format_asn1_entry(asn1_se_info + 1, &si.owner, NULL, 0);
|
||||
sc_format_asn1_entry(asn1_se_info + 2, &si.aid.value, &si.aid.len, 0);
|
||||
sc_format_asn1_entry(asn1_se + 0, asn1_se_info, NULL, 0);
|
||||
|
||||
ret = asn1_decode(ctx, asn1_se, ptr, ptrlen, &ptr, &ptrlen, 0, depth+1);
|
||||
if (ret != SC_SUCCESS)
|
||||
goto err;
|
||||
if (!(asn1_se_info[1].flags & SC_ASN1_PRESENT))
|
||||
for (i=0;i<SC_MAX_OBJECT_ID_OCTETS;i++)
|
||||
si.owner.value[i] = -1;
|
||||
|
||||
ses[idx] = calloc(1, sizeof(sc_pkcs15_sec_env_info_t));
|
||||
if (ses[idx] == NULL) {
|
||||
ret = SC_ERROR_OUT_OF_MEMORY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
si->aid.len = sizeof(si->aid.value);
|
||||
sc_copy_asn1_entry(c_asn1_se_info, asn1_se_info);
|
||||
sc_format_asn1_entry(asn1_se_info + 0, &si->se, NULL, 0);
|
||||
sc_format_asn1_entry(asn1_se_info + 1, &si->owner, NULL, 0);
|
||||
sc_format_asn1_entry(asn1_se_info + 2, &si->aid.value, &si->aid.len, 0);
|
||||
ret = asn1_decode(ctx, asn1_se_info, p, plen, &p, &plen, 0, depth+1);
|
||||
if (ret != SC_SUCCESS) {
|
||||
free(si);
|
||||
ret = SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
goto err;
|
||||
}
|
||||
if (--left == 0) {
|
||||
sc_pkcs15_sec_env_info_t **np;
|
||||
size <<= 1;
|
||||
np = realloc(ses, sizeof(sc_pkcs15_sec_env_info_t *) * size);
|
||||
if (np == NULL) {
|
||||
free(si);
|
||||
ret = SC_ERROR_OUT_OF_MEMORY;
|
||||
goto err;
|
||||
}
|
||||
ses = np;
|
||||
left = size >> 1;
|
||||
}
|
||||
ses[idx++] = si;
|
||||
memcpy(ses[idx], &si, sizeof(struct sc_pkcs15_sec_env_info));
|
||||
idx++;
|
||||
}
|
||||
err:
|
||||
if (ret == SC_SUCCESS) {
|
||||
*se = ses;
|
||||
*num = idx;
|
||||
} else {
|
||||
size_t i;
|
||||
for (i = 0; i < idx; i++)
|
||||
free(ses[i]);
|
||||
free(ses);
|
||||
}
|
||||
|
||||
return ret;
|
||||
*se = ses;
|
||||
*num = idx;
|
||||
ret = SC_SUCCESS;
|
||||
err:
|
||||
if (ret != SC_SUCCESS) {
|
||||
for (i = 0; i < idx; i++)
|
||||
if (ses[i])
|
||||
free(ses[i]);
|
||||
free(ses);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int asn1_encode_se_info(sc_context_t *ctx,
|
||||
struct sc_pkcs15_sec_env_info **se, size_t se_num,
|
||||
unsigned char **buf, size_t *bufsize, int depth)
|
||||
{
|
||||
unsigned char *ptr = NULL, *out = NULL;
|
||||
size_t ptrlen = 0, outlen = 0, idx;
|
||||
int ret;
|
||||
|
||||
for (idx=0; idx < se_num; idx++) {
|
||||
struct sc_asn1_entry asn1_se[2];
|
||||
struct sc_asn1_entry asn1_se_info[4];
|
||||
|
||||
sc_copy_asn1_entry(c_asn1_se, asn1_se);
|
||||
sc_copy_asn1_entry(c_asn1_se_info, asn1_se_info);
|
||||
|
||||
sc_format_asn1_entry(asn1_se_info + 0, &se[idx]->se, NULL, 1);
|
||||
if (se[idx]->owner.value[0] != -1)
|
||||
sc_format_asn1_entry(asn1_se_info + 1, &se[idx]->owner, NULL, 1);
|
||||
if (se[idx]->aid.len)
|
||||
sc_format_asn1_entry(asn1_se_info + 2, &se[idx]->aid.value, &se[idx]->aid.len, 1);
|
||||
sc_format_asn1_entry(asn1_se + 0, asn1_se_info, NULL, 1);
|
||||
|
||||
ret = sc_asn1_encode(ctx, asn1_se, &ptr, &ptrlen);
|
||||
if (ret != SC_SUCCESS)
|
||||
goto err;
|
||||
|
||||
out = (unsigned char *) realloc(out, outlen + ptrlen);
|
||||
if (!out) {
|
||||
ret = SC_ERROR_OUT_OF_MEMORY;
|
||||
goto err;
|
||||
}
|
||||
memcpy(out + outlen, ptr, ptrlen);
|
||||
outlen += ptrlen;
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
ptrlen = 0;
|
||||
}
|
||||
|
||||
*buf = out;
|
||||
*bufsize = outlen;
|
||||
ret = SC_SUCCESS;
|
||||
err:
|
||||
if (ret != SC_SUCCESS && out != NULL)
|
||||
free(out);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* TODO: According to specification type of 'SecurityCondition' is 'CHOICE'.
|
||||
* Do it at least for SC_ASN1_PKCS15_ID(authId), SC_ASN1_STRUCT(authReference) and NULL(always). */
|
||||
static const struct sc_asn1_entry c_asn1_access_control_rule[3] = {
|
||||
{ "accessMode", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
{ "securityCondition", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
|
@ -1058,7 +1115,7 @@ static int asn1_decode_p15_object(sc_context_t *ctx, const u8 *in,
|
|||
sc_format_asn1_entry(asn1_ac_rules + ii, asn1_ac_rule[ii], NULL, 0);
|
||||
}
|
||||
sc_format_asn1_entry(asn1_c_attr + 4, asn1_ac_rules, NULL, 0);
|
||||
|
||||
|
||||
sc_format_asn1_entry(asn1_p15_obj + 0, asn1_c_attr, NULL, 0);
|
||||
sc_format_asn1_entry(asn1_p15_obj + 1, obj->asn1_class_attr, NULL, 0);
|
||||
sc_format_asn1_entry(asn1_p15_obj + 2, obj->asn1_subclass_attr, NULL, 0);
|
||||
|
@ -1116,7 +1173,7 @@ static int asn1_encode_p15_object(sc_context_t *ctx, const struct sc_asn1_pkcs15
|
|||
|
||||
sc_format_asn1_entry(asn1_p15_obj + 0, asn1_c_attr, NULL, 1);
|
||||
sc_format_asn1_entry(asn1_p15_obj + 1, obj->asn1_class_attr, NULL, 1);
|
||||
if (obj->asn1_subclass_attr != NULL)
|
||||
if (obj->asn1_subclass_attr != NULL && obj->asn1_subclass_attr->name)
|
||||
sc_format_asn1_entry(asn1_p15_obj + 2, obj->asn1_subclass_attr, NULL, 1);
|
||||
sc_format_asn1_entry(asn1_p15_obj + 3, obj->asn1_type_attr, NULL, 1);
|
||||
|
||||
|
@ -1129,7 +1186,7 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry,
|
|||
{
|
||||
void *parm = entry->parm;
|
||||
int (*callback_func)(sc_context_t *nctx, void *arg, const u8 *nobj,
|
||||
size_t nobjlen, int ndepth);
|
||||
size_t nobjlen, int ndepth);
|
||||
size_t *len = (size_t *) entry->arg;
|
||||
int r = 0;
|
||||
|
||||
|
@ -1158,7 +1215,7 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry,
|
|||
case SC_ASN1_ENUMERATED:
|
||||
if (parm != NULL) {
|
||||
r = sc_asn1_decode_integer(obj, objlen, (int *) entry->parm);
|
||||
sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sdecoding '%s' returned %d\n", depth, depth, "",
|
||||
sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sdecoding '%s' returned %d\n", depth, depth, "",
|
||||
entry->name, *((int *) entry->parm));
|
||||
}
|
||||
break;
|
||||
|
@ -1273,7 +1330,7 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry,
|
|||
if (entry->parm != NULL) {
|
||||
struct sc_pkcs15_id *id = (struct sc_pkcs15_id *) parm;
|
||||
size_t c = objlen > sizeof(id->value) ? sizeof(id->value) : objlen;
|
||||
|
||||
|
||||
memcpy(id->value, obj, c);
|
||||
id->len = c;
|
||||
}
|
||||
|
@ -1339,8 +1396,7 @@ static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
|
|||
for (idx = 0; asn1[idx].name != NULL; idx++) {
|
||||
entry = &asn1[idx];
|
||||
|
||||
sc_debug(ctx, SC_LOG_DEBUG_ASN1,
|
||||
"Looking for '%s', tag 0x%x%s%s\n",
|
||||
sc_debug(ctx, SC_LOG_DEBUG_ASN1, "Looking for '%s', tag 0x%x%s%s\n",
|
||||
entry->name, entry->tag, choice? ", CHOICE" : "",
|
||||
(entry->flags & SC_ASN1_OPTIONAL)? ", OPTIONAL": "");
|
||||
|
||||
|
@ -1546,6 +1602,11 @@ static int asn1_encode_entry(sc_context_t *ctx, const struct sc_asn1_entry *entr
|
|||
case SC_ASN1_ALGORITHM_ID:
|
||||
r = sc_asn1_encode_algorithm_id(ctx, &buf, &buflen, (const struct sc_algorithm_id *) parm, depth);
|
||||
break;
|
||||
case SC_ASN1_SE_INFO:
|
||||
if (!len)
|
||||
return SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
r = asn1_encode_se_info(ctx, (struct sc_pkcs15_sec_env_info **)parm, *len, &buf, &buflen, depth);
|
||||
break;
|
||||
case SC_ASN1_CALLBACK:
|
||||
r = callback_func(ctx, entry->arg, &buf, &buflen, depth);
|
||||
break;
|
||||
|
@ -1572,8 +1633,7 @@ static int asn1_encode_entry(sc_context_t *ctx, const struct sc_asn1_entry *entr
|
|||
* - any other empty objects are considered bogus
|
||||
*/
|
||||
no_object:
|
||||
if (!buflen && entry->flags & SC_ASN1_OPTIONAL &&
|
||||
!(entry->flags & SC_ASN1_PRESENT)) {
|
||||
if (!buflen && entry->flags & SC_ASN1_OPTIONAL && !(entry->flags & SC_ASN1_PRESENT)) {
|
||||
/* This happens when we try to encode e.g. the
|
||||
* subClassAttributes, which may be empty */
|
||||
*obj = NULL;
|
||||
|
@ -1584,11 +1644,9 @@ no_object:
|
|||
*objlen = 0;
|
||||
r = asn1_write_element(ctx, entry->tag, buf, buflen, obj, objlen);
|
||||
if (r)
|
||||
sc_debug(ctx, SC_LOG_DEBUG_ASN1, "error writing ASN.1 tag and length: %s\n", sc_strerror(r));
|
||||
} else if (buflen || entry->type == SC_ASN1_NULL ||
|
||||
entry->tag & SC_ASN1_CONS) {
|
||||
r = asn1_write_element(ctx, entry->tag,
|
||||
buf, buflen, obj, objlen);
|
||||
sc_debug(ctx, SC_LOG_DEBUG_ASN1, "error writing ASN.1 tag and length: %s\n", sc_strerror(r));
|
||||
} else if (buflen || entry->type == SC_ASN1_NULL || entry->tag & SC_ASN1_CONS) {
|
||||
r = asn1_write_element(ctx, entry->tag, buf, buflen, obj, objlen);
|
||||
if (r)
|
||||
sc_debug(ctx, SC_LOG_DEBUG_ASN1, "error writing ASN.1 tag and length: %s\n",
|
||||
sc_strerror(r));
|
||||
|
@ -1680,7 +1738,7 @@ sc_der_copy(sc_pkcs15_der_t *dst, const sc_pkcs15_der_t *src)
|
|||
}
|
||||
|
||||
int
|
||||
sc_encode_oid (struct sc_context *ctx, struct sc_object_id *id,
|
||||
sc_encode_oid (struct sc_context *ctx, struct sc_object_id *id,
|
||||
unsigned char **out, size_t *size)
|
||||
{
|
||||
static const struct sc_asn1_entry c_asn1_object_id[2] = {
|
||||
|
|
|
@ -191,6 +191,7 @@ sc_pkcs15_get_guid
|
|||
sc_pkcs15_get_object_id
|
||||
sc_pkcs15_get_objects
|
||||
sc_pkcs15_get_objects_cond
|
||||
sc_pkcs15_get_lastupdate
|
||||
sc_pkcs15_hex_string_to_id
|
||||
sc_pkcs15_is_emulation_only
|
||||
sc_pkcs15_make_absolute_path
|
||||
|
|
|
@ -59,13 +59,13 @@ static int generate_cache_filename(struct sc_pkcs15_card *p15card,
|
|||
for (i = 0; i < pathlen; i++)
|
||||
sprintf(pathname + 2*i, "%02X", pathptr[i]);
|
||||
if (p15card->tokeninfo->serial_number != NULL) {
|
||||
if (p15card->tokeninfo->last_update != NULL)
|
||||
r = snprintf(buf, bufsize, "%s/%s_%s_%s", dir,
|
||||
p15card->tokeninfo->serial_number, p15card->tokeninfo->last_update,
|
||||
pathname);
|
||||
char *last_update = sc_pkcs15_get_lastupdate(p15card);
|
||||
if (last_update != NULL)
|
||||
r = snprintf(buf, bufsize, "%s/%s_%s_%s", dir, p15card->tokeninfo->serial_number,
|
||||
last_update, pathname);
|
||||
else
|
||||
r = snprintf(buf, bufsize, "%s/%s_DATE_%s", dir,
|
||||
p15card->tokeninfo->serial_number, pathname);
|
||||
p15card->tokeninfo->serial_number, pathname);
|
||||
if (r < 0)
|
||||
return SC_ERROR_BUFFER_TOO_SMALL;
|
||||
} else
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,9 +34,9 @@ extern "C" {
|
|||
#define SC_PKCS15_MAX_LABEL_SIZE 255
|
||||
#define SC_PKCS15_MAX_ID_SIZE 255
|
||||
|
||||
/* When changing this value, change also initialisation of the
|
||||
/* When changing this value, change also initialisation of the
|
||||
* static ASN1 variables, that use this macro,
|
||||
* like for example, 'c_asn1_access_control_rules'
|
||||
* like for example, 'c_asn1_access_control_rules'
|
||||
* in src/libopensc/asn1.c */
|
||||
#define SC_PKCS15_MAX_ACCESS_RULES 8
|
||||
|
||||
|
@ -64,7 +64,7 @@ typedef struct sc_pkcs15_id sc_pkcs15_id_t;
|
|||
#define SC_PKCS15_PIN_FLAG_EXCHANGE_REF_DATA 0x0800
|
||||
|
||||
#define SC_PKCS15_PIN_TYPE_FLAGS_MASK \
|
||||
( SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_INITIALIZED \
|
||||
( SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_INITIALIZED \
|
||||
| SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN | SC_PKCS15_PIN_FLAG_SO_PIN )
|
||||
|
||||
#define SC_PKCS15_PIN_TYPE_FLAGS_SOPIN \
|
||||
|
@ -77,11 +77,11 @@ typedef struct sc_pkcs15_id sc_pkcs15_id_t;
|
|||
( SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL)
|
||||
|
||||
#define SC_PKCS15_PIN_TYPE_FLAGS_PUK_GLOBAL \
|
||||
( SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN \
|
||||
( SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN \
|
||||
| SC_PKCS15_PIN_FLAG_INITIALIZED )
|
||||
|
||||
#define SC_PKCS15_PIN_TYPE_FLAGS_PUK_LOCAL \
|
||||
( SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN \
|
||||
( SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN \
|
||||
| SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_LOCAL)
|
||||
|
||||
#define SC_PKCS15_PIN_TYPE_BCD 0
|
||||
|
@ -94,7 +94,6 @@ typedef struct sc_pkcs15_id sc_pkcs15_id_t;
|
|||
#define SC_PKCS15_PIN_AUTH_TYPE_BIOMETRIC 1
|
||||
#define SC_PKCS15_PIN_AUTH_TYPE_AUTH_KEY 2
|
||||
#define SC_PKCS15_PIN_AUTH_TYPE_SM_KEY 3
|
||||
|
||||
/* PinAttributes as they defined in PKCS#15 v1.1 for PIN authentication object */
|
||||
struct sc_pkcs15_pin_attributes {
|
||||
unsigned int flags, type;
|
||||
|
@ -194,7 +193,7 @@ struct sc_pkcs15_prkey_dsa {
|
|||
sc_pkcs15_bignum_t priv;
|
||||
};
|
||||
|
||||
/*
|
||||
/*
|
||||
* The ecParameters can be presented as
|
||||
* - named curve;
|
||||
* - OID of named curve;
|
||||
|
@ -333,6 +332,18 @@ typedef struct sc_pkcs15_data_info sc_pkcs15_data_info_t;
|
|||
#define SC_PKCS15_PRKEY_USAGE_DERIVE 0x100
|
||||
#define SC_PKCS15_PRKEY_USAGE_NONREPUDIATION 0x200
|
||||
|
||||
/* keyUsageFlags are the same for all key types */
|
||||
#define SC_PKCS15_KEY_USAGE_ENCRYPT 0x01
|
||||
#define SC_PKCS15_KEY_USAGE_DECRYPT 0x02
|
||||
#define SC_PKCS15_KEY_USAGE_SIGN 0x04
|
||||
#define SC_PKCS15_KEY_USAGE_SIGNRECOVER 0x08
|
||||
#define SC_PKCS15_KEY_USAGE_WRAP 0x10
|
||||
#define SC_PKCS15_KEY_USAGE_UNWRAP 0x20
|
||||
#define SC_PKCS15_KEY_USAGE_VERIFY 0x40
|
||||
#define SC_PKCS15_KEY_USAGE_VERIFYRECOVER 0x80
|
||||
#define SC_PKCS15_KEY_USAGE_DERIVE 0x100
|
||||
#define SC_PKCS15_KEY_USAGE_NONREPUDIATION 0x200
|
||||
|
||||
#define SC_PKCS15_PRKEY_ACCESS_SENSITIVE 0x01
|
||||
#define SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE 0x02
|
||||
#define SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE 0x04
|
||||
|
@ -453,12 +464,16 @@ typedef struct sc_pkcs15_skey_info sc_pkcs15_skey_info_t;
|
|||
#define SC_PKCS15_TYPE_CERT_SPKI 0x402
|
||||
|
||||
#define SC_PKCS15_TYPE_DATA_OBJECT 0x500
|
||||
|
||||
#define SC_PKCS15_TYPE_AUTH 0x600
|
||||
#define SC_PKCS15_TYPE_AUTH_PIN 0x601
|
||||
#define SC_PKCS15_TYPE_AUTH_BIO 0x602
|
||||
#define SC_PKCS15_TYPE_AUTH_AUTHKEY 0x603
|
||||
|
||||
#define SC_PKCS15_TYPE_TO_CLASS(t) (1 << ((t) >> 8))
|
||||
#define SC_PKCS15_SEARCH_CLASS_PRKEY 0x0002U
|
||||
#define SC_PKCS15_SEARCH_CLASS_PUBKEY 0x0004U
|
||||
#define SC_PKCS15_SEARCH_CLASS_SKEY 0x0008U
|
||||
#define SC_PKCS15_SEARCH_CLASS_CERT 0x0010U
|
||||
#define SC_PKCS15_SEARCH_CLASS_DATA 0x0020U
|
||||
#define SC_PKCS15_SEARCH_CLASS_AUTH 0x0040U
|
||||
|
@ -480,11 +495,13 @@ struct sc_pkcs15_object {
|
|||
/* emulated object pointer */
|
||||
void *emulated;
|
||||
|
||||
|
||||
struct sc_pkcs15_df *df; /* can be NULL, if object is 'floating' */
|
||||
struct sc_pkcs15_object *next, *prev; /* used only internally */
|
||||
|
||||
|
||||
struct sc_pkcs15_der content;
|
||||
|
||||
/* Used by minidriver and its on-card support */
|
||||
char *guid;
|
||||
};
|
||||
typedef struct sc_pkcs15_object sc_pkcs15_object_t;
|
||||
|
||||
|
@ -528,13 +545,27 @@ typedef struct sc_pkcs15_sec_env_info {
|
|||
struct sc_aid aid;
|
||||
} sc_pkcs15_sec_env_info_t;
|
||||
|
||||
typedef struct sc_pkcs15_last_update {
|
||||
char *gtime;
|
||||
struct sc_path path;
|
||||
|
||||
} sc_pkcs15_last_update_t;
|
||||
|
||||
typedef struct sc_pkcs15_profile_indication {
|
||||
struct sc_object_id oid;
|
||||
char *name;
|
||||
} sc_pkcs15_profile_indication_t;
|
||||
|
||||
typedef struct sc_pkcs15_tokeninfo {
|
||||
unsigned int version;
|
||||
unsigned int flags;
|
||||
char *label;
|
||||
char *serial_number;
|
||||
char *manufacturer_id;
|
||||
char *last_update;
|
||||
char *manufacturer_id;
|
||||
|
||||
struct sc_pkcs15_last_update last_update;
|
||||
struct sc_pkcs15_profile_indication profile_indication;
|
||||
|
||||
char *preferred_language;
|
||||
sc_pkcs15_sec_env_info_t **seInfo;
|
||||
size_t num_seInfo;
|
||||
|
@ -545,7 +576,7 @@ typedef struct sc_pkcs15_tokeninfo {
|
|||
struct sc_pkcs15_operations {
|
||||
int (*parse_df)(struct sc_pkcs15_card *, struct sc_pkcs15_df *);
|
||||
void (*clear)(struct sc_pkcs15_card *);
|
||||
int (*get_guid)(struct sc_pkcs15_card *, const struct sc_pkcs15_object *,
|
||||
int (*get_guid)(struct sc_pkcs15_card *, const struct sc_pkcs15_object *,
|
||||
char *, size_t);
|
||||
};
|
||||
|
||||
|
@ -617,6 +648,11 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
|||
unsigned long flags,
|
||||
const u8 *in, size_t inlen, u8 *out, size_t outlen);
|
||||
|
||||
int sc_pkcs15_derive(struct sc_pkcs15_card *p15card,
|
||||
const struct sc_pkcs15_object *prkey_obj,
|
||||
unsigned long flags,
|
||||
const u8 *in, size_t inlen, u8 *out, unsigned long *poutlen);
|
||||
|
||||
int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
|
||||
const struct sc_pkcs15_object *prkey_obj,
|
||||
unsigned long alg_flags, const u8 *in,
|
||||
|
@ -649,11 +685,11 @@ int sc_pkcs15_encode_pubkey(struct sc_context *,
|
|||
struct sc_pkcs15_pubkey *, u8 **, size_t *);
|
||||
void sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *);
|
||||
void sc_pkcs15_free_pubkey(struct sc_pkcs15_pubkey *);
|
||||
int sc_pkcs15_pubkey_from_prvkey(struct sc_context *, struct sc_pkcs15_prkey *,
|
||||
int sc_pkcs15_pubkey_from_prvkey(struct sc_context *, struct sc_pkcs15_prkey *,
|
||||
struct sc_pkcs15_pubkey **);
|
||||
int sc_pkcs15_pubkey_from_cert(struct sc_context *, struct sc_pkcs15_der *,
|
||||
int sc_pkcs15_pubkey_from_cert(struct sc_context *, struct sc_pkcs15_der *,
|
||||
struct sc_pkcs15_pubkey **);
|
||||
int sc_pkcs15_pubkey_from_spki_filename(struct sc_context *,
|
||||
int sc_pkcs15_pubkey_from_spki_filename(struct sc_context *,
|
||||
char *, sc_pkcs15_pubkey_t ** );
|
||||
int sc_pkcs15_pubkey_from_spki(struct sc_context *,
|
||||
sc_pkcs15_pubkey_t **, u8 *, size_t, int);
|
||||
|
@ -706,6 +742,9 @@ int sc_pkcs15_find_prkey_by_reference(sc_pkcs15_card_t *,
|
|||
int sc_pkcs15_find_pubkey_by_id(struct sc_pkcs15_card *card,
|
||||
const struct sc_pkcs15_id *id,
|
||||
struct sc_pkcs15_object **out);
|
||||
int sc_pkcs15_find_skey_by_id(struct sc_pkcs15_card *card,
|
||||
const struct sc_pkcs15_id *id,
|
||||
struct sc_pkcs15_object **out);
|
||||
|
||||
int sc_pkcs15_verify_pin(struct sc_pkcs15_card *card,
|
||||
struct sc_pkcs15_object *pin_obj,
|
||||
|
@ -731,8 +770,8 @@ int sc_pkcs15_find_pin_by_type_and_reference(struct sc_pkcs15_card *card,
|
|||
int sc_pkcs15_find_so_pin(struct sc_pkcs15_card *card,
|
||||
struct sc_pkcs15_object **out);
|
||||
int sc_pkcs15_find_pin_by_flags(struct sc_pkcs15_card *p15card,
|
||||
unsigned flags, unsigned mask, int *index,
|
||||
struct sc_pkcs15_object **out);
|
||||
unsigned flags, unsigned mask, int *index,
|
||||
struct sc_pkcs15_object **out);
|
||||
|
||||
void sc_pkcs15_pincache_add(struct sc_pkcs15_card *, struct sc_pkcs15_object *,
|
||||
const u8 *, size_t);
|
||||
|
@ -791,6 +830,9 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card,
|
|||
int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card,
|
||||
struct sc_pkcs15_object *obj,
|
||||
const u8 **buf, size_t *bufsize);
|
||||
int sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card,
|
||||
struct sc_pkcs15_object *obj,
|
||||
const u8 **buf, size_t *bufsize);
|
||||
|
||||
int sc_pkcs15_decode_enveloped_data(struct sc_context *ctx,
|
||||
struct sc_pkcs15_enveloped_data *result,
|
||||
|
@ -804,19 +846,19 @@ int sc_pkcs15_add_object(struct sc_pkcs15_card *p15card,
|
|||
void sc_pkcs15_remove_object(struct sc_pkcs15_card *p15card,
|
||||
struct sc_pkcs15_object *obj);
|
||||
int sc_pkcs15_add_df(struct sc_pkcs15_card *, unsigned int, const sc_path_t *);
|
||||
void sc_pkcs15_remove_df(struct sc_pkcs15_card *p15card,
|
||||
struct sc_pkcs15_df *df);
|
||||
|
||||
int sc_pkcs15_add_unusedspace(struct sc_pkcs15_card *p15card,
|
||||
const sc_path_t *path, const sc_pkcs15_id_t *auth_id);
|
||||
void sc_pkcs15_remove_unusedspace(struct sc_pkcs15_card *p15card,
|
||||
sc_pkcs15_unusedspace_t *obj);
|
||||
int sc_pkcs15_parse_unusedspace(const u8 * buf, size_t buflen,
|
||||
struct sc_pkcs15_card *card);
|
||||
int sc_pkcs15_encode_unusedspace(sc_context_t *ctx,
|
||||
struct sc_pkcs15_card *p15card,
|
||||
u8 **buf, size_t *buflen);
|
||||
|
||||
/* Deduce private key attributes from cerresponding certificate */
|
||||
int sc_pkcs15_prkey_attrs_from_cert(struct sc_pkcs15_card *, struct sc_pkcs15_object *,
|
||||
struct sc_pkcs15_object **);
|
||||
|
||||
void sc_pkcs15_free_prkey_info(sc_pkcs15_prkey_info_t *key);
|
||||
void sc_pkcs15_free_pubkey_info(sc_pkcs15_pubkey_info_t *key);
|
||||
void sc_pkcs15_free_cert_info(sc_pkcs15_cert_info_t *cert);
|
||||
|
@ -845,9 +887,9 @@ void sc_pkcs15_format_id(const char *id_in, struct sc_pkcs15_id *id_out);
|
|||
int sc_pkcs15_hex_string_to_id(const char *in, struct sc_pkcs15_id *out);
|
||||
int sc_der_copy(sc_pkcs15_der_t *, const sc_pkcs15_der_t *);
|
||||
int sc_pkcs15_get_object_id(const struct sc_pkcs15_object *, struct sc_pkcs15_id *);
|
||||
int sc_pkcs15_get_guid(struct sc_pkcs15_card *, const struct sc_pkcs15_object *,
|
||||
int sc_pkcs15_get_guid(struct sc_pkcs15_card *, const struct sc_pkcs15_object *, unsigned,
|
||||
char *, size_t);
|
||||
int sc_encode_oid (struct sc_context *, struct sc_object_id *,
|
||||
int sc_encode_oid (struct sc_context *, struct sc_object_id *,
|
||||
unsigned char **, size_t *);
|
||||
|
||||
/* Get application by type: 'protected', 'generic' */
|
||||
|
@ -870,6 +912,14 @@ int sc_pkcs15_add_supported_algo_ref(struct sc_pkcs15_object *,
|
|||
|
||||
int sc_pkcs15_fix_ec_parameters(struct sc_context *, struct sc_pkcs15_ec_parameters *);
|
||||
|
||||
/* Convert the OpenSSL key data type into the OpenSC key */
|
||||
int sc_pkcs15_convert_bignum(sc_pkcs15_bignum_t *dst, const void *bignum);
|
||||
int sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *key, void *evp_key);
|
||||
int sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *key, void *evp_key);
|
||||
|
||||
/* Get 'LastUpdate' string */
|
||||
char *sc_pkcs15_get_lastupdate(struct sc_pkcs15_card *p15card);
|
||||
|
||||
/* New object search API.
|
||||
* More complex, but also more powerful.
|
||||
*/
|
||||
|
|
|
@ -43,12 +43,13 @@ typedef unsigned char u8;
|
|||
#define SC_MAX_PATH_STRING_SIZE (SC_MAX_PATH_SIZE * 2 + 3)
|
||||
#define SC_MAX_SDO_ACLS 8
|
||||
#define SC_MAX_CRTS_IN_SE 12
|
||||
#define SC_MAX_SE_NUM 8
|
||||
|
||||
/* When changing this value, pay attention to the initialization of the ASN1
|
||||
* static variables that use this macro, like, for example,
|
||||
* 'c_asn1_supported_algorithms' in src/libopensc/pkcs15.c
|
||||
*/
|
||||
#define SC_MAX_SUPPORTED_ALGORITHMS 8
|
||||
#define SC_MAX_SUPPORTED_ALGORITHMS 8
|
||||
|
||||
struct sc_lv_data {
|
||||
unsigned char *value;
|
||||
|
@ -311,13 +312,11 @@ typedef struct sc_serial_number {
|
|||
|
||||
/**
|
||||
* @struct sc_remote_apdu data
|
||||
* Structure to supply the linked APDU data used in
|
||||
* Structure to supply the linked APDU data used in
|
||||
* communication with the external (SM) modules.
|
||||
*/
|
||||
#define SC_REMOTE_APDU_FLAG_FATAL
|
||||
#define SC_REMOTE_APDU_FLAG_LAST
|
||||
#define SC_REMOTE_APDU_FLAG_RETURN_ANSWER
|
||||
#define SC_REMOTE_APDU_FLAG_GET_RESPONSE
|
||||
#define SC_REMOTE_APDU_FLAG_NOT_FATAL 0x01
|
||||
#define SC_REMOTE_APDU_FLAG_RETURN_ANSWER 0x02
|
||||
struct sc_remote_apdu {
|
||||
unsigned char sbuf[2*SC_MAX_APDU_BUFFER_SIZE];
|
||||
unsigned char rbuf[2*SC_MAX_APDU_BUFFER_SIZE];
|
||||
|
|
|
@ -97,6 +97,8 @@ static int sc_pkcs15init_update_dir(struct sc_pkcs15_card *,
|
|||
struct sc_app_info *app);
|
||||
static int sc_pkcs15init_update_tokeninfo(struct sc_pkcs15_card *,
|
||||
struct sc_profile *profile);
|
||||
static int sc_pkcs15init_update_lastupdate(struct sc_pkcs15_card *,
|
||||
struct sc_profile *profile);
|
||||
static int sc_pkcs15init_update_odf(struct sc_pkcs15_card *,
|
||||
struct sc_profile *profile);
|
||||
static int sc_pkcs15init_map_usage(unsigned long, int);
|
||||
|
@ -406,8 +408,10 @@ sc_pkcs15init_unbind(struct sc_profile *profile)
|
|||
int r;
|
||||
struct sc_context *ctx = profile->card->ctx;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
sc_log(ctx, "Pksc15init Unbind: %i:%p:%i", profile->dirty, profile->p15_data, profile->pkcs15.do_last_update);
|
||||
if (profile->dirty != 0 && profile->p15_data != NULL && profile->pkcs15.do_last_update) {
|
||||
r = sc_pkcs15init_update_tokeninfo(profile->p15_data, profile);
|
||||
r = sc_pkcs15init_update_lastupdate(profile->p15_data, profile);
|
||||
if (r < 0)
|
||||
sc_log(ctx, "Failed to update TokenInfo: %s", sc_strerror(r));
|
||||
}
|
||||
|
@ -2462,8 +2466,7 @@ get_generalized_time(struct sc_context *ctx)
|
|||
|
||||
|
||||
static int
|
||||
sc_pkcs15init_update_tokeninfo(struct sc_pkcs15_card *p15card,
|
||||
struct sc_profile *profile)
|
||||
sc_pkcs15init_update_tokeninfo(struct sc_pkcs15_card *p15card, struct sc_profile *profile)
|
||||
{
|
||||
struct sc_card *card = p15card->card;
|
||||
struct sc_pkcs15_tokeninfo tokeninfo;
|
||||
|
@ -2472,10 +2475,10 @@ sc_pkcs15init_update_tokeninfo(struct sc_pkcs15_card *p15card,
|
|||
int r;
|
||||
|
||||
/* set lastUpdate field */
|
||||
if (p15card->tokeninfo->last_update != NULL)
|
||||
free(p15card->tokeninfo->last_update);
|
||||
p15card->tokeninfo->last_update = get_generalized_time(card->ctx);
|
||||
if (p15card->tokeninfo->last_update == NULL)
|
||||
if (p15card->tokeninfo->last_update.gtime != NULL)
|
||||
free(p15card->tokeninfo->last_update.gtime);
|
||||
p15card->tokeninfo->last_update.gtime = get_generalized_time(card->ctx);
|
||||
if (p15card->tokeninfo->last_update.gtime == NULL)
|
||||
return SC_ERROR_INTERNAL;
|
||||
|
||||
tokeninfo = *(p15card->tokeninfo);
|
||||
|
@ -2491,6 +2494,56 @@ sc_pkcs15init_update_tokeninfo(struct sc_pkcs15_card *p15card,
|
|||
return r;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sc_pkcs15init_update_lastupdate(struct sc_pkcs15_card *p15card, struct sc_profile *profile)
|
||||
{
|
||||
struct sc_context *ctx = p15card->card->ctx;
|
||||
int r;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
if (p15card->tokeninfo->last_update.path.len) {
|
||||
static const struct sc_asn1_entry c_asn1_last_update[2] = {
|
||||
{ "generalizedTime", SC_ASN1_GENERALIZEDTIME, SC_ASN1_TAG_GENERALIZEDTIME, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL }
|
||||
};
|
||||
struct sc_asn1_entry asn1_last_update[2];
|
||||
size_t lupdate_len;
|
||||
struct sc_file *file = NULL;
|
||||
struct sc_pkcs15_last_update *last_update = &p15card->tokeninfo->last_update;
|
||||
unsigned char *buf = NULL;
|
||||
size_t buflen;
|
||||
|
||||
/* update 'lastUpdate' file */
|
||||
if (last_update->gtime != NULL)
|
||||
free(last_update->gtime);
|
||||
last_update->gtime = get_generalized_time(ctx);
|
||||
if (last_update->gtime == NULL)
|
||||
return SC_ERROR_INTERNAL;
|
||||
|
||||
sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update);
|
||||
lupdate_len = strlen(last_update->gtime);
|
||||
sc_format_asn1_entry(asn1_last_update + 0, last_update->gtime, &lupdate_len, 1);
|
||||
|
||||
r = sc_asn1_encode(ctx, asn1_last_update, &buf, &buflen);
|
||||
LOG_TEST_RET(ctx, r, "select object path failed");
|
||||
|
||||
r = sc_select_file(p15card->card, &last_update->path, &file);
|
||||
LOG_TEST_RET(ctx, r, "select object path failed");
|
||||
|
||||
r = sc_pkcs15init_update_file(profile, p15card, file, buf, buflen);
|
||||
sc_file_free(file);
|
||||
if (buf)
|
||||
free(buf);
|
||||
LOG_TEST_RET(ctx, r, "Cannot update 'LastUpdate' file");
|
||||
LOG_FUNC_RETURN(ctx, r);
|
||||
}
|
||||
|
||||
r = sc_pkcs15init_update_tokeninfo(p15card, profile);
|
||||
LOG_FUNC_RETURN(ctx, r);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sc_pkcs15init_update_odf(struct sc_pkcs15_card *p15card,
|
||||
struct sc_profile *profile)
|
||||
|
|
|
@ -222,7 +222,7 @@ static void print_cert_info(const struct sc_pkcs15_object *obj)
|
|||
printf("\tPath : %s\n", sc_print_path(&cert_info->path));
|
||||
printf("\tID : %s\n", sc_pkcs15_print_id(&cert_info->id));
|
||||
|
||||
rv = sc_pkcs15_get_guid(p15card, obj, guid, sizeof(guid));
|
||||
rv = sc_pkcs15_get_guid(p15card, obj, 0, guid, sizeof(guid));
|
||||
if (!rv)
|
||||
printf("\tGUID : %s\n", guid);
|
||||
|
||||
|
@ -536,7 +536,7 @@ static void print_prkey_info(const struct sc_pkcs15_object *obj)
|
|||
printf("\tAuth ID : %s\n", sc_pkcs15_print_id(&obj->auth_id));
|
||||
printf("\tID : %s\n", sc_pkcs15_print_id(&prkey->id));
|
||||
|
||||
if (!sc_pkcs15_get_guid(p15card, obj, guid, sizeof(guid)))
|
||||
if (!sc_pkcs15_get_guid(p15card, obj, 0, guid, sizeof(guid)))
|
||||
printf("\tGUID : %s\n", guid);
|
||||
|
||||
}
|
||||
|
@ -1158,17 +1158,19 @@ static int dump(void)
|
|||
"PRN generation",
|
||||
"EID compliant"
|
||||
};
|
||||
|
||||
char *last_update = sc_pkcs15_get_lastupdate(p15card);
|
||||
int i, count = 0;
|
||||
|
||||
printf("PKCS#15 Card [%s]:\n", p15card->tokeninfo->label);
|
||||
printf("\tVersion : %d\n", p15card->tokeninfo->version);
|
||||
printf("\tSerial number : %s\n", p15card->tokeninfo->serial_number);
|
||||
printf("\tManufacturer ID: %s\n", p15card->tokeninfo->manufacturer_id);
|
||||
if (p15card->tokeninfo->last_update)
|
||||
printf("\tLast update : %s\n", p15card->tokeninfo->last_update);
|
||||
if (last_update)
|
||||
printf("\tLast update : %s\n", last_update);
|
||||
if (p15card->tokeninfo->preferred_language)
|
||||
printf("\tLanguage : %s\n", p15card->tokeninfo->preferred_language);
|
||||
if (p15card->tokeninfo->profile_indication.name)
|
||||
printf("\tProfile : %s\n", p15card->tokeninfo->profile_indication.name);
|
||||
printf("\tFlags : ");
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((p15card->tokeninfo->flags >> i) & 1) {
|
||||
|
|
Loading…
Reference in New Issue