- 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:
parent
e256d97f65
commit
6b07ff64f6
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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--;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue