libopensc: 'init', 'format', 'compare', 'is-valid' OID procedures
In a reason of number of bugs(*) that concern the OID management,
the general usage OID procedures 'init', 'format', 'compare', 'is-valid' are introduced.
These procedures should be used by all actors: libopensc, pkcs15, pkcs11, tools, ....
(*)
This bug reported by Andreas Schwier :
8e75d971cb (commitcomment-1792477)
In pkcs15-algo sc_asn1_get_algorithm_info() can return the OID without ending '-1's:
https://github.com/OpenSC/OpenSC/blob/staging/src/libopensc/pkcs15-algo.c#L452
https://github.com/OpenSC/OpenSC/blob/staging/src/libopensc/pkcs15-algo.c#L459
This commit is contained in:
parent
d5ee8a80b5
commit
58b4304957
|
@ -207,23 +207,23 @@ static void sc_asn1_print_bit_string(const u8 * buf, size_t buflen)
|
|||
|
||||
static void sc_asn1_print_object_id(const u8 * buf, size_t buflen)
|
||||
{
|
||||
int i = 0;
|
||||
struct sc_object_id oid;
|
||||
int i = 0;
|
||||
char sbuf[256];
|
||||
|
||||
if (sc_asn1_decode_object_id(buf, buflen, &oid)) {
|
||||
printf("decode error");
|
||||
return;
|
||||
}
|
||||
|
||||
sbuf[0] = 0;
|
||||
while (oid.value[i] >= 0) {
|
||||
for (i = 0; (i < SC_MAX_OBJECT_ID_OCTETS) && (oid.value[i] != -1); i++) {
|
||||
char tmp[12];
|
||||
|
||||
if (i)
|
||||
strcat(sbuf, ".");
|
||||
sprintf(tmp, "%d", oid.value[i]);
|
||||
strcat(sbuf, tmp);
|
||||
i++;
|
||||
}
|
||||
printf("%s", sbuf);
|
||||
}
|
||||
|
@ -636,18 +636,19 @@ static int asn1_encode_integer(int in, u8 ** obj, size_t * objsize)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sc_asn1_decode_object_id(const u8 * inbuf, size_t inlen,
|
||||
struct sc_object_id *id)
|
||||
int
|
||||
sc_asn1_decode_object_id(const u8 *inbuf, size_t inlen, struct sc_object_id *id)
|
||||
{
|
||||
int i, a;
|
||||
int a;
|
||||
const u8 *p = inbuf;
|
||||
int *octet;
|
||||
|
||||
if (inlen == 0 || inbuf == NULL || id == NULL)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
sc_init_oid(id);
|
||||
octet = id->value;
|
||||
for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++)
|
||||
id->value[i] = -1;
|
||||
|
||||
a = *p;
|
||||
*octet++ = a / 40;
|
||||
*octet++ = a % 40;
|
||||
|
@ -664,31 +665,35 @@ int sc_asn1_decode_object_id(const u8 * inbuf, size_t inlen,
|
|||
inlen--;
|
||||
}
|
||||
*octet++ = a;
|
||||
if (octet - id->value >= SC_MAX_OBJECT_ID_OCTETS-1)
|
||||
if (octet - id->value >= SC_MAX_OBJECT_ID_OCTETS) {
|
||||
sc_init_oid(id);
|
||||
return SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
}
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sc_asn1_encode_object_id(u8 **buf, size_t *buflen,
|
||||
const struct sc_object_id *id)
|
||||
int
|
||||
sc_asn1_encode_object_id(u8 **buf, size_t *buflen, const struct sc_object_id *id)
|
||||
{
|
||||
u8 temp[SC_MAX_OBJECT_ID_OCTETS*5], *p = temp;
|
||||
size_t count = 0;
|
||||
int i;
|
||||
int value[SC_MAX_OBJECT_ID_OCTETS];
|
||||
|
||||
/* set the unused ID part to '-1' */
|
||||
memcpy(value, &id->value[0], sizeof(value));
|
||||
for (i = SC_MAX_OBJECT_ID_OCTETS - 1; i>=0; i--)
|
||||
if (!value[i])
|
||||
value[i] = -1;
|
||||
if (!buflen || !id)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS && value[i] >= 0; i++) {
|
||||
/* an OID must have at least two components */
|
||||
if (id->value[0] == -1 || id->value[1] == -1)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++) {
|
||||
unsigned int k, shift;
|
||||
|
||||
k = value[i];
|
||||
if (id->value[i] == -1)
|
||||
break;
|
||||
|
||||
k = id->value[i];
|
||||
switch (i) {
|
||||
case 0:
|
||||
if (k > 2)
|
||||
|
@ -712,14 +717,15 @@ int sc_asn1_encode_object_id(u8 **buf, size_t *buflen,
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (i == 1)
|
||||
/* an OID must have at least two components */
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
*buflen = count = p - temp;
|
||||
*buf = malloc(count);
|
||||
if (!*buf)
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
memcpy(*buf, temp, count);
|
||||
|
||||
*buflen = p - temp;
|
||||
|
||||
if (buf) {
|
||||
*buf = malloc(*buflen);
|
||||
if (!*buf)
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
memcpy(*buf, temp, *buflen);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -953,7 +959,7 @@ static int asn1_decode_se_info(sc_context_t *ctx, const u8 *obj, size_t objlen,
|
|||
{
|
||||
struct sc_pkcs15_sec_env_info **ses;
|
||||
const unsigned char *ptr = obj;
|
||||
size_t i, idx, ptrlen = objlen;
|
||||
size_t idx, ptrlen = objlen;
|
||||
int ret;
|
||||
|
||||
ses = calloc(SC_MAX_SE_NUM, sizeof(sc_pkcs15_sec_env_info_t *));
|
||||
|
@ -978,8 +984,7 @@ static int asn1_decode_se_info(sc_context_t *ctx, const u8 *obj, size_t objlen,
|
|||
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;
|
||||
sc_init_oid(&si.owner);
|
||||
|
||||
ses[idx] = calloc(1, sizeof(sc_pkcs15_sec_env_info_t));
|
||||
if (ses[idx] == NULL) {
|
||||
|
@ -996,6 +1001,7 @@ static int asn1_decode_se_info(sc_context_t *ctx, const u8 *obj, size_t objlen,
|
|||
ret = SC_SUCCESS;
|
||||
err:
|
||||
if (ret != SC_SUCCESS) {
|
||||
int i;
|
||||
for (i = 0; i < idx; i++)
|
||||
if (ses[i])
|
||||
free(ses[i]);
|
||||
|
@ -1022,7 +1028,7 @@ static int asn1_encode_se_info(sc_context_t *ctx,
|
|||
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)
|
||||
if (sc_valid_oid(&se[idx]->owner))
|
||||
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);
|
||||
|
|
|
@ -95,9 +95,14 @@ sc_parse_ef_atr_content(struct sc_card *card, unsigned char *buf, size_t buflen)
|
|||
}
|
||||
|
||||
tag = sc_asn1_find_tag(ctx, buf, buflen, ISO7816_TAG_II_ALLOCATION_SCHEME, &taglen);
|
||||
if (tag && taglen < sizeof(ef_atr.allocation_oid)) {
|
||||
sc_log(ctx, "EF.ATR: OID %s", sc_dump_hex(tag, sizeof(taglen)));
|
||||
memcpy(ef_atr.allocation_oid.value, tag, taglen);
|
||||
if (tag) {
|
||||
sc_log(ctx, "EF.ATR: DER encoded OID %s", sc_dump_hex(tag, taglen));
|
||||
tag = sc_asn1_find_tag(ctx, tag, taglen, SC_ASN1_TAG_OBJECT, &taglen);
|
||||
if (tag) {
|
||||
sc_log(ctx, "EF.ATR: OID %s", sc_dump_hex(tag, taglen));
|
||||
if(sc_asn1_decode_object_id(tag, taglen, &ef_atr.allocation_oid))
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ASN1_OBJECT);
|
||||
}
|
||||
}
|
||||
|
||||
if (category == ISO7816_II_CATEGORY_TLV) {
|
||||
|
|
|
@ -101,6 +101,9 @@ sc_format_apdu
|
|||
sc_bytes2apdu
|
||||
sc_format_asn1_entry
|
||||
sc_format_oid
|
||||
sc_init_oid
|
||||
sc_compare_oid
|
||||
sc_valid_oid
|
||||
sc_format_path
|
||||
sc_free_apps
|
||||
sc_free_ef_atr
|
||||
|
|
|
@ -174,7 +174,7 @@ typedef struct sc_security_env {
|
|||
|
||||
struct sc_algorithm_id {
|
||||
unsigned int algorithm;
|
||||
struct sc_object_id obj_id;
|
||||
struct sc_object_id oid;
|
||||
void *params;
|
||||
};
|
||||
|
||||
|
@ -1216,6 +1216,12 @@ const sc_path_t *sc_get_mf_path(void);
|
|||
int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen);
|
||||
int sc_bin_to_hex(const u8 *, size_t, char *, size_t, int separator);
|
||||
scconf_block *sc_get_conf_block(sc_context_t *ctx, const char *name1, const char *name2, int priority);
|
||||
|
||||
/**
|
||||
* Initializes a given OID
|
||||
* @param oid sc_object_id object to be initialized
|
||||
*/
|
||||
void sc_init_oid(struct sc_object_id *oid);
|
||||
/**
|
||||
* Converts a given OID in ascii form to a internal sc_object_id object
|
||||
* @param oid OUT sc_object_id object for the result
|
||||
|
@ -1230,6 +1236,11 @@ int sc_format_oid(struct sc_object_id *oid, const char *in);
|
|||
* @return 1 if the oids are equal and a non-zero value otherwise
|
||||
*/
|
||||
int sc_compare_oid(const struct sc_object_id *oid1, const struct sc_object_id *oid2);
|
||||
/**
|
||||
* Validates a given OID
|
||||
* @param oid sc_object_id object to be validated
|
||||
*/
|
||||
int sc_valid_oid(const struct sc_object_id *oid);
|
||||
|
||||
/* Base64 encoding/decoding functions */
|
||||
int sc_base64_encode(const u8 *in, size_t inlen, u8 *out, size_t outlen,
|
||||
|
|
|
@ -335,131 +335,122 @@ asn1_free_ec_params(void *params)
|
|||
static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = {
|
||||
#ifdef SC_ALGORITHM_SHA1
|
||||
/* hmacWithSHA1 */
|
||||
{ SC_ALGORITHM_SHA1, {{ 1, 2, 840, 113549, 2, 7 }}, NULL, NULL, NULL },
|
||||
{ SC_ALGORITHM_SHA1, {{ 1, 3, 6, 1, 5, 5, 8, 1, 2 }}, NULL, NULL, NULL },
|
||||
{ SC_ALGORITHM_SHA1, {{ 1, 2, 840, 113549, 2, 7, -1}}, NULL, NULL, NULL },
|
||||
{ SC_ALGORITHM_SHA1, {{ 1, 3, 6, 1, 5, 5, 8, 1, 2, -1}}, NULL, NULL, NULL },
|
||||
/* SHA1 */
|
||||
{ SC_ALGORITHM_SHA1, {{ 1, 3, 14, 3, 2, 26, }}, NULL, NULL, NULL },
|
||||
{ SC_ALGORITHM_SHA1, {{ 1, 3, 14, 3, 2, 26, -1}}, NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_MD5
|
||||
{ SC_ALGORITHM_MD5, {{ 1, 2, 840, 113549, 2, 5, }}, NULL, NULL, NULL },
|
||||
{ SC_ALGORITHM_MD5, {{ 1, 2, 840, 113549, 2, 5, -1}}, NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_DSA
|
||||
{ SC_ALGORITHM_DSA, {{ 1, 2, 840, 10040, 4, 3 }}, NULL, NULL, NULL },
|
||||
{ SC_ALGORITHM_DSA, {{ 1, 2, 840, 10040, 4, 3, -1}}, NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_RSA /* really rsaEncryption */
|
||||
{ SC_ALGORITHM_RSA, {{ 1, 2, 840, 113549, 1, 1, 1 }}, NULL, NULL, NULL },
|
||||
{ SC_ALGORITHM_RSA, {{ 1, 2, 840, 113549, 1, 1, 1, -1}}, NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_DH
|
||||
{ SC_ALGORITHM_DH, {{ 1, 2, 840, 10046, 2, 1 }}, NULL, NULL, NULL },
|
||||
{ SC_ALGORITHM_DH, {{ 1, 2, 840, 10046, 2, 1, -1}}, NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_RC2_WRAP /* from CMS */
|
||||
{ SC_ALGORITHM_RC2_WRAP, {{ 1, 2, 840, 113549, 1, 9, 16, 3, 7 }}, NULL, NULL, NULL },
|
||||
{ SC_ALGORITHM_RC2_WRAP, {{ 1, 2, 840, 113549, 1, 9, 16, 3, 7, -1}}, NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_RC2 /* CBC mode */
|
||||
{ SC_ALGORITHM_RC2, {{ 1, 2, 840, 113549, 3, 2 }},
|
||||
{ SC_ALGORITHM_RC2, {{ 1, 2, 840, 113549, 3, 2, -1}},
|
||||
asn1_decode_rc2_params,
|
||||
asn1_encode_rc2_params },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_DES /* CBC mode */
|
||||
{ SC_ALGORITHM_DES, {{ 1, 3, 14, 3, 2, 7 }},
|
||||
{ SC_ALGORITHM_DES, {{ 1, 3, 14, 3, 2, 7, -1}},
|
||||
asn1_decode_des_params,
|
||||
asn1_encode_des_params,
|
||||
free },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_3DES_WRAP /* from CMS */
|
||||
{ SC_ALGORITHM_3DES_WRAP, {{ 1, 2, 840, 113549, 1, 9, 16, 3, 6 }}, NULL, NULL, NULL },
|
||||
{ SC_ALGORITHM_3DES_WRAP, {{ 1, 2, 840, 113549, 1, 9, 16, 3, 6, -1}}, NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_3DES /* EDE CBC mode */
|
||||
{ SC_ALGORITHM_3DES, {{ 1, 2, 840, 113549, 3, 7 }},
|
||||
{ SC_ALGORITHM_3DES, {{ 1, 2, 840, 113549, 3, 7, -1}},
|
||||
asn1_decode_des_params,
|
||||
asn1_encode_des_params,
|
||||
free },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_GOST /* EDE CBC mode */
|
||||
{ SC_ALGORITHM_GOST, {{ 1, 2, 4434, 66565, 3, 7 }},
|
||||
NULL,
|
||||
NULL,
|
||||
NULL },
|
||||
{ SC_ALGORITHM_GOST, {{ 1, 2, 4434, 66565, 3, 7, -1}}, NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_GOSTR3410
|
||||
{ SC_ALGORITHM_GOSTR3410, {{ 1, 2, 643, 2, 2, 19 }},
|
||||
{ SC_ALGORITHM_GOSTR3410, {{ 1, 2, 643, 2, 2, 19, -1}},
|
||||
asn1_decode_gostr3410_params,
|
||||
asn1_encode_gostr3410_params,
|
||||
NULL },
|
||||
#endif
|
||||
/* We do not support PBES1 because the encryption is weak */
|
||||
#ifdef SC_ALGORITHM_PBKDF2
|
||||
{ SC_ALGORITHM_PBKDF2, {{ 1, 2, 840, 113549, 1, 5, 12 }},
|
||||
{ SC_ALGORITHM_PBKDF2, {{ 1, 2, 840, 113549, 1, 5, 12, -1}},
|
||||
asn1_decode_pbkdf2_params,
|
||||
asn1_encode_pbkdf2_params,
|
||||
free },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_PBES2
|
||||
{ SC_ALGORITHM_PBES2, {{ 1, 2, 840, 113549, 1, 5, 13 }},
|
||||
{ SC_ALGORITHM_PBES2, {{ 1, 2, 840, 113549, 1, 5, 13, -1}},
|
||||
asn1_decode_pbes2_params,
|
||||
asn1_encode_pbes2_params,
|
||||
asn1_free_pbes2_params },
|
||||
#endif
|
||||
|
||||
#ifdef SC_ALGORITHM_EC
|
||||
{ SC_ALGORITHM_EC, {{ 1, 2, 840, 10045, 2, 1 }},
|
||||
asn1_decode_ec_params, asn1_encode_ec_params, asn1_free_ec_params },
|
||||
{ SC_ALGORITHM_EC, {{ 1, 2, 840, 10045, 2, 1, -1}},
|
||||
asn1_decode_ec_params,
|
||||
asn1_encode_ec_params,
|
||||
asn1_free_ec_params },
|
||||
#endif
|
||||
/* TODO: -DEE Not clear of we need the next five or not */
|
||||
#ifdef SC_ALGORITHM_ECDSA_SHA1
|
||||
/* Note RFC 3279 says no ecParameters */
|
||||
{ SC_ALGORITHM_ECDSA_SHA1, {{ 1, 2, 840, 10045, 4, 1 }}, NULL, NULL, NULL},
|
||||
{ SC_ALGORITHM_ECDSA_SHA1, {{ 1, 2, 840, 10045, 4, 1, -1}}, NULL, NULL, NULL},
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_ECDSA_SHA224
|
||||
/* These next 4 are defined in RFC 5758 */
|
||||
{ SC_ALGORITHM_ECDSA_SHA224, {{ 1, 2, 840, 10045, 4, 3, 1 }},
|
||||
asn1_decode_ec_params, asn1_encode_ec_params, asn1_free_ec_params },
|
||||
{ SC_ALGORITHM_ECDSA_SHA224, {{ 1, 2, 840, 10045, 4, 3, 1, -1}},
|
||||
asn1_decode_ec_params,
|
||||
asn1_encode_ec_params,
|
||||
asn1_free_ec_params },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_ECDSA_SHA256
|
||||
{ SC_ALGORITHM_ECDSA_SHA256, {{ 1, 2, 840, 10045, 4, 3, 2 }},
|
||||
asn1_decode_ec_params, asn1_encode_ec_params, asn1_free_ec_params },
|
||||
{ SC_ALGORITHM_ECDSA_SHA256, {{ 1, 2, 840, 10045, 4, 3, 2, -1}},
|
||||
asn1_decode_ec_params,
|
||||
asn1_encode_ec_params,
|
||||
asn1_free_ec_params },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_ECDSA_SHA384
|
||||
{ SC_ALGORITHM_ECDSA_SHA384, {{ 1, 2, 840, 10045, 4, 3, 3 }},
|
||||
asn1_decode_ec_params, asn1_encode_ec_params, asn1_free_ec_params },
|
||||
{ SC_ALGORITHM_ECDSA_SHA384, {{ 1, 2, 840, 10045, 4, 3, 3, -1}},
|
||||
asn1_decode_ec_params,
|
||||
asn1_encode_ec_params,
|
||||
asn1_free_ec_params },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_ECDSA_SHA512
|
||||
{ SC_ALGORITHM_ECDSA_SHA512, {{ 1, 2, 840, 10045, 4, 3, 4 }},
|
||||
asn1_decode_ec_params, asn1_encode_ec_params, asn1_free_ec_params },
|
||||
{ SC_ALGORITHM_ECDSA_SHA512, {{ 1, 2, 840, 10045, 4, 3, 4, -1}},
|
||||
asn1_decode_ec_params,
|
||||
asn1_encode_ec_params,
|
||||
asn1_free_ec_params },
|
||||
#endif
|
||||
{ -1, {{ -1 }}, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
static struct sc_asn1_pkcs15_algorithm_info *
|
||||
sc_asn1_get_algorithm_info(const struct sc_algorithm_id *id)
|
||||
{
|
||||
struct sc_asn1_pkcs15_algorithm_info *aip;
|
||||
struct sc_asn1_pkcs15_algorithm_info *aip = NULL;
|
||||
|
||||
aip = algorithm_table;
|
||||
if ((int) id->algorithm < 0) {
|
||||
while (aip->id >= 0) {
|
||||
const int *oid1, *oid2;
|
||||
int m;
|
||||
for (aip = algorithm_table; aip->id >= 0; aip++) {
|
||||
if ((int) id->algorithm < 0 && sc_compare_oid(&id->oid, &aip->oid))
|
||||
return aip;
|
||||
|
||||
oid1 = aip->oid.value;
|
||||
oid2 = id->obj_id.value;
|
||||
for (m = 0; m < SC_MAX_OBJECT_ID_OCTETS; m++) {
|
||||
if (oid1[m] == oid2[m])
|
||||
continue;
|
||||
if (oid1[m] > 0 || oid2[m] > 0)
|
||||
break;
|
||||
/* We have a match */
|
||||
return aip;
|
||||
}
|
||||
aip++;
|
||||
}
|
||||
} else {
|
||||
while (aip->id >= 0) {
|
||||
if (aip->id == (int)id->algorithm)
|
||||
return aip;
|
||||
aip++;
|
||||
}
|
||||
if (aip->id == (int)id->algorithm)
|
||||
return aip;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -479,7 +470,7 @@ sc_asn1_decode_algorithm_id(sc_context_t *ctx, const u8 *in,
|
|||
int r;
|
||||
|
||||
sc_copy_asn1_entry(c_asn1_alg_id, asn1_alg_id);
|
||||
sc_format_asn1_entry(asn1_alg_id + 0, &id->obj_id, NULL, 0);
|
||||
sc_format_asn1_entry(asn1_alg_id + 0, &id->oid, NULL, 0);
|
||||
|
||||
memset(id, 0, sizeof(*id));
|
||||
r = _sc_asn1_decode(ctx, asn1_alg_id, in, len, &in, &len, 0, depth + 1);
|
||||
|
@ -522,20 +513,19 @@ sc_asn1_encode_algorithm_id(sc_context_t *ctx,
|
|||
|
||||
alg_info = sc_asn1_get_algorithm_info(id);
|
||||
if (alg_info == NULL) {
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Cannot encode unknown algorithm %u.\n",
|
||||
id->algorithm);
|
||||
sc_log(ctx, "Cannot encode unknown algorithm %u", id->algorithm);
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
/* Set the oid if not yet given */
|
||||
if (id->obj_id.value[0] <= 0) {
|
||||
if (!sc_valid_oid(&id->oid)) {
|
||||
temp_id = *id;
|
||||
temp_id.obj_id = alg_info->oid;
|
||||
temp_id.oid = alg_info->oid;
|
||||
id = &temp_id;
|
||||
}
|
||||
|
||||
sc_copy_asn1_entry(c_asn1_alg_id, asn1_alg_id);
|
||||
sc_format_asn1_entry(asn1_alg_id + 0, (void *) &id->obj_id, NULL, 1);
|
||||
sc_format_asn1_entry(asn1_alg_id + 0, (void *) &id->oid, NULL, 1);
|
||||
|
||||
/* no parameters, write NULL tag */
|
||||
if (!id->params || !alg_info->encode)
|
||||
|
|
|
@ -107,7 +107,7 @@ int sc_pkcs15_decode_dodf_entry(struct sc_pkcs15_card *p15card,
|
|||
|
||||
/* Fill in defaults */
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.app_oid.value[0] = -1;
|
||||
sc_init_oid(&info.app_oid);
|
||||
|
||||
r = sc_asn1_decode(ctx, asn1_data, *buf, *buflen, buf, buflen);
|
||||
if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
|
||||
|
@ -152,14 +152,12 @@ int sc_pkcs15_encode_dodf_entry(sc_context_t *ctx,
|
|||
sc_copy_asn1_entry(c_asn1_type_data_attr, asn1_type_data_attr);
|
||||
sc_copy_asn1_entry(c_asn1_data, asn1_data);
|
||||
|
||||
if (label_len) {
|
||||
sc_format_asn1_entry(asn1_com_data_attr + 0,
|
||||
&info->app_label, &label_len, 1);
|
||||
}
|
||||
if (info->app_oid.value[0] != -1) {
|
||||
sc_format_asn1_entry(asn1_com_data_attr + 1,
|
||||
&info->app_oid, NULL, 1);
|
||||
}
|
||||
if (label_len)
|
||||
sc_format_asn1_entry(asn1_com_data_attr + 0, &info->app_label, &label_len, 1);
|
||||
|
||||
if (sc_valid_oid(&info->app_oid))
|
||||
sc_format_asn1_entry(asn1_com_data_attr + 1, &info->app_oid, NULL, 1);
|
||||
|
||||
sc_format_asn1_entry(asn1_type_data_attr + 0, &info->path, NULL, 1);
|
||||
sc_format_asn1_entry(asn1_data + 0, &data_obj, NULL, 1);
|
||||
|
||||
|
|
|
@ -1055,7 +1055,7 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_pkcs15_ec_paramete
|
|||
sc_log(ctx, "Curve name: '%s'", ecparams->named_curve);
|
||||
}
|
||||
|
||||
if (ecparams->id.value[0] <=0 || ecparams->id.value[1] <=0)
|
||||
if (!sc_valid_oid(&ecparams->id))
|
||||
sc_format_oid(&ecparams->id, ec_curve_infos[ii].oid_str);
|
||||
|
||||
ecparams->field_length = ec_curve_infos[ii].size;
|
||||
|
@ -1081,7 +1081,7 @@ sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_pkcs15_ec_paramete
|
|||
LOG_TEST_RET(ctx, rv, "Cannot encode object ID");
|
||||
}
|
||||
}
|
||||
else if (ecparams->id.value[0] > 0 && ecparams->id.value[1] > 0) {
|
||||
else if (sc_valid_oid(&ecparams->id)) {
|
||||
LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "EC parameters has to be presented as a named curve or explicit data");
|
||||
}
|
||||
|
||||
|
|
|
@ -354,13 +354,13 @@ sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti,
|
|||
}
|
||||
sc_format_asn1_entry(asn1_toki_attrs + 12, NULL, NULL, 0);
|
||||
|
||||
if (ti->profile_indication.oid.value[0] > 0) {
|
||||
sc_format_asn1_entry(asn1_profile_indication + 0, &ti->profile_indication.oid, NULL, 1);
|
||||
if (sc_valid_oid(&ti->profile_indication.oid)) {
|
||||
sc_format_asn1_entry(asn1_profile_indication + 0, &ti->profile_indication.oid, NULL, 1);
|
||||
sc_format_asn1_entry(asn1_toki_attrs + 13, asn1_profile_indication, NULL, 1);
|
||||
}
|
||||
else if (ti->profile_indication.name) {
|
||||
pi_len = strlen(ti->profile_indication.name);
|
||||
sc_format_asn1_entry(asn1_profile_indication + 1, ti->profile_indication.name, &pi_len, 1);
|
||||
sc_format_asn1_entry(asn1_profile_indication + 1, ti->profile_indication.name, &pi_len, 1);
|
||||
sc_format_asn1_entry(asn1_toki_attrs + 13, asn1_profile_indication, NULL, 1);
|
||||
}
|
||||
else {
|
||||
|
@ -713,7 +713,7 @@ struct sc_pkcs15_card * sc_pkcs15_card_new(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
p15card->tokeninfo->profile_indication.oid.value[0] = -1;
|
||||
sc_init_oid(&p15card->tokeninfo->profile_indication.oid);
|
||||
|
||||
p15card->magic = SC_PKCS15_CARD_MAGIC;
|
||||
return p15card;
|
||||
|
|
|
@ -145,59 +145,88 @@ unsigned short bebytes2ushort(const u8 *buf)
|
|||
return (unsigned short) (buf[0] << 8 | buf[1]);
|
||||
}
|
||||
|
||||
void sc_init_oid(struct sc_object_id *oid)
|
||||
{
|
||||
int ii;
|
||||
|
||||
if (!oid)
|
||||
return;
|
||||
for (ii=0; ii<SC_MAX_OBJECT_ID_OCTETS; ii++)
|
||||
oid->value[ii] = -1;
|
||||
}
|
||||
|
||||
int sc_format_oid(struct sc_object_id *oid, const char *in)
|
||||
{
|
||||
int ii;
|
||||
int ii, ret = SC_ERROR_INVALID_ARGUMENTS;
|
||||
const char *p;
|
||||
char *q;
|
||||
|
||||
if (oid == NULL || in == NULL)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
/* init oid */
|
||||
for (ii=0; ii<SC_MAX_OBJECT_ID_OCTETS; ii++)
|
||||
oid->value[ii] = -1;
|
||||
|
||||
sc_init_oid(oid);
|
||||
|
||||
p = in;
|
||||
|
||||
for (ii=0; ii < SC_MAX_OBJECT_ID_OCTETS; ii++) {
|
||||
oid->value[ii] = strtol(p, &q, 10);
|
||||
if (!*q)
|
||||
break;
|
||||
if (!(q[0] == '.' && isdigit(q[1]))) {
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
if (!(q[0] == '.' && isdigit(q[1])))
|
||||
goto out;
|
||||
|
||||
p = q + 1;
|
||||
}
|
||||
|
||||
if (ii == 1)
|
||||
/* reject too short OIDs */
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
if (!sc_valid_oid(oid))
|
||||
goto out;
|
||||
|
||||
return SC_SUCCESS;
|
||||
ret = SC_SUCCESS;
|
||||
out:
|
||||
if (ret)
|
||||
sc_init_oid(oid);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sc_compare_oid(const struct sc_object_id *oid1, const struct sc_object_id *oid2)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(oid1 != NULL && oid2 != NULL);
|
||||
for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++) {
|
||||
|
||||
for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++) {
|
||||
if (oid1->value[i] != oid2->value[i])
|
||||
return 0;
|
||||
if (oid1->value[i] < 0)
|
||||
return 1;
|
||||
if (oid1->value[i] == -1)
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int sc_valid_oid(const struct sc_object_id *oid)
|
||||
{
|
||||
if (!oid)
|
||||
return 0;
|
||||
if (oid->value[0] == -1 || oid->value[1] == -1)
|
||||
return 0;
|
||||
if (oid->value[0] > 2 || oid->value[1] > 39)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int sc_detect_card_presence(sc_reader_t *reader)
|
||||
{
|
||||
int r;
|
||||
SC_FUNC_CALLED(reader->ctx, SC_LOG_DEBUG_VERBOSE);
|
||||
LOG_FUNC_CALLED(reader->ctx);
|
||||
if (reader->ops->detect_card_presence == NULL)
|
||||
SC_FUNC_RETURN(reader->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED);
|
||||
LOG_FUNC_RETURN(reader->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
|
||||
r = reader->ops->detect_card_presence(reader);
|
||||
SC_FUNC_RETURN(reader->ctx, SC_LOG_DEBUG_NORMAL, r);
|
||||
LOG_FUNC_RETURN(reader->ctx, r);
|
||||
}
|
||||
|
||||
int sc_path_set(sc_path_t *path, int type, const u8 *id, size_t id_len,
|
||||
|
@ -643,12 +672,12 @@ int _sc_parse_atr(sc_reader_t *reader)
|
|||
reader->atr_info.hist_bytes = NULL;
|
||||
|
||||
if (atr_len == 0) {
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "empty ATR - card not present?\n");
|
||||
sc_log(reader->ctx, "empty ATR - card not present?\n");
|
||||
return SC_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
if (p[0] != 0x3B && p[0] != 0x3F) {
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "invalid sync byte in ATR: 0x%02X\n", p[0]);
|
||||
sc_log(reader->ctx, "invalid sync byte in ATR: 0x%02X\n", p[0]);
|
||||
return SC_ERROR_INTERNAL;
|
||||
}
|
||||
n_hist = p[1] & 0x0F;
|
||||
|
|
|
@ -2260,7 +2260,7 @@ pkcs15_create_data(struct sc_pkcs11_slot *slot, struct sc_profile *profile,
|
|||
char label[SC_PKCS15_MAX_LABEL_SIZE];
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.app_oid.value[0] = -1;
|
||||
sc_init_oid(&args.app_oid);
|
||||
|
||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[slot->fw_data_idx];
|
||||
if (!fw_data)
|
||||
|
@ -2298,9 +2298,10 @@ pkcs15_create_data(struct sc_pkcs11_slot *slot, struct sc_profile *profile,
|
|||
args.app_label = (char *) attr->pValue;
|
||||
break;
|
||||
case CKA_OBJECT_ID:
|
||||
rv = attr_extract(attr, args.app_oid.value, NULL);
|
||||
if (rv != CKR_OK)
|
||||
if (sc_asn1_decode_object_id(attr->pValue, attr->ulValueLen, &args.app_oid)) {
|
||||
rv = CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case CKA_VALUE:
|
||||
args.der_encoded.len = attr->ulValueLen;
|
||||
|
@ -2907,10 +2908,9 @@ pkcs15_cert_release(void *obj)
|
|||
struct pkcs15_cert_object *cert = (struct pkcs15_cert_object *) obj;
|
||||
struct sc_pkcs15_cert *cert_data = cert->cert_data;
|
||||
|
||||
if (__pkcs15_release_object((struct pkcs15_any_object *) obj) == 0) {
|
||||
if (__pkcs15_release_object((struct pkcs15_any_object *) obj) == 0)
|
||||
if (cert_data) /* may never have been read */
|
||||
sc_pkcs15_free_certificate(cert_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2945,8 +2945,7 @@ pkcs15_cert_get_attribute(struct sc_pkcs11_session *session, void *object, CK_AT
|
|||
break;
|
||||
case CKA_PRIVATE:
|
||||
check_attribute_buffer(attr, sizeof(CK_BBOOL));
|
||||
*(CK_BBOOL*)attr->pValue =
|
||||
(cert->base.p15_object->flags & SC_PKCS15_CO_FLAG_PRIVATE) != 0;
|
||||
*(CK_BBOOL*)attr->pValue = (cert->base.p15_object->flags & SC_PKCS15_CO_FLAG_PRIVATE) != 0;
|
||||
break;
|
||||
case CKA_MODIFIABLE:
|
||||
check_attribute_buffer(attr, sizeof(CK_BBOOL));
|
||||
|
@ -2962,11 +2961,11 @@ pkcs15_cert_get_attribute(struct sc_pkcs11_session *session, void *object, CK_AT
|
|||
*(CK_CERTIFICATE_TYPE*)attr->pValue = CKC_X_509;
|
||||
break;
|
||||
case CKA_ID:
|
||||
if (cert->cert_info->authority
|
||||
&& sc_pkcs11_conf.zero_ckaid_for_ca_certs) {
|
||||
if (cert->cert_info->authority && sc_pkcs11_conf.zero_ckaid_for_ca_certs) {
|
||||
check_attribute_buffer(attr, 1);
|
||||
*(unsigned char*)attr->pValue = 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
check_attribute_buffer(attr, cert->cert_info->id.len);
|
||||
memcpy(attr->pValue, cert->cert_info->id.value, cert->cert_info->id.len);
|
||||
}
|
||||
|
@ -2996,15 +2995,13 @@ pkcs15_cert_get_attribute(struct sc_pkcs11_session *session, void *object, CK_AT
|
|||
attr->ulValueLen = 0;
|
||||
return CKR_OK;
|
||||
}
|
||||
return asn1_sequence_wrapper(cert->cert_data->subject,
|
||||
cert->cert_data->subject_len, attr);
|
||||
return asn1_sequence_wrapper(cert->cert_data->subject, cert->cert_data->subject_len, attr);
|
||||
case CKA_ISSUER:
|
||||
if (check_cert_data_read(fw_data, cert) != 0) {
|
||||
attr->ulValueLen = 0;
|
||||
return CKR_OK;
|
||||
}
|
||||
return asn1_sequence_wrapper(cert->cert_data->issuer,
|
||||
cert->cert_data->issuer_len, attr);
|
||||
return asn1_sequence_wrapper(cert->cert_data->issuer, cert->cert_data->issuer_len, attr);
|
||||
default:
|
||||
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
}
|
||||
|
@ -3863,7 +3860,11 @@ static CK_RV
|
|||
pkcs15_dobj_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ATTRIBUTE_PTR attr)
|
||||
{
|
||||
struct pkcs15_data_object *dobj = (struct pkcs15_data_object*) object;
|
||||
struct sc_pkcs15_data *data = NULL;
|
||||
CK_RV rv;
|
||||
size_t len;
|
||||
int r;
|
||||
unsigned char *buf = NULL;
|
||||
|
||||
switch (attr->type) {
|
||||
case CKA_CLASS:
|
||||
|
@ -3876,13 +3877,11 @@ pkcs15_dobj_get_attribute(struct sc_pkcs11_session *session, void *object, CK_AT
|
|||
break;
|
||||
case CKA_PRIVATE:
|
||||
check_attribute_buffer(attr, sizeof(CK_BBOOL));
|
||||
*(CK_BBOOL*)attr->pValue =
|
||||
(dobj->base.p15_object->flags & SC_PKCS15_CO_FLAG_PRIVATE) != 0;
|
||||
*(CK_BBOOL*)attr->pValue = (dobj->base.p15_object->flags & SC_PKCS15_CO_FLAG_PRIVATE) != 0;
|
||||
break;
|
||||
case CKA_MODIFIABLE:
|
||||
check_attribute_buffer(attr, sizeof(CK_BBOOL));
|
||||
*(CK_BBOOL*)attr->pValue =
|
||||
(dobj->base.p15_object->flags & 0x02) != 0;
|
||||
*(CK_BBOOL*)attr->pValue = (dobj->base.p15_object->flags & 0x02) != 0;
|
||||
break;
|
||||
case CKA_LABEL:
|
||||
len = strlen(dobj->base.p15_object->label);
|
||||
|
@ -3901,28 +3900,37 @@ pkcs15_dobj_get_attribute(struct sc_pkcs11_session *session, void *object, CK_AT
|
|||
break;
|
||||
#endif
|
||||
case CKA_OBJECT_ID:
|
||||
{
|
||||
len = sizeof(dobj->info->app_oid);
|
||||
|
||||
check_attribute_buffer(attr, len);
|
||||
memcpy(attr->pValue, dobj->info->app_oid.value, len);
|
||||
if (!sc_valid_oid(&dobj->info->app_oid)) {
|
||||
attr->ulValueLen = -1;
|
||||
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
}
|
||||
r = sc_asn1_encode_object_id(NULL, &len, &dobj->info->app_oid);
|
||||
if (r) {
|
||||
sc_log(context, "data_get_attr(): encode OID error %i", r);
|
||||
return CKR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
check_attribute_buffer(attr, len);
|
||||
|
||||
r = sc_asn1_encode_object_id(&buf, &len, &dobj->info->app_oid);
|
||||
if (r) {
|
||||
sc_log(context, "data_get_attr(): encode OID error %i", r);
|
||||
return CKR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
memcpy(attr->pValue, buf, len);
|
||||
free(buf);
|
||||
break;
|
||||
case CKA_VALUE:
|
||||
{
|
||||
CK_RV rv;
|
||||
struct sc_pkcs15_data *data = NULL;
|
||||
|
||||
rv = pkcs15_dobj_get_value(session, dobj, &data);
|
||||
if (rv == CKR_OK)
|
||||
rv = data_value_to_attr(attr, data);
|
||||
if (data) {
|
||||
free(data->data);
|
||||
free(data);
|
||||
}
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
rv = pkcs15_dobj_get_value(session, dobj, &data);
|
||||
if (rv == CKR_OK)
|
||||
rv = data_value_to_attr(attr, data);
|
||||
if (data) {
|
||||
free(data->data);
|
||||
free(data);
|
||||
}
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
break;
|
||||
default:
|
||||
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
|
|
|
@ -1384,7 +1384,7 @@ iasecc_md_gemalto_set_default(struct sc_pkcs15_card *p15card, struct sc_profile
|
|||
|
||||
if (!data_obj) {
|
||||
memset(&data_args, 0, sizeof(data_args));
|
||||
data_args.app_oid.value[0] = -1;
|
||||
sc_init_oid(&data_args.app_oid);
|
||||
data_args.label = "Default Key Container";
|
||||
data_args.app_label = "CSP";
|
||||
data_args.der_encoded.value = (unsigned char *)guid;
|
||||
|
@ -1493,7 +1493,7 @@ iasecc_md_gemalto_new_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *
|
|||
data[offs++] = 0x01;
|
||||
|
||||
memset(&data_args, 0, sizeof(data_args));
|
||||
data_args.app_oid.value[0] = -1;
|
||||
sc_init_oid(&data_args.app_oid);
|
||||
data_args.label = guid;
|
||||
data_args.app_label = "CSP";
|
||||
data_args.der_encoded.value = data;
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
#include "pkcs11/pkcs11.h"
|
||||
#include "pkcs11/pkcs11-opensc.h"
|
||||
#include "libopensc/asn1.h"
|
||||
#include "util.h"
|
||||
|
||||
extern void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR);
|
||||
|
@ -1762,6 +1763,7 @@ static int write_object(CK_SESSION_HANDLE session)
|
|||
struct sc_object_id oid;
|
||||
CK_RV rv;
|
||||
int need_to_parse_certdata = 0;
|
||||
unsigned char *oid_buf = NULL;
|
||||
#ifdef ENABLE_OPENSSL
|
||||
struct x509cert_info cert;
|
||||
struct rsakey_info rsa;
|
||||
|
@ -2002,9 +2004,15 @@ static int write_object(CK_SESSION_HANDLE session)
|
|||
}
|
||||
|
||||
if (opt_application_id != NULL) {
|
||||
sc_format_oid(&oid, opt_application_id);
|
||||
FILL_ATTR(data_templ[n_data_attr], CKA_OBJECT_ID,
|
||||
(unsigned char *)oid.value, sizeof(oid.value));
|
||||
size_t len;
|
||||
|
||||
if (sc_format_oid(&oid, opt_application_id))
|
||||
util_fatal("Invalid OID \"%s\"\n", opt_application_id);
|
||||
|
||||
if (sc_asn1_encode_object_id(&oid_buf, &len, &oid))
|
||||
util_fatal("Cannot encode OID \"%s\"\n", opt_application_id);
|
||||
|
||||
FILL_ATTR(data_templ[n_data_attr], CKA_OBJECT_ID, oid_buf, len);
|
||||
n_data_attr++;
|
||||
}
|
||||
|
||||
|
@ -2053,6 +2061,8 @@ static int write_object(CK_SESSION_HANDLE session)
|
|||
show_object(session, privkey_obj);
|
||||
}
|
||||
|
||||
if (oid_buf)
|
||||
free(oid_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2702,8 +2712,8 @@ static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
|||
|
||||
static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
{
|
||||
int *app_oid;
|
||||
char *label;
|
||||
unsigned char *oid_buf;
|
||||
char *label;
|
||||
CK_ULONG size = 0;
|
||||
|
||||
printf("Data object %u\n", (unsigned int) obj);
|
||||
|
@ -2726,18 +2736,20 @@ static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
|||
}
|
||||
|
||||
printf(" app_id: ");
|
||||
app_oid = (int *)getOBJECT_ID(sess, obj, &size);
|
||||
if (app_oid != NULL && size) {
|
||||
oid_buf = getOBJECT_ID(sess, obj, &size);
|
||||
if (oid_buf != NULL && size) {
|
||||
unsigned int n;
|
||||
struct sc_object_id oid;
|
||||
|
||||
size /= sizeof(int);
|
||||
printf("%i", app_oid[0]);
|
||||
if (app_oid[0] >= 0)
|
||||
for (n = 1; (n < size) && (app_oid[n] >= 0); n++)
|
||||
printf(".%i", app_oid[n]);
|
||||
|
||||
sc_init_oid(&oid);
|
||||
sc_asn1_decode_object_id(oid_buf, size, &oid);
|
||||
printf("%i", oid.value[0]);
|
||||
if (oid.value[0] >= 0)
|
||||
for (n = 1; (n < SC_MAX_OBJECT_ID_OCTETS) && (oid.value[n] >= 0); n++)
|
||||
printf(".%i", oid.value[n]);
|
||||
printf("\n");
|
||||
free(app_oid);
|
||||
|
||||
free(oid_buf);
|
||||
}
|
||||
else {
|
||||
printf("<empty>\n");
|
||||
|
@ -2805,7 +2817,7 @@ static int read_object(CK_SESSION_HANDLE session)
|
|||
CK_OBJECT_CLASS clazz = opt_object_class;
|
||||
CK_OBJECT_HANDLE obj = CK_INVALID_HANDLE;
|
||||
int nn_attrs = 0;
|
||||
unsigned char *value = NULL;
|
||||
unsigned char *value = NULL, *oid_buf = NULL;
|
||||
CK_ULONG len = 0;
|
||||
FILE *out;
|
||||
struct sc_object_id oid;
|
||||
|
@ -2836,9 +2848,15 @@ static int read_object(CK_SESSION_HANDLE session)
|
|||
}
|
||||
|
||||
if (opt_application_id != NULL) {
|
||||
sc_format_oid(&oid, opt_application_id);
|
||||
FILL_ATTR(attrs[nn_attrs], CKA_OBJECT_ID,
|
||||
(unsigned char *)oid.value, sizeof(oid.value));
|
||||
size_t oid_buf_len;
|
||||
|
||||
if (sc_format_oid(&oid, opt_application_id))
|
||||
util_fatal("Invalid OID \"%s\"\n", opt_application_id);
|
||||
|
||||
if (sc_asn1_encode_object_id(&oid_buf, &oid_buf_len, &oid))
|
||||
util_fatal("Cannot encode OID \"%s\"\n", opt_application_id);
|
||||
|
||||
FILL_ATTR(attrs[nn_attrs], CKA_OBJECT_ID, oid_buf, oid_buf_len);
|
||||
nn_attrs++;
|
||||
}
|
||||
|
||||
|
@ -2886,6 +2904,9 @@ static int read_object(CK_SESSION_HANDLE session)
|
|||
util_fatal("cannot write to '%s'\n", opt_output);
|
||||
if (opt_output)
|
||||
fclose(out);
|
||||
|
||||
if (oid_buf)
|
||||
free(oid_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2900,6 +2921,7 @@ static int delete_object(CK_SESSION_HANDLE session)
|
|||
CK_OBJECT_HANDLE obj = CK_INVALID_HANDLE;
|
||||
int nn_attrs = 0;
|
||||
struct sc_object_id oid;
|
||||
unsigned char *oid_buf = NULL;
|
||||
|
||||
if (opt_object_class_str != NULL) {
|
||||
FILL_ATTR(attrs[nn_attrs], CKA_CLASS,
|
||||
|
@ -2926,9 +2948,15 @@ static int delete_object(CK_SESSION_HANDLE session)
|
|||
}
|
||||
|
||||
if (opt_application_id != NULL) {
|
||||
sc_format_oid(&oid, opt_application_id);
|
||||
FILL_ATTR(attrs[nn_attrs], CKA_OBJECT_ID,
|
||||
(unsigned char *)oid.value, sizeof(oid.value));
|
||||
size_t oid_buf_len;
|
||||
|
||||
if (sc_format_oid(&oid, opt_application_id))
|
||||
util_fatal("Invalid OID '%s'\n", opt_application_id);
|
||||
|
||||
if (sc_asn1_encode_object_id(&oid_buf, &oid_buf_len, &oid))
|
||||
util_fatal("Cannot encode OID \"%s\"\n", opt_application_id);
|
||||
|
||||
FILL_ATTR(attrs[nn_attrs], CKA_OBJECT_ID, oid_buf, oid_buf_len);
|
||||
nn_attrs++;
|
||||
}
|
||||
|
||||
|
@ -2941,6 +2969,9 @@ static int delete_object(CK_SESSION_HANDLE session)
|
|||
if (rv != CKR_OK)
|
||||
p11_fatal("C_DestroyObject()", rv);
|
||||
|
||||
if (oid_buf)
|
||||
free(oid_buf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "libopensc/pkcs15.h"
|
||||
#include "libopensc/log.h"
|
||||
#include "libopensc/cards.h"
|
||||
#include "libopensc/asn1.h"
|
||||
#include "pkcs15init/pkcs15-init.h"
|
||||
#include "pkcs15init/profile.h"
|
||||
#include "util.h"
|
||||
|
@ -1189,7 +1190,7 @@ do_store_data_object(struct sc_profile *profile)
|
|||
int r=0;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.app_oid.value[0] = -1;
|
||||
sc_init_oid(&args.app_oid);
|
||||
|
||||
if (opt_objectid)
|
||||
sc_pkcs15_format_id(opt_objectid, &args.id);
|
||||
|
|
|
@ -236,7 +236,6 @@ static void print_cert_info(const struct sc_pkcs15_object *obj)
|
|||
if (rv >= 0 && cert_parsed) {
|
||||
printf("\tEncoded serial : %02X %02X ", *(cert_parsed->serial), *(cert_parsed->serial + 1));
|
||||
util_hex_dump(stdout, cert_parsed->serial + 2, cert_parsed->serial_len - 2, "");
|
||||
printf("\n");
|
||||
sc_pkcs15_free_certificate(cert_parsed);
|
||||
}
|
||||
}
|
||||
|
@ -399,9 +398,9 @@ static int read_certificate(void)
|
|||
|
||||
static int read_data_object(void)
|
||||
{
|
||||
int r, i, count, oid_len = 0;
|
||||
int r, i, count;
|
||||
struct sc_pkcs15_object *objs[32];
|
||||
struct sc_object_id oid;
|
||||
struct sc_object_id oid;
|
||||
|
||||
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, objs, 32);
|
||||
if (r < 0) {
|
||||
|
@ -410,19 +409,15 @@ static int read_data_object(void)
|
|||
}
|
||||
count = r;
|
||||
|
||||
r = sc_format_oid(&oid, opt_data);
|
||||
if (r == SC_SUCCESS) {
|
||||
while (oid.value[oid_len] >= 0) oid_len++;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
struct sc_pkcs15_data_info *cinfo = (struct sc_pkcs15_data_info *) objs[i]->data;
|
||||
struct sc_pkcs15_data *data_object;
|
||||
|
||||
if (oid_len) {
|
||||
if (memcmp(oid.value, cinfo->app_oid.value, sizeof(int) * oid_len))
|
||||
if (!sc_format_oid(&oid, opt_data)) {
|
||||
if (!sc_compare_oid(&oid, &cinfo->app_oid))
|
||||
continue;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (strcmp(opt_data, cinfo->app_label) && strcmp(opt_data, objs[i]->label))
|
||||
continue;
|
||||
}
|
||||
|
@ -465,20 +460,18 @@ static int list_data_objects(void)
|
|||
int idx;
|
||||
struct sc_pkcs15_data_info *cinfo = (struct sc_pkcs15_data_info *) objs[i]->data;
|
||||
|
||||
printf("Reading data object <%i>\n", i);
|
||||
printf("applicationName: %s\n", cinfo->app_label);
|
||||
printf("Label: %s\n", objs[i]->label);
|
||||
if (cinfo->app_oid.value[0] >= 0) {
|
||||
printf("applicationOID: %i", cinfo->app_oid.value[0]);
|
||||
idx = 1;
|
||||
while (idx < SC_MAX_OBJECT_ID_OCTETS) {
|
||||
if (cinfo->app_oid.value[idx] < 0)
|
||||
break;
|
||||
printf(".%i", cinfo->app_oid.value[idx++]);
|
||||
}
|
||||
if (objs[i]->label)
|
||||
printf("Data object '%s'\n", objs[i]->label);
|
||||
else
|
||||
printf("Data object <%i>\n", i);
|
||||
printf("\tapplicationName: %s\n", cinfo->app_label);
|
||||
if (sc_valid_oid(&cinfo->app_oid)) {
|
||||
printf("\tapplicationOID: %i", cinfo->app_oid.value[0]);
|
||||
for (idx = 1; idx < SC_MAX_OBJECT_ID_OCTETS && cinfo->app_oid.value[idx] != -1 ; idx++)
|
||||
printf(".%i", cinfo->app_oid.value[idx]);
|
||||
printf("\n");
|
||||
}
|
||||
printf("Path: %s\n", sc_print_path(&cinfo->path));
|
||||
printf("\tPath: %s\n", sc_print_path(&cinfo->path));
|
||||
if (objs[i]->auth_id.len == 0) {
|
||||
struct sc_pkcs15_data *data_object;
|
||||
r = sc_pkcs15_read_data_object(p15card, cinfo, &data_object);
|
||||
|
@ -488,11 +481,11 @@ static int list_data_objects(void)
|
|||
continue; /* DEE emulation may say there is a file */
|
||||
return 1;
|
||||
}
|
||||
r = list_data_object("Data Object", data_object->data, data_object->data_len);
|
||||
r = list_data_object("\tData", data_object->data, data_object->data_len);
|
||||
sc_pkcs15_free_data_object(data_object);
|
||||
}
|
||||
else {
|
||||
printf("Auth ID: %s\n", sc_pkcs15_print_id(&objs[i]->auth_id));
|
||||
printf("\tAuth ID: %s\n", sc_pkcs15_print_id(&objs[i]->auth_id));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue