- Reworked PKCS #15 structure a bit (MANY THINGS

WILL BREAK)
- Added support for public key DFs (not tested yet)


git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@251 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
jey 2002-03-03 00:32:28 +00:00
parent e256d97f65
commit 6b07ff64f6
16 changed files with 684 additions and 457 deletions

View File

@ -19,8 +19,8 @@ bin_SCRIPTS = opensc-config
lib_LTLIBRARIES = libopensc.la
libopensc_la_SOURCES = asn1.c base64.c sec.c log.c sc.c card.c iso7816.c \
dir.c pkcs15.c pkcs15-cert.c pkcs15-pin.c \
pkcs15-prkey.c pkcs15-sec.c pkcs15-cache.c \
$(PCSC_SRC) \
pkcs15-prkey.c pkcs15-pubkey.c pkcs15-sec.c \
pkcs15-cache.c $(PCSC_SRC) \
card-setcos.c card-miocos.c card-flex.c card-gpk.c \
card-tcos.c card-emv.c card-default.c
libopensc_la_LDFLAGS = -version-info 0:6:0

View File

@ -707,17 +707,17 @@ static int asn1_decode_p15_object(struct sc_context *ctx, const u8 *in,
int depth)
{
int r;
struct sc_pkcs15_common_obj_attr *com_attr = obj->com_attr;
struct sc_pkcs15_object *p15_obj = obj->p15_obj;
struct sc_asn1_entry asn1_c_attr[6], asn1_p15_obj[5];
size_t flags_len = sizeof(com_attr->flags);
size_t label_len = sizeof(com_attr->label);
size_t flags_len = sizeof(p15_obj->flags);
size_t label_len = sizeof(p15_obj->label);
sc_copy_asn1_entry(c_asn1_com_obj_attr, asn1_c_attr);
sc_copy_asn1_entry(c_asn1_p15_obj, asn1_p15_obj);
sc_format_asn1_entry(asn1_c_attr + 0, com_attr->label, &label_len, 0);
sc_format_asn1_entry(asn1_c_attr + 1, &com_attr->flags, &flags_len, 0);
sc_format_asn1_entry(asn1_c_attr + 2, &com_attr->auth_id, NULL, 0);
sc_format_asn1_entry(asn1_c_attr + 3, &com_attr->user_consent, NULL, 0);
sc_format_asn1_entry(asn1_c_attr + 0, p15_obj->label, &label_len, 0);
sc_format_asn1_entry(asn1_c_attr + 1, &p15_obj->flags, &flags_len, 0);
sc_format_asn1_entry(asn1_c_attr + 2, &p15_obj->auth_id, NULL, 0);
sc_format_asn1_entry(asn1_c_attr + 3, &p15_obj->user_consent, NULL, 0);
/* FIXME: encode accessControlRules */
sc_format_asn1_entry(asn1_c_attr + 4, NULL, NULL, 0);
sc_format_asn1_entry(asn1_p15_obj + 0, asn1_c_attr, NULL, 0);
@ -733,23 +733,23 @@ static int asn1_encode_p15_object(struct sc_context *ctx, const struct sc_asn1_p
u8 **buf, size_t *bufsize, int depth)
{
int r;
const struct sc_pkcs15_common_obj_attr *com_attr = obj->com_attr;
const struct sc_pkcs15_object *p15_obj = obj->p15_obj;
struct sc_asn1_entry asn1_c_attr[6], asn1_p15_obj[5];
size_t flags_len;
size_t label_len = strlen(com_attr->label);
size_t label_len = strlen(p15_obj->label);
sc_copy_asn1_entry(c_asn1_com_obj_attr, asn1_c_attr);
sc_copy_asn1_entry(c_asn1_p15_obj, asn1_p15_obj);
if (label_len != 0)
sc_format_asn1_entry(asn1_c_attr + 0, (void *) com_attr->label, &label_len, 1);
if (com_attr->flags) {
flags_len = _sc_count_bit_string_size(&com_attr->flags, sizeof(com_attr->flags));
sc_format_asn1_entry(asn1_c_attr + 1, (void *) &com_attr->flags, &flags_len, 1);
sc_format_asn1_entry(asn1_c_attr + 0, (void *) p15_obj->label, &label_len, 1);
if (p15_obj->flags) {
flags_len = _sc_count_bit_string_size(&p15_obj->flags, sizeof(p15_obj->flags));
sc_format_asn1_entry(asn1_c_attr + 1, (void *) &p15_obj->flags, &flags_len, 1);
}
if (com_attr->auth_id.len)
sc_format_asn1_entry(asn1_c_attr + 2, (void *) &com_attr->auth_id, NULL, 1);
if (com_attr->user_consent)
sc_format_asn1_entry(asn1_c_attr + 3, (void *) &com_attr->user_consent, NULL, 1);
if (p15_obj->auth_id.len)
sc_format_asn1_entry(asn1_c_attr + 2, (void *) &p15_obj->auth_id, NULL, 1);
if (p15_obj->user_consent)
sc_format_asn1_entry(asn1_c_attr + 3, (void *) &p15_obj->user_consent, NULL, 1);
/* FIXME: decode accessControlRules */
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);

View File

@ -34,7 +34,7 @@ struct sc_asn1_entry {
};
struct sc_asn1_pkcs15_object {
struct sc_pkcs15_common_obj_attr *com_attr;
struct sc_pkcs15_object *p15_obj;
struct sc_asn1_entry *asn1_class_attr;
struct sc_asn1_entry *asn1_subclass_attr;
struct sc_asn1_entry *asn1_type_attr;

View File

@ -46,15 +46,6 @@ struct sc_pkcs15_id {
#define SC_PKCS15_CO_FLAG_MODIFIABLE 0x00000002
#define SC_PKCS15_CO_FLAG_OBJECT_SEEN 0x80000000 /* for PKCS #11 module */
struct sc_pkcs15_common_obj_attr {
char label[SC_PKCS15_MAX_LABEL_SIZE]; /* zero terminated */
int flags;
struct sc_pkcs15_id auth_id;
int user_consent;
/* FIXME: add accessControlRules */
};
#define SC_PKCS15_PIN_FLAG_CASE_SENSITIVE 0x0001
#define SC_PKCS15_PIN_FLAG_LOCAL 0x0002
#define SC_PKCS15_PIN_FLAG_CHANGE_DISABLED 0x0004
@ -73,8 +64,6 @@ struct sc_pkcs15_common_obj_attr {
#define SC_PKCS15_PIN_TYPE_UTF8 2
struct sc_pkcs15_pin_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id auth_id;
int reference;
int flags, type;
@ -100,11 +89,11 @@ struct sc_pkcs15_algorithm_info {
int algorithm, supported_operations;
};
struct sc_pkcs15_rsa_pubkey {
struct sc_pkcs15_pubkey_rsa {
u8 *modulus;
int modulus_len;
unsigned int exponent;
u8 *data; /* DER encoded raw key */
int data_len;
};
@ -113,15 +102,13 @@ struct sc_pkcs15_cert {
int version;
unsigned long serial;
struct sc_pkcs15_rsa_pubkey key;
struct sc_pkcs15_pubkey_rsa key;
u8 *data; /* DER encoded raw cert */
int data_len;
};
struct sc_pkcs15_cert_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id id; /* correlates to private RSA key id */
struct sc_pkcs15_id id; /* correlates to private key id */
int authority; /* boolean */
/* identifiers [2] SEQUENCE OF CredentialIdentifier{{KeyIdentifiers}} */
struct sc_path path;
@ -145,8 +132,6 @@ struct sc_pkcs15_cert_info {
#define SC_PKCS15_PRKEY_ACCESS_LOCAL 0x10
struct sc_pkcs15_prkey_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id id; /* correlates to public certificate id */
unsigned int usage, access_flags;
int native, key_reference;
@ -155,19 +140,44 @@ struct sc_pkcs15_prkey_info {
struct sc_path path;
};
#define SC_PKCS15_TYPE_PRKEY_RSA 0x100
#define SC_PKCS15_TYPE_PUBKEY_RSA 0x200
#define SC_PKCS15_TYPE_CERT_X509 0x400
struct sc_pkcs15_pubkey_info {
struct sc_pkcs15_id id; /* correlates to private key id */
unsigned int usage, access_flags;
int native, key_reference;
int modulus_length;
struct sc_path path;
};
#define SC_PKCS15_TYPE_CLASS_MASK 0xF00
#define SC_PKCS15_TYPE_PRKEY 0x100
#define SC_PKCS15_TYPE_PRKEY_RSA 0x101
#define SC_PKCS15_TYPE_PUBKEY 0x200
#define SC_PKCS15_TYPE_PUBKEY_RSA 0x201
#define SC_PKCS15_TYPE_CERT 0x400
#define SC_PKCS15_TYPE_CERT_X509 0x401
#define SC_PKCS15_TYPE_CERT_SPKI 0x402
#define SC_PKCS15_TYPE_DATA_OBJECT 0x500
#define SC_PKCS15_TYPE_AUTH_PIN 0x600
#define SC_PKCS15_TYPE_AUTH 0x600
#define SC_PKCS15_TYPE_AUTH_PIN 0x601
struct sc_pkcs15_object {
int type;
/* CommonObjectAttributes */
char label[SC_PKCS15_MAX_LABEL_SIZE]; /* zero terminated */
int flags;
struct sc_pkcs15_id auth_id;
int user_consent;
/* Object type specific data */
void *data;
/* For linked list purposes */
struct sc_pkcs15_object *next;
struct sc_pkcs15_object *next; /* used only internally */
};
#define SC_PKCS15_PRKDF 0
@ -187,6 +197,7 @@ struct sc_pkcs15_df {
struct sc_file *file[SC_PKCS15_MAX_DFS];
struct sc_pkcs15_object *obj[SC_PKCS15_MAX_DFS];
int count, record_length, type;
int enumerated;
};
#define SC_PKCS15_CARD_MAGIC 0x10203040
@ -199,14 +210,6 @@ struct sc_pkcs15_card {
char *serial_number, *manufacturer_id;
unsigned long flags;
struct sc_pkcs15_algorithm_info alg_info[1];
/* FIXME: this could be done better with some C pre-processor
* magic */
struct sc_pkcs15_cert_info cert_info[SC_PKCS15_MAX_CERTS];
int cert_count;
struct sc_pkcs15_prkey_info prkey_info[SC_PKCS15_MAX_PRKEYS];
int prkey_count;
struct sc_pkcs15_pin_info pin_info[SC_PKCS15_MAX_PINS];
int pin_count;
struct sc_file *file_app;
struct sc_file *file_tokeninfo, *file_odf;
@ -223,7 +226,7 @@ struct sc_pkcs15_card {
#define SC_PKCS15_CARD_FLAG_EID_COMPLIANT 0x08
/* sc_pkcs15_bind: Binds a card object to a PKCS #15 card object
* and initializes a new PKCS#15 card object. Will return
* and initializes a new PKCS #15 card object. Will return
* SC_ERROR_PKCS15_APP_NOT_FOUND, if the card hasn't got a
* valid PKCS #15 file structure. */
int sc_pkcs15_bind(struct sc_card *card,
@ -232,6 +235,13 @@ int sc_pkcs15_bind(struct sc_card *card,
* memory allocations done on the card object. */
int sc_pkcs15_unbind(struct sc_pkcs15_card *card);
int sc_pkcs15_get_objects(struct sc_pkcs15_card *card, int type,
struct sc_pkcs15_object **ret, int ret_count);
int sc_pkcs15_get_objects_cond(struct sc_pkcs15_card *card, int type,
int (* func)(struct sc_pkcs15_object *, void *),
void *func_arg,
struct sc_pkcs15_object **ret, int ret_count);
struct sc_pkcs15_card * sc_pkcs15_card_new();
void sc_pkcs15_card_free(struct sc_pkcs15_card *p15card);
@ -250,14 +260,13 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
void sc_pkcs15_print_card(const struct sc_pkcs15_card *card);
void sc_pkcs15_print_cert_info(const struct sc_pkcs15_cert_info *cert);
int sc_pkcs15_enum_certificates(struct sc_pkcs15_card *card);
int sc_pkcs15_read_certificate(struct sc_pkcs15_card *card,
const struct sc_pkcs15_cert_info *info,
struct sc_pkcs15_cert **cert);
void sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert);
int sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id,
struct sc_pkcs15_cert_info **out);
struct sc_pkcs15_object **out);
/* sc_pkcs15_create_cdf: Creates a new certificate DF on a card pointed
* by <card>. Information about the file, such as the file ID, is read
* from <file>. <certs> has to be NULL-terminated. */
@ -267,23 +276,21 @@ int sc_pkcs15_create_cdf(struct sc_pkcs15_card *card,
int sc_pkcs15_create(struct sc_pkcs15_card *p15card, struct sc_card *card);
void sc_pkcs15_print_prkey_info(const struct sc_pkcs15_prkey_info *prkey);
int sc_pkcs15_enum_private_keys(struct sc_pkcs15_card *card);
int sc_pkcs15_find_prkey_by_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id,
struct sc_pkcs15_prkey_info **out);
struct sc_pkcs15_object **out);
void sc_pkcs15_print_pin_info(const struct sc_pkcs15_pin_info *pin);
int sc_pkcs15_enum_pins(struct sc_pkcs15_card *card);
void sc_pkcs15_print_pin_info(const struct sc_pkcs15_pin_info *auth);
int sc_pkcs15_verify_pin(struct sc_pkcs15_card *card,
struct sc_pkcs15_pin_info *pin,
const u8 *pincode, int pinlen);
const u8 *pincode, size_t pinlen);
int sc_pkcs15_change_pin(struct sc_pkcs15_card *card,
struct sc_pkcs15_pin_info *pin,
const u8 *oldpincode, int oldpinlen,
const u8 *newpincode, int newpinlen);
const u8 *oldpincode, size_t oldpinlen,
const u8 *newpincode, size_t newpinlen);
int sc_pkcs15_find_pin_by_auth_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id,
struct sc_pkcs15_pin_info **out);
struct sc_pkcs15_object **out);
int sc_pkcs15_encode_dir(struct sc_context *ctx,
struct sc_pkcs15_card *card,
@ -303,6 +310,9 @@ int sc_pkcs15_encode_cdf_entry(struct sc_context *ctx,
int sc_pkcs15_encode_prkdf_entry(struct sc_context *ctx,
const struct sc_pkcs15_object *obj, u8 **buf,
size_t *bufsize);
int sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx,
const struct sc_pkcs15_object *obj, u8 **buf,
size_t *bufsize);
int sc_pkcs15_encode_aodf_entry(struct sc_context *ctx,
const struct sc_pkcs15_object *obj, u8 **buf,
size_t *bufsize);

View File

@ -29,9 +29,9 @@
#include <unistd.h>
#include <assert.h>
static int parse_rsa_pubkey(struct sc_context *ctx, struct sc_pkcs15_rsa_pubkey *key)
static int parse_pubkey_rsa(struct sc_context *ctx, struct sc_pkcs15_pubkey_rsa *key)
{
struct sc_asn1_entry asn1_rsa_pubkey[] = {
struct sc_asn1_entry asn1_pubkey_rsa[] = {
{ "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 }
@ -46,7 +46,7 @@ static int parse_rsa_pubkey(struct sc_context *ctx, struct sc_pkcs15_rsa_pubkey
error(ctx, "RSA public key not found\n");
return SC_ERROR_INVALID_ASN1_OBJECT;
}
r = sc_asn1_decode(ctx, asn1_rsa_pubkey, obj, objlen, NULL, NULL);
r = sc_asn1_decode(ctx, asn1_pubkey_rsa, obj, objlen, NULL, NULL);
SC_TEST_RET(ctx, r, "ASN.1 parsing failed");
return 0;
@ -76,7 +76,7 @@ static int parse_algorithm_id(struct sc_context *ctx, void *arg, const u8 *obj,
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 sc_pkcs15_pubkey_rsa *key = &cert->key;
struct asn1_algorithm_id pk_alg, sig_alg;
u8 *pk = NULL;
size_t pklen = 0;
@ -123,7 +123,7 @@ static int parse_x509_cert(struct sc_context *ctx, const u8 *buf, size_t buflen,
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);
r = parse_pubkey_rsa(ctx, key);
if (r) {
free(key->data);
return SC_ERROR_INVALID_ASN1_OBJECT;
@ -219,7 +219,7 @@ int sc_pkcs15_decode_cdf_entry(struct sc_pkcs15_card *p15card,
struct sc_asn1_entry asn1_cred_ident[3], asn1_com_cert_attr[4],
asn1_x509_cert_attr[2], asn1_type_cert_attr[2],
asn1_cert[2];
struct sc_asn1_pkcs15_object cert_obj = { &info.com_attr, asn1_com_cert_attr, NULL,
struct sc_asn1_pkcs15_object cert_obj = { obj, asn1_com_cert_attr, NULL,
asn1_type_cert_attr };
u8 id_value[128];
int id_type, id_value_len = sizeof(id_value);
@ -254,12 +254,6 @@ int sc_pkcs15_decode_cdf_entry(struct sc_pkcs15_card *p15card,
SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY);
memcpy(obj->data, &info, sizeof(info));
/* Legacy code */
if (p15card->cert_count >= SC_PKCS15_MAX_CERTS)
return SC_ERROR_TOO_MANY_OBJECTS;
p15card->cert_info[p15card->cert_count] = info;
p15card->cert_count++;
return 0;
}
@ -272,8 +266,9 @@ int sc_pkcs15_encode_cdf_entry(struct sc_context *ctx,
asn1_cert[2];
struct sc_pkcs15_cert_info *infop =
(struct sc_pkcs15_cert_info *) obj->data;
const struct sc_asn1_pkcs15_object cert_obj = { &infop->com_attr, asn1_com_cert_attr, NULL,
asn1_type_cert_attr };
const struct sc_asn1_pkcs15_object cert_obj = { (struct sc_pkcs15_object *) obj,
asn1_com_cert_attr, NULL,
asn1_type_cert_attr };
int r;
sc_copy_asn1_entry(c_asn1_cred_ident, asn1_cred_ident);
@ -294,51 +289,6 @@ int sc_pkcs15_encode_cdf_entry(struct sc_context *ctx,
return r;
}
void sc_pkcs15_print_cert_info(const struct sc_pkcs15_cert_info *cert)
{
int i;
printf("X.509 Certificate [%s]\n", cert->com_attr.label);
printf("\tFlags : %d\n", cert->com_attr.flags);
printf("\tAuthority: %s\n", cert->authority ? "yes" : "no");
printf("\tPath : ");
for (i = 0; i < cert->path.len; i++)
printf("%02X", cert->path.value[i]);
printf("\n");
printf("\tID : ");
sc_pkcs15_print_id(&cert->id);
printf("\n");
}
int sc_pkcs15_enum_certificates(struct sc_pkcs15_card *p15card)
{
int r = 0, i, j;
const int df_types[] = {
SC_PKCS15_CDF, SC_PKCS15_CDF_TRUSTED, SC_PKCS15_CDF_USEFUL
};
const int nr_types = sizeof(df_types)/sizeof(df_types[0]);
assert(p15card != NULL);
if (p15card->cert_count)
return p15card->cert_count; /* already enumerated */
r = sc_lock(p15card->card);
SC_TEST_RET(p15card->card->ctx, r, "sc_lock() failed");
for (j = 0; j < nr_types; j++) {
int type = df_types[j];
for (i = 0; i < p15card->df[type].count; i++) {
r = sc_pkcs15_parse_df(p15card, &p15card->df[type], i);
if (r != 0)
break;
}
if (r != 0)
break;
}
sc_unlock(p15card->card);
if (r != 0)
return r;
return p15card->cert_count;
}
void sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert)
{
assert(cert != NULL);
@ -348,22 +298,3 @@ void sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert)
free(cert->data);
free(cert);
}
int sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id,
struct sc_pkcs15_cert_info **cert_out)
{
int r, i;
r = sc_pkcs15_enum_certificates(card);
if (r < 0)
return r;
for (i = 0; i < card->cert_count; i++) {
struct sc_pkcs15_cert_info *cert = &card->cert_info[i];
if (sc_pkcs15_compare_id(&cert->id, id) == 1) {
*cert_out = cert;
return 0;
}
}
return SC_ERROR_OBJECT_NOT_FOUND;
}

View File

@ -63,8 +63,7 @@ int sc_pkcs15_decode_aodf_entry(struct sc_pkcs15_card *p15card,
int padchar_len = 1;
struct sc_asn1_entry asn1_com_ao_attr[2], asn1_pin_attr[10], asn1_type_pin_attr[2];
struct sc_asn1_entry asn1_pin[2];
struct sc_asn1_pkcs15_object pin_obj = { &info.com_attr, asn1_com_ao_attr, NULL,
asn1_type_pin_attr };
struct sc_asn1_pkcs15_object pin_obj = { obj, asn1_com_ao_attr, NULL, asn1_type_pin_attr };
sc_copy_asn1_entry(c_asn1_pin, asn1_pin);
sc_copy_asn1_entry(c_asn1_type_pin_attr, asn1_type_pin_attr);
sc_copy_asn1_entry(c_asn1_pin_attr, asn1_pin_attr);
@ -99,12 +98,6 @@ int sc_pkcs15_decode_aodf_entry(struct sc_pkcs15_card *p15card,
SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY);
memcpy(obj->data, &info, sizeof(info));
/* Legacy code */
if (p15card->pin_count >= SC_PKCS15_MAX_PINS)
return SC_ERROR_TOO_MANY_OBJECTS;
p15card->pin_info[p15card->pin_count] = info;
p15card->pin_count++;
return 0;
}
@ -116,8 +109,9 @@ int sc_pkcs15_encode_aodf_entry(struct sc_context *ctx,
struct sc_asn1_entry asn1_pin[2];
struct sc_pkcs15_pin_info *pin =
(struct sc_pkcs15_pin_info *) obj->data;
struct sc_asn1_pkcs15_object pin_obj = { &pin->com_attr, asn1_com_ao_attr, NULL,
asn1_type_pin_attr };
struct sc_asn1_pkcs15_object pin_obj = { (struct sc_pkcs15_object *) obj,
asn1_com_ao_attr, NULL,
asn1_type_pin_attr };
int r;
int flags_len = sizeof(pin->flags);
int padchar_len = 1;
@ -149,85 +143,9 @@ int sc_pkcs15_encode_aodf_entry(struct sc_context *ctx,
return r;
}
void sc_pkcs15_print_pin_info(const struct sc_pkcs15_pin_info *pin)
{
const char *pin_flags[] = {
"case-sensitive", "local", "change-disabled",
"unblock-disabled", "initialized", "needs-padding",
"unblockingPin", "soPin", "disable_allowed",
"integrity-protected", "confidentiality-protected",
"exchangeRefData"
};
const int pf_count = sizeof(pin_flags)/sizeof(pin_flags[0]);
char path[SC_MAX_PATH_SIZE * 2 + 1];
int i;
char *p;
p = path;
*p = 0;
for (i = 0; i < pin->path.len; i++) {
sprintf(p, "%02X", pin->path.value[i]);
p += 2;
}
printf("PIN [%s]\n", pin->com_attr.label);
printf("\tCom. Flags: 0x%X\n", pin->com_attr.flags);
printf("\tAuth ID : ");
sc_pkcs15_print_id(&pin->auth_id);
printf("\n");
printf("\tFlags : [0x%02X]", pin->flags);
for (i = 0; i < pf_count; i++)
if (pin->flags & (1 << i)) {
printf(", %s", pin_flags[i]);
}
printf("\n");
printf("\tLength : %d..%d\n", pin->min_length, pin->stored_length);
printf("\tPad char : 0x%02X\n", pin->pad_char);
printf("\tReference : %d\n", pin->reference);
printf("\tType : %d\n", pin->type);
printf("\tPath : %s\n", path);
}
int sc_pkcs15_enum_pins(struct sc_pkcs15_card *p15card)
{
int r, i, j;
const int df_types[] = {
SC_PKCS15_AODF
};
const int nr_types = sizeof(df_types)/sizeof(df_types[0]);
assert(p15card != NULL);
SC_FUNC_CALLED(p15card->card->ctx, 1);
if (p15card->pin_count) {
for (i = 0; i < p15card->pin_count; i++) {
if (p15card->pin_info[i].magic != SC_PKCS15_PIN_MAGIC)
break;
}
if (i == p15card->pin_count)
return i; /* Already enumerated */
}
p15card->pin_count = 0;
r = sc_lock(p15card->card);
SC_TEST_RET(p15card->card->ctx, r, "sc_lock() failed");
for (j = 0; r == 0 && j < nr_types; j++) {
int type = df_types[j];
for (i = 0; r == 0 && i < p15card->df[type].count; i++) {
r = sc_pkcs15_parse_df(p15card, &p15card->df[type], i);
if (r != 0)
break;
}
if (r != 0)
break;
}
sc_unlock(p15card->card);
if (r != 0)
return r;
return p15card->pin_count;
}
int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card,
struct sc_pkcs15_pin_info *pin,
const u8 *pincode, int pinlen)
const u8 *pincode, size_t pinlen)
{
int r;
struct sc_card *card;
@ -260,8 +178,8 @@ int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card,
int sc_pkcs15_change_pin(struct sc_pkcs15_card *p15card,
struct sc_pkcs15_pin_info *pin,
const u8 *oldpin, int oldpinlen,
const u8 *newpin, int newpinlen)
const u8 *oldpin, size_t oldpinlen,
const u8 *newpin, size_t newpinlen)
{
int r;
struct sc_card *card;
@ -293,22 +211,3 @@ int sc_pkcs15_change_pin(struct sc_pkcs15_card *p15card,
sc_unlock(card);
return r;
}
int sc_pkcs15_find_pin_by_auth_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id,
struct sc_pkcs15_pin_info **pin_out)
{
int r, i;
r = sc_pkcs15_enum_pins(card);
if (r < 0)
return r;
for (i = 0; i < card->pin_count; i++) {
struct sc_pkcs15_pin_info *pin = &card->pin_info[i];
if (sc_pkcs15_compare_id(&pin->auth_id, id) == 1) {
*pin_out = pin;
return 0;
}
}
return SC_ERROR_OBJECT_NOT_FOUND;
}

View File

@ -27,50 +27,6 @@
#include <stdio.h>
#include <assert.h>
void sc_pkcs15_print_prkey_info(const struct sc_pkcs15_prkey_info *prkey)
{
int i;
const char *usages[] = {
"encrypt", "decrypt", "sign", "signRecover",
"wrap", "unwrap", "verify", "verifyRecover",
"derive", "nonRepudiation"
};
const int usage_count = sizeof(usages)/sizeof(usages[0]);
const char *access_flags[] = {
"sensitive", "extract", "alwaysSensitive",
"neverExtract", "local"
};
const int af_count = sizeof(access_flags)/sizeof(access_flags[0]);
printf("Private RSA Key [%s]\n", prkey->com_attr.label);
printf("\tCom. Flags : %X\n", prkey->com_attr.flags);
printf("\tUsage : [0x%X]", prkey->usage);
for (i = 0; i < usage_count; i++)
if (prkey->usage & (1 << i)) {
printf(", %s", usages[i]);
}
printf("\n");
printf("\tAccess Flags: [0x%X]", prkey->access_flags);
for (i = 0; i < af_count; i++)
if (prkey->access_flags & (1 << i)) {
printf(", %s", access_flags[i]);
}
printf("\n");
printf("\tModLength : %d\n", prkey->modulus_length);
printf("\tKey ref : %d\n", prkey->key_reference);
printf("\tNative : %s\n", prkey->native ? "yes" : "no");
printf("\tPath : ");
for (i = 0; i < prkey->path.len; i++)
printf("%02X", prkey->path.value[i]);
printf("\n");
printf("\tAuth ID : ");
sc_pkcs15_print_id(&prkey->com_attr.auth_id);
printf("\n");
printf("\tID : ");
sc_pkcs15_print_id(&prkey->id);
printf("\n");
}
static const struct sc_asn1_entry c_asn1_com_key_attr[] = {
{ "iD", SC_ASN1_PKCS15_ID, ASN1_OCTET_STRING, 0, NULL },
{ "usage", SC_ASN1_BIT_STRING, ASN1_BIT_STRING, 0, NULL },
@ -114,8 +70,8 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card,
struct sc_asn1_entry asn1_com_key_attr[6], asn1_com_prkey_attr[1];
struct sc_asn1_entry asn1_rsakey_attr[4], asn1_type_attr[2];
struct sc_asn1_entry asn1_prkey[2];
struct sc_asn1_pkcs15_object prkey_obj = { &info.com_attr, asn1_com_key_attr,
asn1_com_prkey_attr, asn1_type_attr };
struct sc_asn1_pkcs15_object prkey_obj = { obj, asn1_com_key_attr,
asn1_com_prkey_attr, asn1_type_attr };
sc_copy_asn1_entry(c_asn1_prkey, asn1_prkey);
sc_copy_asn1_entry(c_asn1_type_attr, asn1_type_attr);
@ -151,12 +107,6 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card,
SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY);
memcpy(obj->data, &info, sizeof(info));
/* Legacy code */
if (p15card->prkey_count >= SC_PKCS15_MAX_PRKEYS)
return SC_ERROR_TOO_MANY_OBJECTS;
p15card->prkey_info[p15card->prkey_count] = info;
p15card->prkey_count++;
return 0;
}
int sc_pkcs15_encode_prkdf_entry(struct sc_context *ctx,
@ -168,7 +118,8 @@ int sc_pkcs15_encode_prkdf_entry(struct sc_context *ctx,
struct sc_asn1_entry asn1_prkey[2];
struct sc_pkcs15_prkey_info *prkey =
(struct sc_pkcs15_prkey_info *) obj->data;
struct sc_asn1_pkcs15_object prkey_obj = { &prkey->com_attr, asn1_com_key_attr,
struct sc_asn1_pkcs15_object prkey_obj = { (struct sc_pkcs15_object *) obj,
asn1_com_key_attr,
asn1_com_prkey_attr, asn1_type_attr };
int r;
int af_len, usage_len;
@ -201,53 +152,3 @@ int sc_pkcs15_encode_prkdf_entry(struct sc_context *ctx,
return r;
}
int sc_pkcs15_enum_private_keys(struct sc_pkcs15_card *p15card)
{
int r, i, j;
const int df_types[] = {
SC_PKCS15_PRKDF
};
const int nr_types = sizeof(df_types)/sizeof(df_types[0]);
assert(p15card != NULL);
SC_FUNC_CALLED(p15card->card->ctx, 1);
if (p15card->prkey_count)
return p15card->prkey_count; /* already enumerated */
r = sc_lock(p15card->card);
SC_TEST_RET(p15card->card->ctx, r, "sc_lock() failed");
for (j = 0; r == 0 && j < nr_types; j++) {
int type = df_types[j];
for (i = 0; r == 0 && i < p15card->df[type].count; i++) {
r = sc_pkcs15_parse_df(p15card, &p15card->df[type], i);
if (r != 0)
break;
}
if (r != 0)
break;
}
sc_unlock(p15card->card);
if (r != 0)
return r;
return p15card->prkey_count;
}
int sc_pkcs15_find_prkey_by_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id,
struct sc_pkcs15_prkey_info **key_out)
{
int r, i;
r = sc_pkcs15_enum_private_keys(card);
if (r < 0)
return r;
for (i = 0; i < card->prkey_count; i++) {
struct sc_pkcs15_prkey_info *key = &card->prkey_info[i];
if (sc_pkcs15_compare_id(&key->id, id) == 1) {
*key_out = key;
return 0;
}
}
return SC_ERROR_OBJECT_NOT_FOUND;
}

View File

@ -0,0 +1,154 @@
/*
* pkcs15-pubkey.c: PKCS #15 public key functions
*
* Copyright (C) 2002 Juha Yrjölä <juha.yrjola@iki.fi>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sc-internal.h"
#include "opensc-pkcs15.h"
#include "sc-asn1.h"
#include "sc-log.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
static const struct sc_asn1_entry c_asn1_com_key_attr[] = {
{ "iD", SC_ASN1_PKCS15_ID, ASN1_OCTET_STRING, 0, NULL },
{ "usage", SC_ASN1_BIT_STRING, ASN1_BIT_STRING, 0, NULL },
{ "native", SC_ASN1_BOOLEAN, ASN1_BOOLEAN, SC_ASN1_OPTIONAL, NULL },
{ "accessFlags", SC_ASN1_BIT_STRING, ASN1_BIT_STRING, SC_ASN1_OPTIONAL, NULL },
{ "keyReference",SC_ASN1_INTEGER, ASN1_INTEGER, SC_ASN1_OPTIONAL, NULL },
{ NULL }
};
static const struct sc_asn1_entry c_asn1_com_pubkey_attr[] = {
/* FIXME */
{ NULL }
};
static const struct sc_asn1_entry c_asn1_rsakey_attr[] = {
{ "value", SC_ASN1_PATH, ASN1_SEQUENCE | SC_ASN1_CONS, 0, NULL },
{ "modulusLength", SC_ASN1_INTEGER, ASN1_INTEGER, 0, NULL },
{ "keyInfo", SC_ASN1_INTEGER, ASN1_INTEGER, SC_ASN1_OPTIONAL, NULL },
{ NULL }
};
static const struct sc_asn1_entry c_asn1_type_attr[] = {
{ "privateRSAKeyAttributes", SC_ASN1_STRUCT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, NULL },
{ NULL }
};
static const struct sc_asn1_entry c_asn1_pubkey[] = {
{ "publicRSAKey", SC_ASN1_PKCS15_OBJECT, ASN1_SEQUENCE | SC_ASN1_CONS, 0, NULL },
{ NULL }
};
int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card,
struct sc_pkcs15_object *obj,
const u8 ** buf, size_t *buflen)
{
struct sc_context *ctx = p15card->card->ctx;
struct sc_pkcs15_pubkey_info info;
int r;
int usage_len = sizeof(info.usage);
int af_len = sizeof(info.access_flags);
struct sc_asn1_entry asn1_com_key_attr[6], asn1_com_pubkey_attr[1];
struct sc_asn1_entry asn1_rsakey_attr[4], asn1_type_attr[2];
struct sc_asn1_entry asn1_pubkey[2];
struct sc_asn1_pkcs15_object pubkey_obj = { obj, asn1_com_key_attr,
asn1_com_pubkey_attr, asn1_type_attr };
sc_copy_asn1_entry(c_asn1_pubkey, asn1_pubkey);
sc_copy_asn1_entry(c_asn1_type_attr, asn1_type_attr);
sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr);
sc_copy_asn1_entry(c_asn1_com_pubkey_attr, asn1_com_pubkey_attr);
sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr);
sc_format_asn1_entry(asn1_pubkey + 0, &pubkey_obj, NULL, 0);
sc_format_asn1_entry(asn1_type_attr + 0, asn1_rsakey_attr, NULL, 0);
sc_format_asn1_entry(asn1_rsakey_attr + 0, &info.path, NULL, 0);
sc_format_asn1_entry(asn1_rsakey_attr + 1, &info.modulus_length, NULL, 0);
sc_format_asn1_entry(asn1_com_key_attr + 0, &info.id, NULL, 0);
sc_format_asn1_entry(asn1_com_key_attr + 1, &info.usage, &usage_len, 0);
sc_format_asn1_entry(asn1_com_key_attr + 2, &info.native, NULL, 0);
sc_format_asn1_entry(asn1_com_key_attr + 3, &info.access_flags, &af_len, 0);
sc_format_asn1_entry(asn1_com_key_attr + 4, &info.key_reference, NULL, 0);
/* Fill in defaults */
memset(&info, 0, sizeof(info));
info.key_reference = -1;
info.native = 1;
r = sc_asn1_decode(ctx, asn1_pubkey, *buf, *buflen, buf, buflen);
if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
return r;
SC_TEST_RET(ctx, r, "ASN.1 decoding failed");
obj->type = SC_PKCS15_TYPE_PUBKEY_RSA;
obj->data = malloc(sizeof(info));
if (obj->data == NULL)
SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY);
memcpy(obj->data, &info, sizeof(info));
return 0;
}
int sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx,
const struct sc_pkcs15_object *obj,
u8 **buf, size_t *buflen)
{
struct sc_asn1_entry asn1_com_key_attr[6], asn1_com_pubkey_attr[1];
struct sc_asn1_entry asn1_rsakey_attr[4], asn1_type_attr[2];
struct sc_asn1_entry asn1_pubkey[2];
struct sc_pkcs15_pubkey_info *pubkey =
(struct sc_pkcs15_pubkey_info *) obj->data;
struct sc_asn1_pkcs15_object pubkey_obj = { (struct sc_pkcs15_object *) obj,
asn1_com_key_attr,
asn1_com_pubkey_attr, asn1_type_attr };
int r;
int af_len, usage_len;
sc_copy_asn1_entry(c_asn1_pubkey, asn1_pubkey);
sc_copy_asn1_entry(c_asn1_type_attr, asn1_type_attr);
sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr);
sc_copy_asn1_entry(c_asn1_com_pubkey_attr, asn1_com_pubkey_attr);
sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr);
sc_format_asn1_entry(asn1_pubkey + 0, &pubkey_obj, NULL, 1);
sc_format_asn1_entry(asn1_type_attr + 0, asn1_rsakey_attr, NULL, 1);
sc_format_asn1_entry(asn1_rsakey_attr + 0, &pubkey->path, NULL, 1);
sc_format_asn1_entry(asn1_rsakey_attr + 1, &pubkey->modulus_length, NULL, 1);
sc_format_asn1_entry(asn1_com_key_attr + 0, &pubkey->id, NULL, 1);
usage_len = _sc_count_bit_string_size(&pubkey->usage, sizeof(pubkey->usage));
sc_format_asn1_entry(asn1_com_key_attr + 1, &pubkey->usage, &usage_len, 1);
if (pubkey->native == 0)
sc_format_asn1_entry(asn1_com_key_attr + 2, &pubkey->native, NULL, 1);
if (pubkey->access_flags) {
af_len = _sc_count_bit_string_size(&pubkey->access_flags, sizeof(pubkey->access_flags));
sc_format_asn1_entry(asn1_com_key_attr + 3, &pubkey->access_flags, &af_len, 1);
}
if (pubkey->key_reference >= 0)
sc_format_asn1_entry(asn1_com_key_attr + 4, &pubkey->key_reference, NULL, 1);
r = sc_asn1_encode(ctx, asn1_pubkey, buf, buflen);
return r;
}

View File

@ -305,8 +305,11 @@ int sc_pkcs15_create_dir(struct sc_pkcs15_card *p15card, struct sc_card *card)
static const struct sc_asn1_entry c_asn1_odf[] = {
{ "privateKeys", SC_ASN1_STRUCT, SC_ASN1_CTX | 0 | SC_ASN1_CONS, 0, NULL },
{ "publicKeys", SC_ASN1_STRUCT, SC_ASN1_CTX | 1 | SC_ASN1_CONS, 0, NULL },
{ "trustedPublicKeys", SC_ASN1_STRUCT, SC_ASN1_CTX | 2 | SC_ASN1_CONS, 0, NULL },
{ "certificates", SC_ASN1_STRUCT, SC_ASN1_CTX | 4 | SC_ASN1_CONS, 0, NULL },
{ "trustedCertificates", SC_ASN1_STRUCT, SC_ASN1_CTX | 5 | SC_ASN1_CONS, 0, NULL },
{ "usefulCertificates", SC_ASN1_STRUCT, SC_ASN1_CTX | 6 | SC_ASN1_CONS, 0, NULL },
{ "dataObjects", SC_ASN1_STRUCT, SC_ASN1_CTX | 7 | SC_ASN1_CONS, 0, NULL },
{ "authObjects", SC_ASN1_STRUCT, SC_ASN1_CTX | 8 | SC_ASN1_CONS, 0, NULL },
{ NULL }
@ -314,8 +317,11 @@ static const struct sc_asn1_entry c_asn1_odf[] = {
static const int odf_indexes[] = {
SC_PKCS15_PRKDF,
SC_PKCS15_PUKDF,
SC_PKCS15_PUKDF_TRUSTED,
SC_PKCS15_CDF,
SC_PKCS15_CDF_TRUSTED,
SC_PKCS15_CDF_USEFUL,
SC_PKCS15_DODF,
SC_PKCS15_AODF,
};
@ -330,7 +336,7 @@ static int parse_odf(const u8 * buf, int buflen, struct sc_pkcs15_card *card)
{ "path", SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_SEQUENCE, 0, &path },
{ NULL }
};
struct sc_asn1_entry asn1_odf[6];
struct sc_asn1_entry asn1_odf[9];
sc_copy_asn1_entry(c_asn1_odf, asn1_odf);
for (i = 0; asn1_odf[i].name != NULL; i++)
@ -593,6 +599,148 @@ int sc_pkcs15_unbind(struct sc_pkcs15_card *p15card)
return 0;
}
int sc_pkcs15_get_objects_cond(struct sc_pkcs15_card *p15card, int type,
int (* func)(struct sc_pkcs15_object *, void *),
void *func_arg,
struct sc_pkcs15_object **ret, int ret_size)
{
const int prkey_df[] = { SC_PKCS15_PRKDF, -1 };
const int pubkey_df[] = { SC_PKCS15_PUKDF, SC_PKCS15_PUKDF_TRUSTED, -1 };
const int cert_df[] = { SC_PKCS15_CDF, SC_PKCS15_CDF_TRUSTED, SC_PKCS15_CDF_USEFUL, -1 };
const int auth_df[] = { SC_PKCS15_AODF, -1 };
const int *dfs;
int count = 0, i, r;
switch (type & SC_PKCS15_TYPE_CLASS_MASK) {
case SC_PKCS15_TYPE_PRKEY:
dfs = prkey_df;
break;
case SC_PKCS15_TYPE_PUBKEY:
dfs = pubkey_df;
break;
case SC_PKCS15_TYPE_CERT:
dfs = cert_df;
break;
case SC_PKCS15_TYPE_AUTH:
dfs = auth_df;
break;
default:
return SC_ERROR_INVALID_ARGUMENTS;
}
for (i = 0; dfs[i] != -1; i++) {
int j;
struct sc_pkcs15_df *df = &p15card->df[dfs[i]];
if (!df->enumerated) {
r = sc_lock(p15card->card);
SC_TEST_RET(p15card->card->ctx, r, "sc_lock() failed");
for (j = 0; j < df->count; j++) {
r = sc_pkcs15_parse_df(p15card, df, j);
if (r < 0)
break;
}
sc_unlock(p15card->card);
SC_TEST_RET(p15card->card->ctx, r, "DF parsing failed");
df->enumerated = 1;
}
for (j = 0; j < df->count; j++) {
struct sc_pkcs15_object *obj = df->obj[j];
for (; obj != NULL; obj = obj->next) {
if (obj->type != type)
continue;
if (func != NULL && func(obj, func_arg) <= 0)
continue;
count++;
}
}
}
if (count == 0)
return 0;
if (ret_size <= 0)
return count;
count = 0;
for (i = 0; dfs[i] != -1; i++) {
int j;
struct sc_pkcs15_df *df = &p15card->df[dfs[i]];
for (j = 0; j < df->count && count < ret_size; j++) {
struct sc_pkcs15_object *obj = df->obj[j];
for (; obj != NULL; obj = obj->next) {
if (count >= ret_size)
break;
if (obj->type != type)
continue;
if (func != NULL && func(obj, func_arg) <= 0)
continue;
ret[count] = obj;
count++;
}
}
}
return count;
}
int sc_pkcs15_get_objects(struct sc_pkcs15_card *p15card, int type,
struct sc_pkcs15_object **ret, int ret_size)
{
return sc_pkcs15_get_objects_cond(p15card, type, NULL, NULL, ret, ret_size);
}
static int compare_obj_id(struct sc_pkcs15_object *obj, void *arg)
{
void *data = obj->data;
const struct sc_pkcs15_id *id = arg;
switch (obj->type) {
case SC_PKCS15_TYPE_CERT_X509:
return sc_pkcs15_compare_id(&((struct sc_pkcs15_cert_info *) data)->id, id);
case SC_PKCS15_TYPE_PRKEY_RSA:
return sc_pkcs15_compare_id(&((struct sc_pkcs15_prkey_info *) data)->id, id);
case SC_PKCS15_TYPE_PUBKEY_RSA:
return sc_pkcs15_compare_id(&((struct sc_pkcs15_pubkey_info *) data)->id, id);
case SC_PKCS15_TYPE_AUTH_PIN:
return sc_pkcs15_compare_id(&((struct sc_pkcs15_pin_info *) data)->auth_id, id);
}
return 0;
}
static int find_by_id(struct sc_pkcs15_card *p15card,
int type, const struct sc_pkcs15_id *id,
struct sc_pkcs15_object **out)
{
int r;
r = sc_pkcs15_get_objects_cond(p15card, type, compare_obj_id, (void *) id, out, 1);
if (r < 0)
return r;
if (r == 0)
return SC_ERROR_OBJECT_NOT_FOUND;
return 0;
}
int sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *p15card,
const struct sc_pkcs15_id *id,
struct sc_pkcs15_object **out)
{
return find_by_id(p15card, SC_PKCS15_TYPE_CERT_X509, id, out);
}
int sc_pkcs15_find_prkey_by_id(struct sc_pkcs15_card *p15card,
const struct sc_pkcs15_id *id,
struct sc_pkcs15_object **out)
{
return find_by_id(p15card, SC_PKCS15_TYPE_PRKEY_RSA, id, out);
}
int sc_pkcs15_find_pin_by_auth_id(struct sc_pkcs15_card *p15card,
const struct sc_pkcs15_id *id,
struct sc_pkcs15_object **out)
{
return find_by_id(p15card, SC_PKCS15_TYPE_AUTH_PIN, id, out);
}
int sc_pkcs15_add_object(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df,
int file_nr, struct sc_pkcs15_object *obj)
{
@ -625,6 +773,10 @@ int sc_pkcs15_encode_df(struct sc_context *ctx,
case SC_PKCS15_PRKDF:
func = sc_pkcs15_encode_prkdf_entry;
break;
case SC_PKCS15_PUKDF:
case SC_PKCS15_PUKDF_TRUSTED:
func = sc_pkcs15_encode_pukdf_entry;
break;
case SC_PKCS15_CDF:
case SC_PKCS15_CDF_TRUSTED:
case SC_PKCS15_CDF_USEFUL:
@ -854,18 +1006,23 @@ int sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card,
struct sc_file *file = NULL;
size_t file_size;
r = sc_lock(p15card->card);
SC_TEST_RET(ctx, r, "sc_lock() failed");
r = sc_select_file(p15card->card, &path, &file);
if (r) {
sc_perror(ctx, r, "sc_select_file() failed");
sc_unlock(p15card->card);
return r;
}
file_size = file->size;
sc_file_free(file);
if (file_size > sizeof(buf)) {
error(ctx, "Buffer too small to handle DF contents\n");
sc_unlock(p15card->card);
return SC_ERROR_INTERNAL;
}
r = sc_read_binary(p15card->card, 0, buf, file_size, 0);
sc_unlock(p15card->card);
if (r < 0)
return r;
bufsize = file_size;

View File

@ -46,15 +46,6 @@ struct sc_pkcs15_id {
#define SC_PKCS15_CO_FLAG_MODIFIABLE 0x00000002
#define SC_PKCS15_CO_FLAG_OBJECT_SEEN 0x80000000 /* for PKCS #11 module */
struct sc_pkcs15_common_obj_attr {
char label[SC_PKCS15_MAX_LABEL_SIZE]; /* zero terminated */
int flags;
struct sc_pkcs15_id auth_id;
int user_consent;
/* FIXME: add accessControlRules */
};
#define SC_PKCS15_PIN_FLAG_CASE_SENSITIVE 0x0001
#define SC_PKCS15_PIN_FLAG_LOCAL 0x0002
#define SC_PKCS15_PIN_FLAG_CHANGE_DISABLED 0x0004
@ -73,8 +64,6 @@ struct sc_pkcs15_common_obj_attr {
#define SC_PKCS15_PIN_TYPE_UTF8 2
struct sc_pkcs15_pin_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id auth_id;
int reference;
int flags, type;
@ -100,11 +89,11 @@ struct sc_pkcs15_algorithm_info {
int algorithm, supported_operations;
};
struct sc_pkcs15_rsa_pubkey {
struct sc_pkcs15_pubkey_rsa {
u8 *modulus;
int modulus_len;
unsigned int exponent;
u8 *data; /* DER encoded raw key */
int data_len;
};
@ -113,15 +102,13 @@ struct sc_pkcs15_cert {
int version;
unsigned long serial;
struct sc_pkcs15_rsa_pubkey key;
struct sc_pkcs15_pubkey_rsa key;
u8 *data; /* DER encoded raw cert */
int data_len;
};
struct sc_pkcs15_cert_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id id; /* correlates to private RSA key id */
struct sc_pkcs15_id id; /* correlates to private key id */
int authority; /* boolean */
/* identifiers [2] SEQUENCE OF CredentialIdentifier{{KeyIdentifiers}} */
struct sc_path path;
@ -145,8 +132,6 @@ struct sc_pkcs15_cert_info {
#define SC_PKCS15_PRKEY_ACCESS_LOCAL 0x10
struct sc_pkcs15_prkey_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id id; /* correlates to public certificate id */
unsigned int usage, access_flags;
int native, key_reference;
@ -155,19 +140,44 @@ struct sc_pkcs15_prkey_info {
struct sc_path path;
};
#define SC_PKCS15_TYPE_PRKEY_RSA 0x100
#define SC_PKCS15_TYPE_PUBKEY_RSA 0x200
#define SC_PKCS15_TYPE_CERT_X509 0x400
struct sc_pkcs15_pubkey_info {
struct sc_pkcs15_id id; /* correlates to private key id */
unsigned int usage, access_flags;
int native, key_reference;
int modulus_length;
struct sc_path path;
};
#define SC_PKCS15_TYPE_CLASS_MASK 0xF00
#define SC_PKCS15_TYPE_PRKEY 0x100
#define SC_PKCS15_TYPE_PRKEY_RSA 0x101
#define SC_PKCS15_TYPE_PUBKEY 0x200
#define SC_PKCS15_TYPE_PUBKEY_RSA 0x201
#define SC_PKCS15_TYPE_CERT 0x400
#define SC_PKCS15_TYPE_CERT_X509 0x401
#define SC_PKCS15_TYPE_CERT_SPKI 0x402
#define SC_PKCS15_TYPE_DATA_OBJECT 0x500
#define SC_PKCS15_TYPE_AUTH_PIN 0x600
#define SC_PKCS15_TYPE_AUTH 0x600
#define SC_PKCS15_TYPE_AUTH_PIN 0x601
struct sc_pkcs15_object {
int type;
/* CommonObjectAttributes */
char label[SC_PKCS15_MAX_LABEL_SIZE]; /* zero terminated */
int flags;
struct sc_pkcs15_id auth_id;
int user_consent;
/* Object type specific data */
void *data;
/* For linked list purposes */
struct sc_pkcs15_object *next;
struct sc_pkcs15_object *next; /* used only internally */
};
#define SC_PKCS15_PRKDF 0
@ -187,6 +197,7 @@ struct sc_pkcs15_df {
struct sc_file *file[SC_PKCS15_MAX_DFS];
struct sc_pkcs15_object *obj[SC_PKCS15_MAX_DFS];
int count, record_length, type;
int enumerated;
};
#define SC_PKCS15_CARD_MAGIC 0x10203040
@ -199,14 +210,6 @@ struct sc_pkcs15_card {
char *serial_number, *manufacturer_id;
unsigned long flags;
struct sc_pkcs15_algorithm_info alg_info[1];
/* FIXME: this could be done better with some C pre-processor
* magic */
struct sc_pkcs15_cert_info cert_info[SC_PKCS15_MAX_CERTS];
int cert_count;
struct sc_pkcs15_prkey_info prkey_info[SC_PKCS15_MAX_PRKEYS];
int prkey_count;
struct sc_pkcs15_pin_info pin_info[SC_PKCS15_MAX_PINS];
int pin_count;
struct sc_file *file_app;
struct sc_file *file_tokeninfo, *file_odf;
@ -223,7 +226,7 @@ struct sc_pkcs15_card {
#define SC_PKCS15_CARD_FLAG_EID_COMPLIANT 0x08
/* sc_pkcs15_bind: Binds a card object to a PKCS #15 card object
* and initializes a new PKCS#15 card object. Will return
* and initializes a new PKCS #15 card object. Will return
* SC_ERROR_PKCS15_APP_NOT_FOUND, if the card hasn't got a
* valid PKCS #15 file structure. */
int sc_pkcs15_bind(struct sc_card *card,
@ -232,6 +235,13 @@ int sc_pkcs15_bind(struct sc_card *card,
* memory allocations done on the card object. */
int sc_pkcs15_unbind(struct sc_pkcs15_card *card);
int sc_pkcs15_get_objects(struct sc_pkcs15_card *card, int type,
struct sc_pkcs15_object **ret, int ret_count);
int sc_pkcs15_get_objects_cond(struct sc_pkcs15_card *card, int type,
int (* func)(struct sc_pkcs15_object *, void *),
void *func_arg,
struct sc_pkcs15_object **ret, int ret_count);
struct sc_pkcs15_card * sc_pkcs15_card_new();
void sc_pkcs15_card_free(struct sc_pkcs15_card *p15card);
@ -250,14 +260,13 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
void sc_pkcs15_print_card(const struct sc_pkcs15_card *card);
void sc_pkcs15_print_cert_info(const struct sc_pkcs15_cert_info *cert);
int sc_pkcs15_enum_certificates(struct sc_pkcs15_card *card);
int sc_pkcs15_read_certificate(struct sc_pkcs15_card *card,
const struct sc_pkcs15_cert_info *info,
struct sc_pkcs15_cert **cert);
void sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert);
int sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id,
struct sc_pkcs15_cert_info **out);
struct sc_pkcs15_object **out);
/* sc_pkcs15_create_cdf: Creates a new certificate DF on a card pointed
* by <card>. Information about the file, such as the file ID, is read
* from <file>. <certs> has to be NULL-terminated. */
@ -267,23 +276,21 @@ int sc_pkcs15_create_cdf(struct sc_pkcs15_card *card,
int sc_pkcs15_create(struct sc_pkcs15_card *p15card, struct sc_card *card);
void sc_pkcs15_print_prkey_info(const struct sc_pkcs15_prkey_info *prkey);
int sc_pkcs15_enum_private_keys(struct sc_pkcs15_card *card);
int sc_pkcs15_find_prkey_by_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id,
struct sc_pkcs15_prkey_info **out);
struct sc_pkcs15_object **out);
void sc_pkcs15_print_pin_info(const struct sc_pkcs15_pin_info *pin);
int sc_pkcs15_enum_pins(struct sc_pkcs15_card *card);
void sc_pkcs15_print_pin_info(const struct sc_pkcs15_pin_info *auth);
int sc_pkcs15_verify_pin(struct sc_pkcs15_card *card,
struct sc_pkcs15_pin_info *pin,
const u8 *pincode, int pinlen);
const u8 *pincode, size_t pinlen);
int sc_pkcs15_change_pin(struct sc_pkcs15_card *card,
struct sc_pkcs15_pin_info *pin,
const u8 *oldpincode, int oldpinlen,
const u8 *newpincode, int newpinlen);
const u8 *oldpincode, size_t oldpinlen,
const u8 *newpincode, size_t newpinlen);
int sc_pkcs15_find_pin_by_auth_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id,
struct sc_pkcs15_pin_info **out);
struct sc_pkcs15_object **out);
int sc_pkcs15_encode_dir(struct sc_context *ctx,
struct sc_pkcs15_card *card,
@ -303,6 +310,9 @@ int sc_pkcs15_encode_cdf_entry(struct sc_context *ctx,
int sc_pkcs15_encode_prkdf_entry(struct sc_context *ctx,
const struct sc_pkcs15_object *obj, u8 **buf,
size_t *bufsize);
int sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx,
const struct sc_pkcs15_object *obj, u8 **buf,
size_t *bufsize);
int sc_pkcs15_encode_aodf_entry(struct sc_context *ctx,
const struct sc_pkcs15_object *obj, u8 **buf,
size_t *bufsize);

View File

@ -34,7 +34,7 @@ struct sc_asn1_entry {
};
struct sc_asn1_pkcs15_object {
struct sc_pkcs15_common_obj_attr *com_attr;
struct sc_pkcs15_object *p15_obj;
struct sc_asn1_entry *asn1_class_attr;
struct sc_asn1_entry *asn1_subclass_attr;
struct sc_asn1_entry *asn1_type_attr;

View File

@ -159,7 +159,7 @@ int sc_establish_context(struct sc_context **ctx_out)
for (i = 0; i < SC_MAX_READER_DRIVERS+1; i++)
ctx->reader_drivers[i] = NULL;
i = 0;
#if 1
#if 1 && defined(HAVE_LIBPCSCLITE)
ctx->reader_drivers[i++] = sc_get_pcsc_driver();
#endif
i = 0;

View File

@ -7,7 +7,7 @@ if HAVE_SSL
PROGRAMS_SSL = cryptoflex-tool pkcs15-init
endif
bin_PROGRAMS = opensc-tool opensc-explorer pkcs15-crypt pkcs15-tool \
bin_PROGRAMS = opensc-tool opensc-explorer pkcs15-tool pkcs15-crypt \
$(PROGRAMS_SSL)
opensc_tool_SOURCES = opensc-tool.c util.c

View File

@ -1087,9 +1087,11 @@ int add_object(struct sc_pkcs15_card *p15card,
int create_pkcs15()
{
#if 0
struct sc_pkcs15_card *p15card;
struct sc_file *file;
struct sc_path path;
struct sc_path path;
struct sc_pkcs15_object obj;
struct sc_pkcs15_cert_info cert;
struct sc_pkcs15_pin_info pin;
struct sc_pkcs15_prkey_info prkey;
@ -1223,6 +1225,7 @@ int create_pkcs15()
fprintf(stderr, "PKCS #15 structure creation failed: %s\n", sc_strerror(r));
return 1;
}
#endif
return 0;
}

View File

@ -73,14 +73,15 @@ struct sc_context *ctx = NULL;
struct sc_card *card = NULL;
struct sc_pkcs15_card *p15card = NULL;
char * get_pin(struct sc_pkcs15_pin_info *pinfo)
char * get_pin(struct sc_pkcs15_object *obj)
{
char buf[80];
char *pincode;
struct sc_pkcs15_pin_info *pinfo = obj->data;
if (opt_pincode != NULL)
return strdup(opt_pincode);
sprintf(buf, "Enter PIN [%s]: ", pinfo->com_attr.label);
sprintf(buf, "Enter PIN [%s]: ", obj->label);
while (1) {
pincode = getpass(buf);
if (strlen(pincode) == 0)
@ -192,8 +193,7 @@ int main(int argc, char * const argv[])
int do_decipher = 0;
int do_sign = 0;
int action_count = 0;
struct sc_pkcs15_prkey_info *key;
struct sc_pkcs15_pin_info *pin;
struct sc_pkcs15_object *key, *pin, *objs[32];
struct sc_pkcs15_id id;
char *pincode;
@ -280,17 +280,17 @@ int main(int argc, char * const argv[])
#endif
if (!quiet)
fprintf(stderr, "Trying to find a PKCS#15 compatible card...\n");
fprintf(stderr, "Trying to find a PKCS #15 compatible card...\n");
r = sc_pkcs15_bind(card, &p15card);
if (r) {
fprintf(stderr, "PKCS#15 initialization failed: %s\n", sc_strerror(r));
fprintf(stderr, "PKCS #15 initialization failed: %s\n", sc_strerror(r));
err = 1;
goto end;
}
if (!quiet)
fprintf(stderr, "Found %s!\n", p15card->label);
r = sc_pkcs15_enum_private_keys(p15card);
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY_RSA, objs, 32);
if (r <= 0) {
if (r == 0)
r = SC_ERROR_OBJECT_NOT_FOUND;
@ -308,8 +308,8 @@ int main(int argc, char * const argv[])
goto end;
}
} else
key = &p15card->prkey_info[0];
r = sc_pkcs15_find_pin_by_auth_id(p15card, &key->com_attr.auth_id, &pin);
key = objs[0];
r = sc_pkcs15_find_pin_by_auth_id(p15card, &key->auth_id, &pin);
if (r) {
fprintf(stderr, "Unable to find PIN code for private key: %s\n",
sc_strerror(r));
@ -321,7 +321,7 @@ int main(int argc, char * const argv[])
err = 5;
goto end;
}
r = sc_pkcs15_verify_pin(p15card, pin, (const u8 *) pincode, strlen(pincode));
r = sc_pkcs15_verify_pin(p15card, pin->data, (const u8 *) pincode, strlen(pincode));
if (r) {
fprintf(stderr, "PIN code verification failed: %s\n", sc_strerror(r));
err = 5;
@ -331,12 +331,12 @@ int main(int argc, char * const argv[])
if (!quiet)
fprintf(stderr, "PIN code correct.\n");
if (do_decipher) {
if ((err = decipher(key)))
if ((err = decipher(key->data)))
goto end;
action_count--;
}
if (do_sign) {
if ((err = sign(key)))
if ((err = sign(key->data)))
goto end;
action_count--;
}

View File

@ -74,20 +74,38 @@ struct sc_context *ctx = NULL;
struct sc_card *card = NULL;
struct sc_pkcs15_card *p15card = NULL;
void print_cert_info(const struct sc_pkcs15_object *obj)
{
int i;
struct sc_pkcs15_cert_info *cert = (struct sc_pkcs15_cert_info *) obj->data;
printf("X.509 Certificate [%s]\n", obj->label);
printf("\tFlags : %d\n", obj->flags);
printf("\tAuthority: %s\n", cert->authority ? "yes" : "no");
printf("\tPath : ");
for (i = 0; i < cert->path.len; i++)
printf("%02X", cert->path.value[i]);
printf("\n");
printf("\tID : ");
sc_pkcs15_print_id(&cert->id);
printf("\n");
}
int list_certificates(void)
{
int r, i;
struct sc_pkcs15_object *objs[32];
r = sc_pkcs15_enum_certificates(p15card);
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, objs, 32);
if (r < 0) {
fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r));
return 1;
}
if (!quiet)
printf("Card has %d certificate(s).\n\n", p15card->cert_count);
for (i = 0; i < p15card->cert_count; i++) {
struct sc_pkcs15_cert_info *cinfo = &p15card->cert_info[i];
sc_pkcs15_print_cert_info(cinfo);
printf("Card has %d certificate(s).\n\n", r);
for (i = 0; i < r; i++) {
print_cert_info(objs[i]);
printf("\n");
}
return 0;
@ -123,20 +141,21 @@ int print_pem_certificate(struct sc_pkcs15_cert *cert)
int read_certificate(void)
{
int r, i;
int r, i, count;
struct sc_pkcs15_id id;
struct sc_pkcs15_object *objs[32];
id.len = SC_PKCS15_MAX_ID_SIZE;
sc_pkcs15_hex_string_to_id(opt_cert, &id);
r = sc_pkcs15_enum_certificates(p15card);
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, objs, 32);
if (r < 0) {
fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r));
return 1;
}
for (i = 0; i < p15card->cert_count; i++) {
struct sc_pkcs15_cert_info *cinfo = &p15card->cert_info[i];
count = r;
for (i = 0; i < count; i++) {
struct sc_pkcs15_cert_info *cinfo = objs[i]->data;
struct sc_pkcs15_cert *cert;
if (sc_pkcs15_compare_id(&id, &cinfo->id) != 1)
@ -157,37 +176,131 @@ int read_certificate(void)
return 2;
}
void print_prkey_info(const struct sc_pkcs15_object *obj)
{
int i;
struct sc_pkcs15_prkey_info *prkey = (struct sc_pkcs15_prkey_info *) obj->data;
const char *usages[] = {
"encrypt", "decrypt", "sign", "signRecover",
"wrap", "unwrap", "verify", "verifyRecover",
"derive", "nonRepudiation"
};
const int usage_count = sizeof(usages)/sizeof(usages[0]);
const char *access_flags[] = {
"sensitive", "extract", "alwaysSensitive",
"neverExtract", "local"
};
const int af_count = sizeof(access_flags)/sizeof(access_flags[0]);
printf("Private RSA Key [%s]\n", obj->label);
printf("\tCom. Flags : %X\n", obj->flags);
printf("\tUsage : [0x%X]", prkey->usage);
for (i = 0; i < usage_count; i++)
if (prkey->usage & (1 << i)) {
printf(", %s", usages[i]);
}
printf("\n");
printf("\tAccess Flags: [0x%X]", prkey->access_flags);
for (i = 0; i < af_count; i++)
if (prkey->access_flags & (1 << i)) {
printf(", %s", access_flags[i]);
}
printf("\n");
printf("\tModLength : %d\n", prkey->modulus_length);
printf("\tKey ref : %d\n", prkey->key_reference);
printf("\tNative : %s\n", prkey->native ? "yes" : "no");
printf("\tPath : ");
for (i = 0; i < prkey->path.len; i++)
printf("%02X", prkey->path.value[i]);
printf("\n");
printf("\tAuth ID : ");
sc_pkcs15_print_id(&obj->auth_id);
printf("\n");
printf("\tID : ");
sc_pkcs15_print_id(&prkey->id);
printf("\n");
}
int list_private_keys(void)
{
int r, i;
struct sc_pkcs15_object *objs[32];
r = sc_pkcs15_enum_private_keys(p15card);
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY_RSA, objs, 32);
if (r < 0) {
fprintf(stderr, "Private key enumeration failed: %s\n", sc_strerror(r));
return 1;
}
if (!quiet)
printf("Card has %d private key(s).\n\n", p15card->prkey_count);
for (i = 0; i < p15card->prkey_count; i++) {
struct sc_pkcs15_prkey_info *pinfo = &p15card->prkey_info[i];
sc_pkcs15_print_prkey_info(pinfo);
printf("Card has %d private key(s).\n\n", r);
for (i = 0; i < r; i++) {
print_prkey_info(objs[i]);
printf("\n");
}
return 0;
}
void print_pubkey_info(const struct sc_pkcs15_object *obj)
{
int i;
const struct sc_pkcs15_pubkey_info *pubkey = (const struct sc_pkcs15_pubkey_info *) obj->data;
const char *usages[] = {
"encrypt", "decrypt", "sign", "signRecover",
"wrap", "unwrap", "verify", "verifyRecover",
"derive", "nonRepudiation"
};
const int usage_count = sizeof(usages)/sizeof(usages[0]);
const char *access_flags[] = {
"sensitive", "extract", "alwaysSensitive",
"neverExtract", "local"
};
const int af_count = sizeof(access_flags)/sizeof(access_flags[0]);
printf("Public RSA Key [%s]\n", obj->label);
printf("\tCom. Flags : %X\n", obj->flags);
printf("\tUsage : [0x%X]", pubkey->usage);
for (i = 0; i < usage_count; i++)
if (pubkey->usage & (1 << i)) {
printf(", %s", usages[i]);
}
printf("\n");
printf("\tAccess Flags: [0x%X]", pubkey->access_flags);
for (i = 0; i < af_count; i++)
if (pubkey->access_flags & (1 << i)) {
printf(", %s", access_flags[i]);
}
printf("\n");
printf("\tModLength : %d\n", pubkey->modulus_length);
printf("\tKey ref : %d\n", pubkey->key_reference);
printf("\tNative : %s\n", pubkey->native ? "yes" : "no");
printf("\tPath : ");
for (i = 0; i < pubkey->path.len; i++)
printf("%02X", pubkey->path.value[i]);
printf("\n");
printf("\tAuth ID : ");
sc_pkcs15_print_id(&obj->auth_id);
printf("\n");
printf("\tID : ");
sc_pkcs15_print_id(&pubkey->id);
printf("\n");
}
u8 * get_pin(const char *prompt, struct sc_pkcs15_pin_info **pin_out)
{
int r;
char buf[80];
char *pincode;
struct sc_pkcs15_pin_info *pinfo;
struct sc_pkcs15_object *objs[32], *obj;
struct sc_pkcs15_pin_info *pinfo = NULL;
if (pin_out != NULL)
pinfo = *pin_out;
if (pinfo == NULL && opt_pin_id == NULL) {
r = sc_pkcs15_enum_pins(p15card);
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32);
if (r < 0) {
fprintf(stderr, "PIN code enumeration failed: %s\n", sc_strerror(r));
return NULL;
@ -196,22 +309,24 @@ u8 * get_pin(const char *prompt, struct sc_pkcs15_pin_info **pin_out)
fprintf(stderr, "No PIN codes found.\n");
return NULL;
}
pinfo = &p15card->pin_info[0];
obj = objs[0];
pinfo = obj->data;
} else if (pinfo == NULL) {
struct sc_pkcs15_id pin_id;
sc_pkcs15_hex_string_to_id(opt_pin_id, &pin_id);
r = sc_pkcs15_find_pin_by_auth_id(p15card, &pin_id, &pinfo);
r = sc_pkcs15_find_pin_by_auth_id(p15card, &pin_id, &obj);
if (r) {
fprintf(stderr, "Unable to find PIN code: %s\n", sc_strerror(r));
return NULL;
}
pinfo = obj->data;
}
if (pin_out != NULL)
*pin_out = pinfo;
sprintf(buf, "%s [%s]: ", prompt, pinfo->com_attr.label);
sprintf(buf, "%s [%s]: ", prompt, obj->label);
while (1) {
pincode = getpass(buf);
if (strlen(pincode) == 0)
@ -228,20 +343,59 @@ u8 * get_pin(const char *prompt, struct sc_pkcs15_pin_info **pin_out)
}
}
void print_pin_info(const struct sc_pkcs15_object *obj)
{
const char *pin_flags[] = {
"case-sensitive", "local", "change-disabled",
"unblock-disabled", "initialized", "needs-padding",
"unblockingPin", "soPin", "disable_allowed",
"integrity-protected", "confidentiality-protected",
"exchangeRefData"
};
const struct sc_pkcs15_pin_info *pin = (const struct sc_pkcs15_pin_info *) obj->data;
const int pf_count = sizeof(pin_flags)/sizeof(pin_flags[0]);
char path[SC_MAX_PATH_SIZE * 2 + 1];
int i;
char *p;
p = path;
*p = 0;
for (i = 0; i < pin->path.len; i++) {
sprintf(p, "%02X", pin->path.value[i]);
p += 2;
}
printf("PIN [%s]\n", obj->label);
printf("\tCom. Flags: 0x%X\n", obj->flags);
printf("\tAuth ID : ");
sc_pkcs15_print_id(&pin->auth_id);
printf("\n");
printf("\tFlags : [0x%02X]", pin->flags);
for (i = 0; i < pf_count; i++)
if (pin->flags & (1 << i)) {
printf(", %s", pin_flags[i]);
}
printf("\n");
printf("\tLength : %d..%d\n", pin->min_length, pin->stored_length);
printf("\tPad char : 0x%02X\n", pin->pad_char);
printf("\tReference : %d\n", pin->reference);
printf("\tType : %d\n", pin->type);
printf("\tPath : %s\n", path);
}
int list_pins(void)
{
int r, i;
r = sc_pkcs15_enum_pins(p15card);
struct sc_pkcs15_object *objs[32];
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32);
if (r < 0) {
fprintf(stderr, "PIN code enumeration failed: %s\n", sc_strerror(r));
fprintf(stderr, "Private key enumeration failed: %s\n", sc_strerror(r));
return 1;
}
if (!quiet)
printf("Card has %d PIN code(s).\n\n", p15card->pin_count);
for (i = 0; i < p15card->pin_count; i++) {
struct sc_pkcs15_pin_info *pinfo = &p15card->pin_info[i];
sc_pkcs15_print_pin_info(pinfo);
printf("Card has %d PIN code(s).\n\n", r);
for (i = 0; i < r; i++) {
print_pin_info(objs[i]);
printf("\n");
}
return 0;
@ -332,8 +486,9 @@ int learn_card(void)
{
struct stat stbuf;
char dir[120];
int r, i;
int r, i, cert_count;
struct sc_pkcs15_object *certs[32];
r = sc_get_cache_dir(ctx, dir, sizeof(dir));
if (r) {
fprintf(stderr, "Unable to find cache directory: %s\n", sc_strerror(r));
@ -349,19 +504,20 @@ int learn_card(void)
}
}
printf("Using cache directory '%s'.\n", dir);
r = sc_pkcs15_enum_certificates(p15card);
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, certs, 32);
if (r < 0) {
fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r));
return 1;
}
r = sc_pkcs15_enum_private_keys(p15card);
cert_count = r;
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY_RSA, NULL, 0);
if (r < 0) {
fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r));
fprintf(stderr, "Private key enumeration failed: %s\n", sc_strerror(r));
return 1;
}
r = sc_pkcs15_enum_pins(p15card);
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, NULL, 0);
if (r < 0) {
fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r));
fprintf(stderr, "PIN code enumeration failed: %s\n", sc_strerror(r));
return 1;
}
for (i = 0; i < SC_PKCS15_DF_TYPE_COUNT; i++) {
@ -375,10 +531,10 @@ int learn_card(void)
}
}
printf("Caching %d certificate(s)...\n", r);
for (i = 0; i < p15card->cert_count; i++) {
struct sc_pkcs15_cert_info *cinfo = &p15card->cert_info[i];
for (i = 0; i < cert_count; i++) {
struct sc_pkcs15_cert_info *cinfo = certs[i]->data;
printf("[%s]\n", cinfo->com_attr.label);
printf("[%s]\n", certs[i]->label);
read_and_cache_file(&cinfo->path);
}
@ -458,6 +614,11 @@ int main(int argc, char * const argv[])
ctx->error_file = stderr;
ctx->debug_file = stdout;
ctx->debug = opt_debug;
if (ctx->reader_count == 0) {
fprintf(stderr, "No readers configured.\n");
err = 1;
goto end;
}
if (opt_reader >= ctx->reader_count || opt_reader < 0) {
fprintf(stderr, "Illegal reader number. Only %d reader(s) configured.\n", ctx->reader_count);
err = 1;
@ -465,7 +626,8 @@ int main(int argc, char * const argv[])
}
if (sc_detect_card_presence(ctx->reader[opt_reader], 0) != 1) {
fprintf(stderr, "Card not present.\n");
return 3;
err = 3;
goto end;
}
if (!quiet)
fprintf(stderr, "Connecting to card in reader %s...\n", ctx->reader[opt_reader]->name);