/* libp11 example code: listkeys.c * * This examply simply connects to your smart card * and list the keys. * * Feel free to copy all of the code as needed. * */ #include #include #include #include #include #include #include #include #include #define RANDOM_SOURCE "/dev/urandom" #define RANDOM_SIZE 20 #define MAX_SIGSIZE 256 static void list_keys(const char *title, const PKCS11_KEY *keys, const unsigned int nkeys); static void error_queue(const char *name); #define CHECK_ERR(cond, txt, code) \ do { \ if (cond) { \ fprintf(stderr, "%s\n", (txt)); \ rc=(code); \ goto end; \ } \ } while (0) int main(int argc, char *argv[]) { PKCS11_CTX *ctx=NULL; PKCS11_SLOT *slots=NULL, *slot; PKCS11_KEY *keys; unsigned int nslots, nkeys; int rc = 0; if (argc < 2) { fprintf(stderr, "usage: %s /usr/lib/opensc-pkcs11.so [PIN]\n", argv[0]); return 1; } ctx = PKCS11_CTX_new(); error_queue("PKCS11_CTX_new"); /* load pkcs #11 module */ rc = PKCS11_CTX_load(ctx, argv[1]); error_queue("PKCS11_CTX_load"); CHECK_ERR(rc < 0, "loading pkcs11 engine failed", 1); /* get information on all slots */ rc = PKCS11_enumerate_slots(ctx, &slots, &nslots); error_queue("PKCS11_enumerate_slots"); CHECK_ERR(rc < 0, "no slots available", 2); /* get first slot with a token */ slot = PKCS11_find_token(ctx, slots, nslots); error_queue("PKCS11_find_token"); CHECK_ERR(!slot || !slot->token, "no token available", 3); printf("Slot manufacturer......: %s\n", slot->manufacturer); printf("Slot description.......: %s\n", slot->description); printf("Slot token label.......: %s\n", slot->token->label); printf("Slot token manufacturer: %s\n", slot->token->manufacturer); printf("Slot token model.......: %s\n", slot->token->model); printf("Slot token serialnr....: %s\n", slot->token->serialnr); /* get public keys */ rc = PKCS11_enumerate_public_keys(slot->token, &keys, &nkeys); error_queue("PKCS11_enumerate_public_keys"); CHECK_ERR(rc < 0, "PKCS11_enumerate_public_keys failed", 4); CHECK_ERR(nkeys == 0, "No public keys found", 5); list_keys("Public keys", keys, nkeys); if (slot->token->loginRequired && argc > 2) { /* perform pkcs #11 login */ rc = PKCS11_login(slot, 0, argv[2]); error_queue("PKCS11_login"); CHECK_ERR(rc < 0, "PKCS11_login failed", 6); } /* get private keys */ rc = PKCS11_enumerate_keys(slot->token, &keys, &nkeys); error_queue("PKCS11_enumerate_keys"); CHECK_ERR(rc < 0, "PKCS11_enumerate_keys failed", 7); CHECK_ERR(nkeys == 0, "No private keys found", 8); list_keys("Private keys", keys, nkeys); end: if (slots) PKCS11_release_all_slots(ctx, slots, nslots); if (ctx) { PKCS11_CTX_unload(ctx); PKCS11_CTX_free(ctx); } if (rc) printf("Failed (error code %d).\n", rc); else printf("Success.\n"); return rc; } static void list_keys(const char *title, const PKCS11_KEY *keys, const unsigned int nkeys) { unsigned int i; printf("\n%s:\n", title); for (i = 0; i < nkeys; i++) printf(" * %s key: %s\n", keys[i].isPrivate ? "Private" : "Public", keys[i].label); } static void error_queue(const char *name) { if (ERR_peek_last_error()) { fprintf(stderr, "%s generated errors:\n", name); ERR_print_errors_fp(stderr); } } /* vim: set noexpandtab: */