- 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 lib_LTLIBRARIES = libopensc.la
libopensc_la_SOURCES = asn1.c base64.c sec.c log.c sc.c card.c iso7816.c \ 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 \ dir.c pkcs15.c pkcs15-cert.c pkcs15-pin.c \
pkcs15-prkey.c pkcs15-sec.c pkcs15-cache.c \ pkcs15-prkey.c pkcs15-pubkey.c pkcs15-sec.c \
$(PCSC_SRC) \ pkcs15-cache.c $(PCSC_SRC) \
card-setcos.c card-miocos.c card-flex.c card-gpk.c \ card-setcos.c card-miocos.c card-flex.c card-gpk.c \
card-tcos.c card-emv.c card-default.c card-tcos.c card-emv.c card-default.c
libopensc_la_LDFLAGS = -version-info 0:6:0 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 depth)
{ {
int r; 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]; struct sc_asn1_entry asn1_c_attr[6], asn1_p15_obj[5];
size_t flags_len = sizeof(com_attr->flags); size_t flags_len = sizeof(p15_obj->flags);
size_t label_len = sizeof(com_attr->label); 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_com_obj_attr, asn1_c_attr);
sc_copy_asn1_entry(c_asn1_p15_obj, asn1_p15_obj); 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 + 0, p15_obj->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 + 1, &p15_obj->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 + 2, &p15_obj->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 + 3, &p15_obj->user_consent, NULL, 0);
/* FIXME: encode accessControlRules */ /* FIXME: encode accessControlRules */
sc_format_asn1_entry(asn1_c_attr + 4, NULL, NULL, 0); sc_format_asn1_entry(asn1_c_attr + 4, NULL, NULL, 0);
sc_format_asn1_entry(asn1_p15_obj + 0, asn1_c_attr, 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) u8 **buf, size_t *bufsize, int depth)
{ {
int r; 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]; struct sc_asn1_entry asn1_c_attr[6], asn1_p15_obj[5];
size_t flags_len; 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_com_obj_attr, asn1_c_attr);
sc_copy_asn1_entry(c_asn1_p15_obj, asn1_p15_obj); sc_copy_asn1_entry(c_asn1_p15_obj, asn1_p15_obj);
if (label_len != 0) if (label_len != 0)
sc_format_asn1_entry(asn1_c_attr + 0, (void *) com_attr->label, &label_len, 1); sc_format_asn1_entry(asn1_c_attr + 0, (void *) p15_obj->label, &label_len, 1);
if (com_attr->flags) { if (p15_obj->flags) {
flags_len = _sc_count_bit_string_size(&com_attr->flags, sizeof(com_attr->flags)); flags_len = _sc_count_bit_string_size(&p15_obj->flags, sizeof(p15_obj->flags));
sc_format_asn1_entry(asn1_c_attr + 1, (void *) &com_attr->flags, &flags_len, 1); sc_format_asn1_entry(asn1_c_attr + 1, (void *) &p15_obj->flags, &flags_len, 1);
} }
if (com_attr->auth_id.len) if (p15_obj->auth_id.len)
sc_format_asn1_entry(asn1_c_attr + 2, (void *) &com_attr->auth_id, NULL, 1); sc_format_asn1_entry(asn1_c_attr + 2, (void *) &p15_obj->auth_id, NULL, 1);
if (com_attr->user_consent) if (p15_obj->user_consent)
sc_format_asn1_entry(asn1_c_attr + 3, (void *) &com_attr->user_consent, NULL, 1); sc_format_asn1_entry(asn1_c_attr + 3, (void *) &p15_obj->user_consent, NULL, 1);
/* FIXME: decode accessControlRules */ /* FIXME: decode accessControlRules */
sc_format_asn1_entry(asn1_p15_obj + 0, asn1_c_attr, NULL, 1); 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); 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_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_class_attr;
struct sc_asn1_entry *asn1_subclass_attr; struct sc_asn1_entry *asn1_subclass_attr;
struct sc_asn1_entry *asn1_type_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_MODIFIABLE 0x00000002
#define SC_PKCS15_CO_FLAG_OBJECT_SEEN 0x80000000 /* for PKCS #11 module */ #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_CASE_SENSITIVE 0x0001
#define SC_PKCS15_PIN_FLAG_LOCAL 0x0002 #define SC_PKCS15_PIN_FLAG_LOCAL 0x0002
#define SC_PKCS15_PIN_FLAG_CHANGE_DISABLED 0x0004 #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 #define SC_PKCS15_PIN_TYPE_UTF8 2
struct sc_pkcs15_pin_info { struct sc_pkcs15_pin_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id auth_id; struct sc_pkcs15_id auth_id;
int reference; int reference;
int flags, type; int flags, type;
@ -100,11 +89,11 @@ struct sc_pkcs15_algorithm_info {
int algorithm, supported_operations; int algorithm, supported_operations;
}; };
struct sc_pkcs15_rsa_pubkey { struct sc_pkcs15_pubkey_rsa {
u8 *modulus; u8 *modulus;
int modulus_len; int modulus_len;
unsigned int exponent; unsigned int exponent;
u8 *data; /* DER encoded raw key */ u8 *data; /* DER encoded raw key */
int data_len; int data_len;
}; };
@ -113,15 +102,13 @@ struct sc_pkcs15_cert {
int version; int version;
unsigned long serial; unsigned long serial;
struct sc_pkcs15_rsa_pubkey key; struct sc_pkcs15_pubkey_rsa key;
u8 *data; /* DER encoded raw cert */ u8 *data; /* DER encoded raw cert */
int data_len; int data_len;
}; };
struct sc_pkcs15_cert_info { struct sc_pkcs15_cert_info {
struct sc_pkcs15_common_obj_attr com_attr; struct sc_pkcs15_id id; /* correlates to private key id */
struct sc_pkcs15_id id; /* correlates to private RSA key id */
int authority; /* boolean */ int authority; /* boolean */
/* identifiers [2] SEQUENCE OF CredentialIdentifier{{KeyIdentifiers}} */ /* identifiers [2] SEQUENCE OF CredentialIdentifier{{KeyIdentifiers}} */
struct sc_path path; struct sc_path path;
@ -145,8 +132,6 @@ struct sc_pkcs15_cert_info {
#define SC_PKCS15_PRKEY_ACCESS_LOCAL 0x10 #define SC_PKCS15_PRKEY_ACCESS_LOCAL 0x10
struct sc_pkcs15_prkey_info { struct sc_pkcs15_prkey_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id id; /* correlates to public certificate id */ struct sc_pkcs15_id id; /* correlates to public certificate id */
unsigned int usage, access_flags; unsigned int usage, access_flags;
int native, key_reference; int native, key_reference;
@ -155,19 +140,44 @@ struct sc_pkcs15_prkey_info {
struct sc_path path; struct sc_path path;
}; };
#define SC_PKCS15_TYPE_PRKEY_RSA 0x100 struct sc_pkcs15_pubkey_info {
#define SC_PKCS15_TYPE_PUBKEY_RSA 0x200 struct sc_pkcs15_id id; /* correlates to private key id */
#define SC_PKCS15_TYPE_CERT_X509 0x400 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_CERT_SPKI 0x402
#define SC_PKCS15_TYPE_DATA_OBJECT 0x500 #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 { struct sc_pkcs15_object {
int type; 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; void *data;
/* For linked list purposes */ struct sc_pkcs15_object *next; /* used only internally */
struct sc_pkcs15_object *next;
}; };
#define SC_PKCS15_PRKDF 0 #define SC_PKCS15_PRKDF 0
@ -187,6 +197,7 @@ struct sc_pkcs15_df {
struct sc_file *file[SC_PKCS15_MAX_DFS]; struct sc_file *file[SC_PKCS15_MAX_DFS];
struct sc_pkcs15_object *obj[SC_PKCS15_MAX_DFS]; struct sc_pkcs15_object *obj[SC_PKCS15_MAX_DFS];
int count, record_length, type; int count, record_length, type;
int enumerated;
}; };
#define SC_PKCS15_CARD_MAGIC 0x10203040 #define SC_PKCS15_CARD_MAGIC 0x10203040
@ -199,14 +210,6 @@ struct sc_pkcs15_card {
char *serial_number, *manufacturer_id; char *serial_number, *manufacturer_id;
unsigned long flags; unsigned long flags;
struct sc_pkcs15_algorithm_info alg_info[1]; 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_app;
struct sc_file *file_tokeninfo, *file_odf; struct sc_file *file_tokeninfo, *file_odf;
@ -223,7 +226,7 @@ struct sc_pkcs15_card {
#define SC_PKCS15_CARD_FLAG_EID_COMPLIANT 0x08 #define SC_PKCS15_CARD_FLAG_EID_COMPLIANT 0x08
/* sc_pkcs15_bind: Binds a card object to a PKCS #15 card object /* 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 * SC_ERROR_PKCS15_APP_NOT_FOUND, if the card hasn't got a
* valid PKCS #15 file structure. */ * valid PKCS #15 file structure. */
int sc_pkcs15_bind(struct sc_card *card, 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. */ * memory allocations done on the card object. */
int sc_pkcs15_unbind(struct sc_pkcs15_card *card); 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(); struct sc_pkcs15_card * sc_pkcs15_card_new();
void sc_pkcs15_card_free(struct sc_pkcs15_card *p15card); 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_card(const struct sc_pkcs15_card *card);
void sc_pkcs15_print_cert_info(const struct sc_pkcs15_cert_info *cert); 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, int sc_pkcs15_read_certificate(struct sc_pkcs15_card *card,
const struct sc_pkcs15_cert_info *info, const struct sc_pkcs15_cert_info *info,
struct sc_pkcs15_cert **cert); struct sc_pkcs15_cert **cert);
void sc_pkcs15_free_certificate(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, int sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id, 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 /* 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 * by <card>. Information about the file, such as the file ID, is read
* from <file>. <certs> has to be NULL-terminated. */ * 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); 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); 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, int sc_pkcs15_find_prkey_by_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id, 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); void sc_pkcs15_print_pin_info(const struct sc_pkcs15_pin_info *auth);
int sc_pkcs15_enum_pins(struct sc_pkcs15_card *card);
int sc_pkcs15_verify_pin(struct sc_pkcs15_card *card, int sc_pkcs15_verify_pin(struct sc_pkcs15_card *card,
struct sc_pkcs15_pin_info *pin, 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, int sc_pkcs15_change_pin(struct sc_pkcs15_card *card,
struct sc_pkcs15_pin_info *pin, struct sc_pkcs15_pin_info *pin,
const u8 *oldpincode, int oldpinlen, const u8 *oldpincode, size_t oldpinlen,
const u8 *newpincode, int newpinlen); const u8 *newpincode, size_t newpinlen);
int sc_pkcs15_find_pin_by_auth_id(struct sc_pkcs15_card *card, int sc_pkcs15_find_pin_by_auth_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id, 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, int sc_pkcs15_encode_dir(struct sc_context *ctx,
struct sc_pkcs15_card *card, 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, int sc_pkcs15_encode_prkdf_entry(struct sc_context *ctx,
const struct sc_pkcs15_object *obj, u8 **buf, const struct sc_pkcs15_object *obj, u8 **buf,
size_t *bufsize); 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, int sc_pkcs15_encode_aodf_entry(struct sc_context *ctx,
const struct sc_pkcs15_object *obj, u8 **buf, const struct sc_pkcs15_object *obj, u8 **buf,
size_t *bufsize); size_t *bufsize);

View File

@ -29,9 +29,9 @@
#include <unistd.h> #include <unistd.h>
#include <assert.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 }, { "modulus", SC_ASN1_OCTET_STRING, ASN1_INTEGER, SC_ASN1_ALLOC, &key->modulus, &key->modulus_len },
{ "publicExponent", SC_ASN1_INTEGER, ASN1_INTEGER, 0, &key->exponent }, { "publicExponent", SC_ASN1_INTEGER, ASN1_INTEGER, 0, &key->exponent },
{ NULL } { 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"); error(ctx, "RSA public key not found\n");
return SC_ERROR_INVALID_ASN1_OBJECT; 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"); SC_TEST_RET(ctx, r, "ASN.1 parsing failed");
return 0; 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) static int parse_x509_cert(struct sc_context *ctx, const u8 *buf, size_t buflen, struct sc_pkcs15_cert *cert)
{ {
int r; 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; struct asn1_algorithm_id pk_alg, sig_alg;
u8 *pk = NULL; u8 *pk = NULL;
size_t pklen = 0; 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 = pk;
key->data_len = pklen; key->data_len = pklen;
/* FIXME: ignore the object id for now, and presume it's RSA */ /* 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) { if (r) {
free(key->data); free(key->data);
return SC_ERROR_INVALID_ASN1_OBJECT; 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], struct sc_asn1_entry asn1_cred_ident[3], asn1_com_cert_attr[4],
asn1_x509_cert_attr[2], asn1_type_cert_attr[2], asn1_x509_cert_attr[2], asn1_type_cert_attr[2],
asn1_cert[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 }; asn1_type_cert_attr };
u8 id_value[128]; u8 id_value[128];
int id_type, id_value_len = sizeof(id_value); 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); SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY);
memcpy(obj->data, &info, sizeof(info)); 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; return 0;
} }
@ -272,8 +266,9 @@ int sc_pkcs15_encode_cdf_entry(struct sc_context *ctx,
asn1_cert[2]; asn1_cert[2];
struct sc_pkcs15_cert_info *infop = struct sc_pkcs15_cert_info *infop =
(struct sc_pkcs15_cert_info *) obj->data; (struct sc_pkcs15_cert_info *) obj->data;
const struct sc_asn1_pkcs15_object cert_obj = { &infop->com_attr, asn1_com_cert_attr, NULL, const struct sc_asn1_pkcs15_object cert_obj = { (struct sc_pkcs15_object *) obj,
asn1_type_cert_attr }; asn1_com_cert_attr, NULL,
asn1_type_cert_attr };
int r; int r;
sc_copy_asn1_entry(c_asn1_cred_ident, asn1_cred_ident); 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; 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) void sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert)
{ {
assert(cert != NULL); assert(cert != NULL);
@ -348,22 +298,3 @@ void sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert)
free(cert->data); free(cert->data);
free(cert); 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; 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_com_ao_attr[2], asn1_pin_attr[10], asn1_type_pin_attr[2];
struct sc_asn1_entry asn1_pin[2]; struct sc_asn1_entry asn1_pin[2];
struct sc_asn1_pkcs15_object pin_obj = { &info.com_attr, asn1_com_ao_attr, NULL, struct sc_asn1_pkcs15_object pin_obj = { obj, asn1_com_ao_attr, NULL, asn1_type_pin_attr };
asn1_type_pin_attr };
sc_copy_asn1_entry(c_asn1_pin, asn1_pin); 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_type_pin_attr, asn1_type_pin_attr);
sc_copy_asn1_entry(c_asn1_pin_attr, asn1_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); SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY);
memcpy(obj->data, &info, sizeof(info)); 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; 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_asn1_entry asn1_pin[2];
struct sc_pkcs15_pin_info *pin = struct sc_pkcs15_pin_info *pin =
(struct sc_pkcs15_pin_info *) obj->data; (struct sc_pkcs15_pin_info *) obj->data;
struct sc_asn1_pkcs15_object pin_obj = { &pin->com_attr, asn1_com_ao_attr, NULL, struct sc_asn1_pkcs15_object pin_obj = { (struct sc_pkcs15_object *) obj,
asn1_type_pin_attr }; asn1_com_ao_attr, NULL,
asn1_type_pin_attr };
int r; int r;
int flags_len = sizeof(pin->flags); int flags_len = sizeof(pin->flags);
int padchar_len = 1; int padchar_len = 1;
@ -149,85 +143,9 @@ int sc_pkcs15_encode_aodf_entry(struct sc_context *ctx,
return r; 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, int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card,
struct sc_pkcs15_pin_info *pin, struct sc_pkcs15_pin_info *pin,
const u8 *pincode, int pinlen) const u8 *pincode, size_t pinlen)
{ {
int r; int r;
struct sc_card *card; 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, int sc_pkcs15_change_pin(struct sc_pkcs15_card *p15card,
struct sc_pkcs15_pin_info *pin, struct sc_pkcs15_pin_info *pin,
const u8 *oldpin, int oldpinlen, const u8 *oldpin, size_t oldpinlen,
const u8 *newpin, int newpinlen) const u8 *newpin, size_t newpinlen)
{ {
int r; int r;
struct sc_card *card; struct sc_card *card;
@ -293,22 +211,3 @@ int sc_pkcs15_change_pin(struct sc_pkcs15_card *p15card,
sc_unlock(card); sc_unlock(card);
return r; 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 <stdio.h>
#include <assert.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[] = { static const struct sc_asn1_entry c_asn1_com_key_attr[] = {
{ "iD", SC_ASN1_PKCS15_ID, ASN1_OCTET_STRING, 0, NULL }, { "iD", SC_ASN1_PKCS15_ID, ASN1_OCTET_STRING, 0, NULL },
{ "usage", SC_ASN1_BIT_STRING, ASN1_BIT_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_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_rsakey_attr[4], asn1_type_attr[2];
struct sc_asn1_entry asn1_prkey[2]; struct sc_asn1_entry asn1_prkey[2];
struct sc_asn1_pkcs15_object prkey_obj = { &info.com_attr, asn1_com_key_attr, struct sc_asn1_pkcs15_object prkey_obj = { obj, asn1_com_key_attr,
asn1_com_prkey_attr, asn1_type_attr }; asn1_com_prkey_attr, asn1_type_attr };
sc_copy_asn1_entry(c_asn1_prkey, asn1_prkey); sc_copy_asn1_entry(c_asn1_prkey, asn1_prkey);
sc_copy_asn1_entry(c_asn1_type_attr, asn1_type_attr); 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); SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY);
memcpy(obj->data, &info, sizeof(info)); 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; return 0;
} }
int sc_pkcs15_encode_prkdf_entry(struct sc_context *ctx, 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_asn1_entry asn1_prkey[2];
struct sc_pkcs15_prkey_info *prkey = struct sc_pkcs15_prkey_info *prkey =
(struct sc_pkcs15_prkey_info *) obj->data; (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 }; asn1_com_prkey_attr, asn1_type_attr };
int r; int r;
int af_len, usage_len; int af_len, usage_len;
@ -201,53 +152,3 @@ int sc_pkcs15_encode_prkdf_entry(struct sc_context *ctx,
return r; 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[] = { static const struct sc_asn1_entry c_asn1_odf[] = {
{ "privateKeys", SC_ASN1_STRUCT, SC_ASN1_CTX | 0 | SC_ASN1_CONS, 0, NULL }, { "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 }, { "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 }, { "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 }, { "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 }, { "authObjects", SC_ASN1_STRUCT, SC_ASN1_CTX | 8 | SC_ASN1_CONS, 0, NULL },
{ NULL } { NULL }
@ -314,8 +317,11 @@ static const struct sc_asn1_entry c_asn1_odf[] = {
static const int odf_indexes[] = { static const int odf_indexes[] = {
SC_PKCS15_PRKDF, SC_PKCS15_PRKDF,
SC_PKCS15_PUKDF,
SC_PKCS15_PUKDF_TRUSTED,
SC_PKCS15_CDF, SC_PKCS15_CDF,
SC_PKCS15_CDF_TRUSTED, SC_PKCS15_CDF_TRUSTED,
SC_PKCS15_CDF_USEFUL,
SC_PKCS15_DODF, SC_PKCS15_DODF,
SC_PKCS15_AODF, 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 }, { "path", SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_SEQUENCE, 0, &path },
{ NULL } { NULL }
}; };
struct sc_asn1_entry asn1_odf[6]; struct sc_asn1_entry asn1_odf[9];
sc_copy_asn1_entry(c_asn1_odf, asn1_odf); sc_copy_asn1_entry(c_asn1_odf, asn1_odf);
for (i = 0; asn1_odf[i].name != NULL; i++) for (i = 0; asn1_odf[i].name != NULL; i++)
@ -593,6 +599,148 @@ int sc_pkcs15_unbind(struct sc_pkcs15_card *p15card)
return 0; 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 sc_pkcs15_add_object(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df,
int file_nr, struct sc_pkcs15_object *obj) 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: case SC_PKCS15_PRKDF:
func = sc_pkcs15_encode_prkdf_entry; func = sc_pkcs15_encode_prkdf_entry;
break; 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:
case SC_PKCS15_CDF_TRUSTED: case SC_PKCS15_CDF_TRUSTED:
case SC_PKCS15_CDF_USEFUL: case SC_PKCS15_CDF_USEFUL:
@ -854,18 +1006,23 @@ int sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card,
struct sc_file *file = NULL; struct sc_file *file = NULL;
size_t file_size; 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); r = sc_select_file(p15card->card, &path, &file);
if (r) { if (r) {
sc_perror(ctx, r, "sc_select_file() failed"); sc_perror(ctx, r, "sc_select_file() failed");
sc_unlock(p15card->card);
return r; return r;
} }
file_size = file->size; file_size = file->size;
sc_file_free(file); sc_file_free(file);
if (file_size > sizeof(buf)) { if (file_size > sizeof(buf)) {
error(ctx, "Buffer too small to handle DF contents\n"); error(ctx, "Buffer too small to handle DF contents\n");
sc_unlock(p15card->card);
return SC_ERROR_INTERNAL; return SC_ERROR_INTERNAL;
} }
r = sc_read_binary(p15card->card, 0, buf, file_size, 0); r = sc_read_binary(p15card->card, 0, buf, file_size, 0);
sc_unlock(p15card->card);
if (r < 0) if (r < 0)
return r; return r;
bufsize = file_size; 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_MODIFIABLE 0x00000002
#define SC_PKCS15_CO_FLAG_OBJECT_SEEN 0x80000000 /* for PKCS #11 module */ #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_CASE_SENSITIVE 0x0001
#define SC_PKCS15_PIN_FLAG_LOCAL 0x0002 #define SC_PKCS15_PIN_FLAG_LOCAL 0x0002
#define SC_PKCS15_PIN_FLAG_CHANGE_DISABLED 0x0004 #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 #define SC_PKCS15_PIN_TYPE_UTF8 2
struct sc_pkcs15_pin_info { struct sc_pkcs15_pin_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id auth_id; struct sc_pkcs15_id auth_id;
int reference; int reference;
int flags, type; int flags, type;
@ -100,11 +89,11 @@ struct sc_pkcs15_algorithm_info {
int algorithm, supported_operations; int algorithm, supported_operations;
}; };
struct sc_pkcs15_rsa_pubkey { struct sc_pkcs15_pubkey_rsa {
u8 *modulus; u8 *modulus;
int modulus_len; int modulus_len;
unsigned int exponent; unsigned int exponent;
u8 *data; /* DER encoded raw key */ u8 *data; /* DER encoded raw key */
int data_len; int data_len;
}; };
@ -113,15 +102,13 @@ struct sc_pkcs15_cert {
int version; int version;
unsigned long serial; unsigned long serial;
struct sc_pkcs15_rsa_pubkey key; struct sc_pkcs15_pubkey_rsa key;
u8 *data; /* DER encoded raw cert */ u8 *data; /* DER encoded raw cert */
int data_len; int data_len;
}; };
struct sc_pkcs15_cert_info { struct sc_pkcs15_cert_info {
struct sc_pkcs15_common_obj_attr com_attr; struct sc_pkcs15_id id; /* correlates to private key id */
struct sc_pkcs15_id id; /* correlates to private RSA key id */
int authority; /* boolean */ int authority; /* boolean */
/* identifiers [2] SEQUENCE OF CredentialIdentifier{{KeyIdentifiers}} */ /* identifiers [2] SEQUENCE OF CredentialIdentifier{{KeyIdentifiers}} */
struct sc_path path; struct sc_path path;
@ -145,8 +132,6 @@ struct sc_pkcs15_cert_info {
#define SC_PKCS15_PRKEY_ACCESS_LOCAL 0x10 #define SC_PKCS15_PRKEY_ACCESS_LOCAL 0x10
struct sc_pkcs15_prkey_info { struct sc_pkcs15_prkey_info {
struct sc_pkcs15_common_obj_attr com_attr;
struct sc_pkcs15_id id; /* correlates to public certificate id */ struct sc_pkcs15_id id; /* correlates to public certificate id */
unsigned int usage, access_flags; unsigned int usage, access_flags;
int native, key_reference; int native, key_reference;
@ -155,19 +140,44 @@ struct sc_pkcs15_prkey_info {
struct sc_path path; struct sc_path path;
}; };
#define SC_PKCS15_TYPE_PRKEY_RSA 0x100 struct sc_pkcs15_pubkey_info {
#define SC_PKCS15_TYPE_PUBKEY_RSA 0x200 struct sc_pkcs15_id id; /* correlates to private key id */
#define SC_PKCS15_TYPE_CERT_X509 0x400 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_CERT_SPKI 0x402
#define SC_PKCS15_TYPE_DATA_OBJECT 0x500 #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 { struct sc_pkcs15_object {
int type; 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; void *data;
/* For linked list purposes */ struct sc_pkcs15_object *next; /* used only internally */
struct sc_pkcs15_object *next;
}; };
#define SC_PKCS15_PRKDF 0 #define SC_PKCS15_PRKDF 0
@ -187,6 +197,7 @@ struct sc_pkcs15_df {
struct sc_file *file[SC_PKCS15_MAX_DFS]; struct sc_file *file[SC_PKCS15_MAX_DFS];
struct sc_pkcs15_object *obj[SC_PKCS15_MAX_DFS]; struct sc_pkcs15_object *obj[SC_PKCS15_MAX_DFS];
int count, record_length, type; int count, record_length, type;
int enumerated;
}; };
#define SC_PKCS15_CARD_MAGIC 0x10203040 #define SC_PKCS15_CARD_MAGIC 0x10203040
@ -199,14 +210,6 @@ struct sc_pkcs15_card {
char *serial_number, *manufacturer_id; char *serial_number, *manufacturer_id;
unsigned long flags; unsigned long flags;
struct sc_pkcs15_algorithm_info alg_info[1]; 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_app;
struct sc_file *file_tokeninfo, *file_odf; struct sc_file *file_tokeninfo, *file_odf;
@ -223,7 +226,7 @@ struct sc_pkcs15_card {
#define SC_PKCS15_CARD_FLAG_EID_COMPLIANT 0x08 #define SC_PKCS15_CARD_FLAG_EID_COMPLIANT 0x08
/* sc_pkcs15_bind: Binds a card object to a PKCS #15 card object /* 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 * SC_ERROR_PKCS15_APP_NOT_FOUND, if the card hasn't got a
* valid PKCS #15 file structure. */ * valid PKCS #15 file structure. */
int sc_pkcs15_bind(struct sc_card *card, 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. */ * memory allocations done on the card object. */
int sc_pkcs15_unbind(struct sc_pkcs15_card *card); 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(); struct sc_pkcs15_card * sc_pkcs15_card_new();
void sc_pkcs15_card_free(struct sc_pkcs15_card *p15card); 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_card(const struct sc_pkcs15_card *card);
void sc_pkcs15_print_cert_info(const struct sc_pkcs15_cert_info *cert); 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, int sc_pkcs15_read_certificate(struct sc_pkcs15_card *card,
const struct sc_pkcs15_cert_info *info, const struct sc_pkcs15_cert_info *info,
struct sc_pkcs15_cert **cert); struct sc_pkcs15_cert **cert);
void sc_pkcs15_free_certificate(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, int sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id, 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 /* 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 * by <card>. Information about the file, such as the file ID, is read
* from <file>. <certs> has to be NULL-terminated. */ * 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); 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); 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, int sc_pkcs15_find_prkey_by_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id, 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); void sc_pkcs15_print_pin_info(const struct sc_pkcs15_pin_info *auth);
int sc_pkcs15_enum_pins(struct sc_pkcs15_card *card);
int sc_pkcs15_verify_pin(struct sc_pkcs15_card *card, int sc_pkcs15_verify_pin(struct sc_pkcs15_card *card,
struct sc_pkcs15_pin_info *pin, 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, int sc_pkcs15_change_pin(struct sc_pkcs15_card *card,
struct sc_pkcs15_pin_info *pin, struct sc_pkcs15_pin_info *pin,
const u8 *oldpincode, int oldpinlen, const u8 *oldpincode, size_t oldpinlen,
const u8 *newpincode, int newpinlen); const u8 *newpincode, size_t newpinlen);
int sc_pkcs15_find_pin_by_auth_id(struct sc_pkcs15_card *card, int sc_pkcs15_find_pin_by_auth_id(struct sc_pkcs15_card *card,
const struct sc_pkcs15_id *id, 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, int sc_pkcs15_encode_dir(struct sc_context *ctx,
struct sc_pkcs15_card *card, 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, int sc_pkcs15_encode_prkdf_entry(struct sc_context *ctx,
const struct sc_pkcs15_object *obj, u8 **buf, const struct sc_pkcs15_object *obj, u8 **buf,
size_t *bufsize); 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, int sc_pkcs15_encode_aodf_entry(struct sc_context *ctx,
const struct sc_pkcs15_object *obj, u8 **buf, const struct sc_pkcs15_object *obj, u8 **buf,
size_t *bufsize); size_t *bufsize);

View File

@ -34,7 +34,7 @@ struct sc_asn1_entry {
}; };
struct sc_asn1_pkcs15_object { 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_class_attr;
struct sc_asn1_entry *asn1_subclass_attr; struct sc_asn1_entry *asn1_subclass_attr;
struct sc_asn1_entry *asn1_type_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++) for (i = 0; i < SC_MAX_READER_DRIVERS+1; i++)
ctx->reader_drivers[i] = NULL; ctx->reader_drivers[i] = NULL;
i = 0; i = 0;
#if 1 #if 1 && defined(HAVE_LIBPCSCLITE)
ctx->reader_drivers[i++] = sc_get_pcsc_driver(); ctx->reader_drivers[i++] = sc_get_pcsc_driver();
#endif #endif
i = 0; i = 0;

View File

@ -7,7 +7,7 @@ if HAVE_SSL
PROGRAMS_SSL = cryptoflex-tool pkcs15-init PROGRAMS_SSL = cryptoflex-tool pkcs15-init
endif endif
bin_PROGRAMS = opensc-tool opensc-explorer pkcs15-crypt pkcs15-tool \ bin_PROGRAMS = opensc-tool opensc-explorer pkcs15-tool pkcs15-crypt \
$(PROGRAMS_SSL) $(PROGRAMS_SSL)
opensc_tool_SOURCES = opensc-tool.c util.c 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() int create_pkcs15()
{ {
#if 0
struct sc_pkcs15_card *p15card; struct sc_pkcs15_card *p15card;
struct sc_file *file; 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_cert_info cert;
struct sc_pkcs15_pin_info pin; struct sc_pkcs15_pin_info pin;
struct sc_pkcs15_prkey_info prkey; 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)); fprintf(stderr, "PKCS #15 structure creation failed: %s\n", sc_strerror(r));
return 1; return 1;
} }
#endif
return 0; return 0;
} }

View File

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

View File

@ -74,20 +74,38 @@ struct sc_context *ctx = NULL;
struct sc_card *card = NULL; struct sc_card *card = NULL;
struct sc_pkcs15_card *p15card = 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 list_certificates(void)
{ {
int r, i; 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) { if (r < 0) {
fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r)); fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r));
return 1; return 1;
} }
if (!quiet) if (!quiet)
printf("Card has %d certificate(s).\n\n", p15card->cert_count); printf("Card has %d certificate(s).\n\n", r);
for (i = 0; i < p15card->cert_count; i++) { for (i = 0; i < r; i++) {
struct sc_pkcs15_cert_info *cinfo = &p15card->cert_info[i]; print_cert_info(objs[i]);
sc_pkcs15_print_cert_info(cinfo);
printf("\n"); printf("\n");
} }
return 0; return 0;
@ -123,20 +141,21 @@ int print_pem_certificate(struct sc_pkcs15_cert *cert)
int read_certificate(void) int read_certificate(void)
{ {
int r, i; int r, i, count;
struct sc_pkcs15_id id; struct sc_pkcs15_id id;
struct sc_pkcs15_object *objs[32];
id.len = SC_PKCS15_MAX_ID_SIZE; id.len = SC_PKCS15_MAX_ID_SIZE;
sc_pkcs15_hex_string_to_id(opt_cert, &id); 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) { if (r < 0) {
fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r)); fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r));
return 1; return 1;
} }
count = r;
for (i = 0; i < p15card->cert_count; i++) { for (i = 0; i < count; i++) {
struct sc_pkcs15_cert_info *cinfo = &p15card->cert_info[i]; struct sc_pkcs15_cert_info *cinfo = objs[i]->data;
struct sc_pkcs15_cert *cert; struct sc_pkcs15_cert *cert;
if (sc_pkcs15_compare_id(&id, &cinfo->id) != 1) if (sc_pkcs15_compare_id(&id, &cinfo->id) != 1)
@ -157,37 +176,131 @@ int read_certificate(void)
return 2; 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 list_private_keys(void)
{ {
int r, i; 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) { if (r < 0) {
fprintf(stderr, "Private key enumeration failed: %s\n", sc_strerror(r)); fprintf(stderr, "Private key enumeration failed: %s\n", sc_strerror(r));
return 1; return 1;
} }
if (!quiet) if (!quiet)
printf("Card has %d private key(s).\n\n", p15card->prkey_count); printf("Card has %d private key(s).\n\n", r);
for (i = 0; i < p15card->prkey_count; i++) { for (i = 0; i < r; i++) {
struct sc_pkcs15_prkey_info *pinfo = &p15card->prkey_info[i]; print_prkey_info(objs[i]);
sc_pkcs15_print_prkey_info(pinfo);
printf("\n"); printf("\n");
} }
return 0; 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) u8 * get_pin(const char *prompt, struct sc_pkcs15_pin_info **pin_out)
{ {
int r; int r;
char buf[80]; char buf[80];
char *pincode; 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) if (pin_out != NULL)
pinfo = *pin_out; pinfo = *pin_out;
if (pinfo == NULL && opt_pin_id == NULL) { 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) { if (r < 0) {
fprintf(stderr, "PIN code enumeration failed: %s\n", sc_strerror(r)); fprintf(stderr, "PIN code enumeration failed: %s\n", sc_strerror(r));
return NULL; 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"); fprintf(stderr, "No PIN codes found.\n");
return NULL; return NULL;
} }
pinfo = &p15card->pin_info[0]; obj = objs[0];
pinfo = obj->data;
} else if (pinfo == NULL) { } else if (pinfo == NULL) {
struct sc_pkcs15_id pin_id; struct sc_pkcs15_id pin_id;
sc_pkcs15_hex_string_to_id(opt_pin_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) { if (r) {
fprintf(stderr, "Unable to find PIN code: %s\n", sc_strerror(r)); fprintf(stderr, "Unable to find PIN code: %s\n", sc_strerror(r));
return NULL; return NULL;
} }
pinfo = obj->data;
} }
if (pin_out != NULL) if (pin_out != NULL)
*pin_out = pinfo; *pin_out = pinfo;
sprintf(buf, "%s [%s]: ", prompt, pinfo->com_attr.label); sprintf(buf, "%s [%s]: ", prompt, obj->label);
while (1) { while (1) {
pincode = getpass(buf); pincode = getpass(buf);
if (strlen(pincode) == 0) 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 list_pins(void)
{ {
int r, i; int r, i;
struct sc_pkcs15_object *objs[32];
r = sc_pkcs15_enum_pins(p15card);
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32);
if (r < 0) { 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; return 1;
} }
if (!quiet) if (!quiet)
printf("Card has %d PIN code(s).\n\n", p15card->pin_count); printf("Card has %d PIN code(s).\n\n", r);
for (i = 0; i < p15card->pin_count; i++) { for (i = 0; i < r; i++) {
struct sc_pkcs15_pin_info *pinfo = &p15card->pin_info[i]; print_pin_info(objs[i]);
sc_pkcs15_print_pin_info(pinfo);
printf("\n"); printf("\n");
} }
return 0; return 0;
@ -332,8 +486,9 @@ int learn_card(void)
{ {
struct stat stbuf; struct stat stbuf;
char dir[120]; 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)); r = sc_get_cache_dir(ctx, dir, sizeof(dir));
if (r) { if (r) {
fprintf(stderr, "Unable to find cache directory: %s\n", sc_strerror(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); 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) { if (r < 0) {
fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r)); fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r));
return 1; 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) { 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; return 1;
} }
r = sc_pkcs15_enum_pins(p15card); r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, NULL, 0);
if (r < 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; return 1;
} }
for (i = 0; i < SC_PKCS15_DF_TYPE_COUNT; i++) { 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); printf("Caching %d certificate(s)...\n", r);
for (i = 0; i < p15card->cert_count; i++) { for (i = 0; i < cert_count; i++) {
struct sc_pkcs15_cert_info *cinfo = &p15card->cert_info[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); read_and_cache_file(&cinfo->path);
} }
@ -458,6 +614,11 @@ int main(int argc, char * const argv[])
ctx->error_file = stderr; ctx->error_file = stderr;
ctx->debug_file = stdout; ctx->debug_file = stdout;
ctx->debug = opt_debug; 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) { if (opt_reader >= ctx->reader_count || opt_reader < 0) {
fprintf(stderr, "Illegal reader number. Only %d reader(s) configured.\n", ctx->reader_count); fprintf(stderr, "Illegal reader number. Only %d reader(s) configured.\n", ctx->reader_count);
err = 1; err = 1;
@ -465,7 +626,8 @@ int main(int argc, char * const argv[])
} }
if (sc_detect_card_presence(ctx->reader[opt_reader], 0) != 1) { if (sc_detect_card_presence(ctx->reader[opt_reader], 0) != 1) {
fprintf(stderr, "Card not present.\n"); fprintf(stderr, "Card not present.\n");
return 3; err = 3;
goto end;
} }
if (!quiet) if (!quiet)
fprintf(stderr, "Connecting to card in reader %s...\n", ctx->reader[opt_reader]->name); fprintf(stderr, "Connecting to card in reader %s...\n", ctx->reader[opt_reader]->name);