- list and extract public keys

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@323 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
okir 2002-03-14 16:57:20 +00:00
parent 3161964a4b
commit a42a47ea33
1 changed files with 108 additions and 6 deletions

View File

@ -28,6 +28,7 @@ int opt_reader = 0, opt_debug = 0;
int opt_no_cache = 0; int opt_no_cache = 0;
char * opt_pin_id; char * opt_pin_id;
char * opt_cert = NULL; char * opt_cert = NULL;
char * opt_pubkey = NULL;
char * opt_outfile = NULL; char * opt_outfile = NULL;
char * opt_newpin = NULL; char * opt_newpin = NULL;
@ -38,6 +39,14 @@ int quiet = 0;
#define OPT_READER 0x102 #define OPT_READER 0x102
#define OPT_PIN_ID 0x103 #define OPT_PIN_ID 0x103
#define OPT_NO_CACHE 0x104 #define OPT_NO_CACHE 0x104
#define OPT_LIST_PUB 0x105
#define OPT_READ_PUB 0x106
#define PEM_RSA_KEY_PREFIX \
"\x30\x11\x30\x0D\x06\x09" \
"\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01" \
"\x05\x00\x03\x00\x00"
#define PEM_RSA_KEY_PREFIX_SIZE 20
const struct option options[] = { const struct option options[] = {
{ "learn-card", 0, 0, 'L' }, { "learn-card", 0, 0, 'L' },
@ -46,6 +55,8 @@ const struct option options[] = {
{ "list-pins", 0, 0, OPT_LIST_PINS }, { "list-pins", 0, 0, OPT_LIST_PINS },
{ "change-pin", 0, 0, OPT_CHANGE_PIN }, { "change-pin", 0, 0, OPT_CHANGE_PIN },
{ "list-keys", 0, 0, 'k' }, { "list-keys", 0, 0, 'k' },
{ "list-public-keys", 0, 0, OPT_LIST_PUB },
{ "read-public-key", 1, 0, OPT_READ_PUB },
{ "reader", 1, 0, OPT_READER }, { "reader", 1, 0, OPT_READER },
{ "output", 1, 0, 'o' }, { "output", 1, 0, 'o' },
{ "quiet", 0, 0, 'q' }, { "quiet", 0, 0, 'q' },
@ -62,6 +73,8 @@ const char *option_help[] = {
"Lists PIN codes", "Lists PIN codes",
"Changes the PIN code", "Changes the PIN code",
"Lists private keys", "Lists private keys",
"Lists public keys",
"Reads public key with ID <arg>",
"Uses reader number <arg>", "Uses reader number <arg>",
"Outputs to file <arg>", "Outputs to file <arg>",
"Quiet operation", "Quiet operation",
@ -111,14 +124,14 @@ int list_certificates(void)
return 0; return 0;
} }
int print_pem_certificate(struct sc_pkcs15_cert *cert) int
print_pem_object(const char *kind, const u8*data, size_t data_len)
{ {
int r; int r;
u8 buf[2048]; u8 buf[2048];
FILE *outf; FILE *outf;
r = sc_base64_encode(cert->data, cert->data_len, buf, r = sc_base64_encode(data, data_len, buf, sizeof(buf), 64);
sizeof(buf), 64);
if (r) { if (r) {
fprintf(stderr, "Base64 encoding failed: %s\n", sc_strerror(r)); fprintf(stderr, "Base64 encoding failed: %s\n", sc_strerror(r));
return 1; return 1;
@ -132,8 +145,11 @@ int print_pem_certificate(struct sc_pkcs15_cert *cert)
} }
} else } else
outf = stdout; outf = stdout;
fprintf(outf, "-----BEGIN CERTIFICATE-----\n%s-----END CERTIFICATE-----\n", fprintf(outf,
buf); "-----BEGIN %s-----\n"
"%s"
"-----END %s-----\n",
kind, buf, kind);
if (outf != stdout) if (outf != stdout)
fclose(outf); fclose(outf);
return 0; return 0;
@ -168,7 +184,7 @@ int read_certificate(void)
fprintf(stderr, "Certificate read failed: %s\n", sc_strerror(r)); fprintf(stderr, "Certificate read failed: %s\n", sc_strerror(r));
return 1; return 1;
} }
r = print_pem_certificate(cert); r = print_pem_object("CERTIFICATE", cert->data, cert->data_len);
sc_pkcs15_free_certificate(cert); sc_pkcs15_free_certificate(cert);
return r; return r;
} }
@ -286,6 +302,71 @@ void print_pubkey_info(const struct sc_pkcs15_object *obj)
printf("\n"); printf("\n");
} }
int list_public_keys(void)
{
int r, i;
struct sc_pkcs15_object *objs[32];
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PUBKEY_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 public key(s).\n\n", r);
for (i = 0; i < r; i++) {
print_pubkey_info(objs[i]);
printf("\n");
}
return 0;
}
int read_public_key(void)
{
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_pubkey, &id);
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PUBKEY_RSA, objs, 32);
if (r < 0) {
fprintf(stderr, "Public key enumeration failed: %s\n", sc_strerror(r));
return 1;
}
count = r;
for (i = 0; i < count; i++) {
struct sc_pkcs15_pubkey_info *info = objs[i]->data;
struct sc_pkcs15_pubkey_rsa *key;
u8 buffer[512];
if (sc_pkcs15_compare_id(&id, &info->id) != 1)
continue;
if (!quiet)
printf("Reading public key with ID '%s'\n", opt_pubkey);
r = sc_pkcs15_read_pubkey(p15card, info, &key);
if (r) {
fprintf(stderr, "Public key read failed: %s\n", sc_strerror(r));
return 1;
}
memcpy(buffer, PEM_RSA_KEY_PREFIX, PEM_RSA_KEY_PREFIX_SIZE);
buffer[1] += key->data_len;
buffer[PEM_RSA_KEY_PREFIX_SIZE-2] = key->data_len;
memcpy(buffer + PEM_RSA_KEY_PREFIX_SIZE,
key->data, key->data_len);
r = print_pem_object("PUBLIC KEY", buffer,
PEM_RSA_KEY_PREFIX_SIZE + key->data_len);
/* XXX TBD
sc_pkcs15_free_pubkey(key);
*/
return r;
}
fprintf(stderr, "Public key with ID '%s' not found.\n", opt_pubkey);
return 2;
}
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)
@ -548,6 +629,8 @@ int main(int argc, char * const argv[])
int do_list_certs = 0; int do_list_certs = 0;
int do_list_pins = 0; int do_list_pins = 0;
int do_list_prkeys = 0; int do_list_prkeys = 0;
int do_list_pubkeys = 0;
int do_read_pubkey = 0;
int do_change_pin = 0; int do_change_pin = 0;
int do_learn_card = 0; int do_learn_card = 0;
int action_count = 0; int action_count = 0;
@ -580,6 +663,15 @@ int main(int argc, char * const argv[])
do_list_prkeys = 1; do_list_prkeys = 1;
action_count++; action_count++;
break; break;
case OPT_LIST_PUB:
do_list_pubkeys = 1;
action_count++;
break;
case OPT_READ_PUB:
opt_pubkey = optarg;
do_read_pubkey = 1;
action_count++;
break;
case 'L': case 'L':
do_learn_card = 1; do_learn_card = 1;
action_count++; action_count++;
@ -676,6 +768,16 @@ int main(int argc, char * const argv[])
goto end; goto end;
action_count--; action_count--;
} }
if (do_list_pubkeys) {
if ((err = list_public_keys()))
goto end;
action_count--;
}
if (do_read_pubkey) {
if ((err = read_public_key()))
goto end;
action_count--;
}
if (do_list_pins) { if (do_list_pins) {
if ((err = list_pins())) if ((err = list_pins()))
goto end; goto end;