forked from OpenSC/libp11
-
Notifications
You must be signed in to change notification settings - Fork 0
/
listkeys.c
133 lines (113 loc) · 3.35 KB
/
listkeys.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* 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 <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <libp11.h>
#include <unistd.h>
#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);
}
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
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: */