- --read-public-key will work for non-rsa keys too

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@543 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
okir 2002-04-17 12:20:31 +00:00
parent a5dd0dbb99
commit 5fb2db70fe
1 changed files with 73 additions and 21 deletions

View File

@ -44,11 +44,8 @@ int quiet = 0;
#define OPT_LIST_PUB 0x105 #define OPT_LIST_PUB 0x105
#define OPT_READ_PUB 0x106 #define OPT_READ_PUB 0x106
#define PEM_RSA_KEY_PREFIX \ static int pem_encode(struct sc_context *, int,
"\x30\x12\x30\x0D\x06\x09" \ sc_pkcs15_der_t *, sc_pkcs15_der_t *);
"\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' },
@ -340,27 +337,44 @@ int read_public_key(void)
count = r; count = r;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
struct sc_pkcs15_pubkey_info *info = objs[i]->data; struct sc_pkcs15_pubkey_info *info = objs[i]->data;
struct sc_pkcs15_pubkey_rsa *key; sc_pkcs15_der_t raw_key, pem_key;
u8 buffer[512]; int algorithm;
if (sc_pkcs15_compare_id(&id, &info->id) != 1) if (sc_pkcs15_compare_id(&id, &info->id) != 1)
continue; continue;
if (!quiet) switch (objs[i]->type) {
printf("Reading public key with ID '%s'\n", opt_pubkey); case SC_PKCS15_TYPE_PUBKEY_RSA:
r = sc_pkcs15_read_pubkey(p15card, info, &key); algorithm = SC_ALGORITHM_RSA;
if (r) { break;
fprintf(stderr, "Public key read failed: %s\n", sc_strerror(r)); case SC_PKCS15_TYPE_PUBKEY_DSA:
algorithm = SC_ALGORITHM_DSA;
break;
default:
fprintf(stderr, "Unsupported key type.\n");
return 1; return 1;
} }
memcpy(buffer, PEM_RSA_KEY_PREFIX, PEM_RSA_KEY_PREFIX_SIZE);
buffer[1] += key->data.len; if (!quiet)
buffer[PEM_RSA_KEY_PREFIX_SIZE-2] = key->data.len + 1; printf("Reading public key with ID '%s'\n", opt_pubkey);
memcpy(buffer + PEM_RSA_KEY_PREFIX_SIZE, r = sc_pkcs15_read_file(p15card, &info->path,
key->data.value, key->data.len); &raw_key.value, &raw_key.len);
r = print_pem_object("PUBLIC KEY", buffer, if (r) {
PEM_RSA_KEY_PREFIX_SIZE + key->data.len); fprintf(stderr, "Failed to read public key: %s\n",
sc_pkcs15_free_pubkey(key); sc_strerror(r));
return 1;
}
r = pem_encode(ctx, algorithm, &raw_key, &pem_key);
if (r < 0) {
fprintf(stderr, "Error encoding PEM key: %s\n",
sc_strerror(r));
free(raw_key.value);
return 1;
}
r = print_pem_object("PUBLIC KEY", pem_key.value, pem_key.len);
free(raw_key.value);
free(pem_key.value);
return r; return r;
} }
fprintf(stderr, "Public key with ID '%s' not found.\n", opt_pubkey); fprintf(stderr, "Public key with ID '%s' not found.\n", opt_pubkey);
@ -798,3 +812,41 @@ end:
sc_release_context(ctx); sc_release_context(ctx);
return err; return err;
} }
/*
* Helper function for PEM encoding public key
*/
#include "opensc/asn1.h"
static const struct sc_asn1_entry c_asn1_pem_key_items[] = {
{ "algorithm", SC_ASN1_ALGORITHM_ID, SC_ASN1_CONS|ASN1_SEQUENCE, },
{ "key", SC_ASN1_BIT_STRING_NI, ASN1_BIT_STRING },
{ NULL }
};
static const struct sc_asn1_entry c_asn1_pem_key[] = {
{ "publicKey", SC_ASN1_STRUCT, SC_ASN1_CONS|ASN1_SEQUENCE, },
{ NULL }
};
static int
pem_encode(struct sc_context *ctx,
int alg_id, sc_pkcs15_der_t *key, sc_pkcs15_der_t *out)
{
struct sc_asn1_entry asn1_pem_key[2],
asn1_pem_key_items[3];
struct sc_algorithm_id algorithm;
int key_len;
memset(&algorithm, 0, sizeof(algorithm));
algorithm.algorithm = alg_id;
sc_copy_asn1_entry(c_asn1_pem_key, asn1_pem_key);
sc_copy_asn1_entry(c_asn1_pem_key_items, asn1_pem_key_items);
sc_format_asn1_entry(asn1_pem_key + 0, asn1_pem_key_items, NULL, 1);
sc_format_asn1_entry(asn1_pem_key_items + 0,
&algorithm, NULL, 1);
key_len = 8 * key->len;
sc_format_asn1_entry(asn1_pem_key_items + 1,
key->value, &key_len, 1);
return sc_asn1_encode(ctx, asn1_pem_key, &out->value, &out->len);
}