diff --git a/src/engine_pkcs11.c b/src/engine_pkcs11.c
index c97d08bbc9abbb91e75c98495e5370c77349b12c..41d24ce3c28cc6a777e2efb3ff2399ef9177c9fe 100644 (file)
--- a/src/engine_pkcs11.c
+++ b/src/engine_pkcs11.c
/* Maximum size of a token object */
#define MAX_OBJECT_SIZE 5000
+struct cert_ctrl_params {
+ int slot_nr;
+ unsigned char *cert_id;
+ size_t cert_id_len;
+ char *cert_label;
+ X509 *cert;
+};
+
static int do_login(PKCS11_SLOT *slot);
static int pkcs11_store_cert
(
#define MAX_VALUE_LEN 200
-/* prototype for OpenSSL ENGINE_load_cert */
-/* used by load_cert_ctrl via ENGINE_ctrl for now */
-
-static X509 *pkcs11_load_cert(ENGINE * e, const char *s_slot_cert_id)
+static X509 *pkcs11_load_cert
+(
+ ENGINE * e,
+ int slot_nr,
+ unsigned char *cert_id,
+ size_t cert_id_len,
+ char *cert_label
+)
{
PKCS11_SLOT *slot_list, *slot;
PKCS11_SLOT *found_slot = NULL;
PKCS11_CERT *certs, *selected_cert = NULL;
X509 *x509;
unsigned int slot_count, cert_count, n, m;
- unsigned char cert_id[MAX_VALUE_LEN / 2];
- size_t cert_id_len = sizeof(cert_id);
- char *cert_label = NULL;
- int slot_nr = -1;
char flags[64];
- if (s_slot_cert_id && *s_slot_cert_id) {
- n = parse_slot_id_string(s_slot_cert_id, &slot_nr,
- cert_id, &cert_id_len, &cert_label);
- if (!n) {
- fprintf(stderr,
- "supported formats: <id>, <slot>:<id>, id_<id>, slot_<slot>-id_<id>, label_<label>, slot_<slot>-label_<label>\n");
- fprintf(stderr,
- "where <slot> is the slot number as normal integer,\n");
- fprintf(stderr,
- "and <id> is the id number as hex string.\n");
- fprintf(stderr,
- "and <label> is the textual key label string.\n");
- return NULL;
- }
- if (verbose) {
- fprintf(stderr, "Looking in slot %d for certificate: ",
- slot_nr);
- if (cert_label == NULL) {
- for (n = 0; n < cert_id_len; n++)
- fprintf(stderr, "%02x", cert_id[n]);
- fprintf(stderr, "\n");
- } else
- fprintf(stderr, "label: %s\n", cert_label);
-
- }
+ if (ctx == NULL) {
+ pkcs11_init(e);
}
if (PKCS11_enumerate_slots(ctx, &slot_list, &slot_count) < 0)
fprintf(stderr, "Found %u slot%s\n", slot_count,
(slot_count <= 1) ? "" : "s");
}
+
for (n = 0; n < slot_count; n++) {
slot = slot_list + n;
flags[0] = '\0';
}
}
- if (slot_nr == -1) {
- if (!(slot = PKCS11_find_token(ctx, slot_list, slot_count)))
- fail("didn't find any tokens\n");
- } else if (found_slot) {
+ if (found_slot) {
slot = found_slot;
} else {
- fprintf(stderr, "Invalid slot number: %d\n", slot_nr);
- PKCS11_release_all_slots(ctx, slot_list, slot_count);
- return NULL;
+ fprintf(stderr, "Invalid slot number: %d\n", (int)slot_nr);
+ goto err_out;
}
+
tok = slot->token;
if (tok == NULL) {
fprintf(stderr, "Found empty token; \n");
- PKCS11_release_all_slots(ctx, slot_list, slot_count);
- return NULL;
+ goto err_out;
}
if (verbose) {
fprintf(stderr, "Found token: %s\n", slot->token->label);
}
+ if ((tok->loginRequired) && (do_login(slot))) {
+ fprintf(stderr, "failed to login\n");
+ goto err_out;
+ }
+
if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) {
fprintf(stderr, "unable to enumerate certificates\n");
- PKCS11_release_all_slots(ctx, slot_list, slot_count);
- return NULL;
+ goto err_out;
}
if (verbose) {
fprintf(stderr, "Found %u cert%s:\n", cert_count,
(cert_count <= 1) ? "" : "s");
}
- if ((s_slot_cert_id && *s_slot_cert_id) && (cert_id_len != 0)) {
+
+ /* Find the matching cert */
+ if (cert_id_len || cert_label) {
for (n = 0; n < cert_count; n++) {
PKCS11_CERT *k = certs + n;
- if (cert_id_len != 0 && k->id_len == cert_id_len &&
- memcmp(k->id, cert_id, cert_id_len) == 0) {
- selected_cert = k;
+ if (cert_label == NULL) {
+ if (cert_id_len != 0 && k->id_len == cert_id_len &&
+ memcmp(k->id, cert_id, cert_id_len) == 0) {
+ selected_cert = k;
+ }
+ } else {
+ if (strcmp(k->label, cert_label) == 0) {
+ selected_cert = k;
+ }
}
}
} else {
if (selected_cert == NULL) {
fprintf(stderr, "certificate not found.\n");
- PKCS11_release_all_slots(ctx, slot_list, slot_count);
- return NULL;
+ goto err_out;
}
x509 = X509_dup(selected_cert->x509);
- if (cert_label != NULL)
- free(cert_label);
return x509;
+
+err_out:
+ PKCS11_release_all_slots(ctx, slot_list, slot_count);
+ return NULL;
}
int load_cert_ctrl(ENGINE * e, void *p)
{
- struct {
- const char *s_slot_cert_id;
- X509 *cert;
- } *parms = p;
+ struct cert_ctrl_params *params = p;
- if (parms->cert != NULL)
+ if (params->cert == NULL)
return 0;
- parms->cert = pkcs11_load_cert(e, parms->s_slot_cert_id);
- if (parms->cert == NULL)
+ params->cert = pkcs11_load_cert(e, params->slot_nr, params->cert_id,
+ params->cert_id_len, params->cert_label);
+
+ if (params->cert == NULL)
return 0;
return 1;
+
}
static EVP_PKEY *pkcs11_load_key
int store_cert_ctrl(ENGINE * e, void *p)
{
- struct {
- int slot_nr;
- unsigned char *cert_id;
- size_t cert_id_len;
- char *cert_label;
- X509 *cert;
- } *parms = p;
-
- if (parms->cert == NULL)
+ struct cert_ctrl_params *params = p;
+
+ if (params->cert == NULL)
return 0;
- if (pkcs11_store_cert(e, parms->slot_nr, parms->cert_id,
- parms->cert_id_len, parms->cert_label, parms->cert))
+ if (pkcs11_store_cert(e, params->slot_nr, params->cert_id,
+ params->cert_id_len, params->cert_label, params->cert))
return 0;
return 1;