add options for displaying openssh keys.
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@2351 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
4568015476
commit
f5b1018d04
|
@ -21,10 +21,17 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <asm/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/crypto.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <opensc/pkcs15.h>
|
||||
#include "util.h"
|
||||
|
||||
|
||||
const char *app_name = "pkcs15-tool";
|
||||
|
||||
int opt_reader = -1, opt_wait = 0;
|
||||
|
@ -48,6 +55,9 @@ enum {
|
|||
OPT_NO_CACHE,
|
||||
OPT_LIST_PUB,
|
||||
OPT_READ_PUB,
|
||||
#ifdef HAVE_OPENSSL
|
||||
OPT_READ_SSH,
|
||||
#endif
|
||||
OPT_PIN,
|
||||
OPT_NEWPIN,
|
||||
OPT_PUK,
|
||||
|
@ -71,6 +81,9 @@ const struct option options[] = {
|
|||
{ "list-keys", no_argument, 0, 'k' },
|
||||
{ "list-public-keys", no_argument, 0, OPT_LIST_PUB },
|
||||
{ "read-public-key", required_argument, 0, OPT_READ_PUB },
|
||||
#ifdef HAVE_OPENSSL
|
||||
{ "read-ssh-key", required_argument, 0, OPT_READ_SSH },
|
||||
#endif
|
||||
{ "reader", required_argument, 0, OPT_READER },
|
||||
{ "pin", required_argument, 0, OPT_PIN },
|
||||
{ "new-pin", required_argument, 0, OPT_NEWPIN },
|
||||
|
@ -95,6 +108,7 @@ const char *option_help[] = {
|
|||
"Lists private keys",
|
||||
"Lists public keys",
|
||||
"Reads public key with ID <arg>",
|
||||
"Reads public key with ID <arg>, outputs ssh format",
|
||||
"Uses reader number <arg>",
|
||||
"Specify PIN",
|
||||
"Specify New PIN (when changing or unblocking)",
|
||||
|
@ -540,6 +554,228 @@ static int read_public_key(void)
|
|||
return r;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
static int read_ssh_key(void)
|
||||
{
|
||||
int r;
|
||||
struct sc_pkcs15_id id;
|
||||
struct sc_pkcs15_object *obj;
|
||||
sc_pkcs15_pubkey_t *pubkey = NULL;
|
||||
sc_pkcs15_cert_t *cert = NULL;
|
||||
|
||||
id.len = SC_PKCS15_MAX_ID_SIZE;
|
||||
sc_pkcs15_hex_string_to_id(opt_pubkey, &id);
|
||||
|
||||
r = sc_pkcs15_find_pubkey_by_id(p15card, &id, &obj);
|
||||
if (r >= 0) {
|
||||
if (verbose)
|
||||
printf("Reading ssh key with ID '%s'\n", opt_pubkey);
|
||||
r = authenticate(obj);
|
||||
if (r >= 0)
|
||||
r = sc_pkcs15_read_pubkey(p15card, obj, &pubkey);
|
||||
} else if (r == SC_ERROR_OBJECT_NOT_FOUND) {
|
||||
/* No pubkey - try if there's a certificate */
|
||||
r = sc_pkcs15_find_cert_by_id(p15card, &id, &obj);
|
||||
if (r >= 0) {
|
||||
if (verbose)
|
||||
printf("Reading certificate with ID '%s'\n", opt_pubkey);
|
||||
r = sc_pkcs15_read_certificate(p15card,
|
||||
(sc_pkcs15_cert_info_t *) obj->data,
|
||||
&cert);
|
||||
}
|
||||
if (r >= 0)
|
||||
pubkey = &cert->key;
|
||||
}
|
||||
|
||||
if (r == SC_ERROR_OBJECT_NOT_FOUND) {
|
||||
fprintf(stderr, "Public key with ID '%s' not found.\n", opt_pubkey);
|
||||
return 2;
|
||||
}
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Public key enumeration failed: %s\n", sc_strerror(r));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* rsa1 keys */
|
||||
if (pubkey->algorithm == SC_ALGORITHM_RSA) {
|
||||
int bits;
|
||||
BIGNUM *bn;
|
||||
char *exp,*mod;
|
||||
|
||||
bn = BN_new();
|
||||
BN_bin2bn((unsigned char*)pubkey->u.rsa.modulus.data,
|
||||
pubkey->u.rsa.modulus.len, bn);
|
||||
bits = BN_num_bits(bn);
|
||||
exp = BN_bn2dec(bn);
|
||||
BN_free(bn);
|
||||
|
||||
bn = BN_new();
|
||||
BN_bin2bn((unsigned char*)pubkey->u.rsa.exponent.data,
|
||||
pubkey->u.rsa.exponent.len, bn);
|
||||
mod = BN_bn2dec(bn);
|
||||
BN_free(bn);
|
||||
|
||||
if (bits && exp && mod) {
|
||||
printf("%u %s %s\n", bits,mod,exp);
|
||||
} else {
|
||||
printf("decoding rsa key failed!\n");
|
||||
}
|
||||
OPENSSL_free(exp);
|
||||
OPENSSL_free(mod);
|
||||
}
|
||||
|
||||
/* rsa and des keys - ssh2 */
|
||||
/* key_to_blob */
|
||||
|
||||
if (pubkey->algorithm == SC_ALGORITHM_RSA) {
|
||||
char buf[2048];
|
||||
char *uu;
|
||||
__u32 len;
|
||||
__u32 n;
|
||||
|
||||
buf[0]=0;
|
||||
buf[1]=0;
|
||||
buf[2]=0;
|
||||
buf[3]=7;
|
||||
|
||||
len = sprintf(buf+4,"ssh-rsa");
|
||||
len+=4;
|
||||
|
||||
if (sizeof(buf)-len < 4+pubkey->u.rsa.exponent.len)
|
||||
goto fail;
|
||||
n = pubkey->u.rsa.exponent.len;
|
||||
if (pubkey->u.rsa.exponent.data[0] & 0x80) n++;
|
||||
buf[len++]=(n >>24) & 0xff;
|
||||
buf[len++]=(n >>16) & 0xff;
|
||||
buf[len++]=(n >>8) & 0xff;
|
||||
buf[len++]=(n) & 0xff;
|
||||
if (pubkey->u.rsa.exponent.data[0] & 0x80)
|
||||
buf[len++]= 0;
|
||||
|
||||
memcpy(buf+len,pubkey->u.rsa.exponent.data,
|
||||
pubkey->u.rsa.exponent.len);
|
||||
len += pubkey->u.rsa.exponent.len;
|
||||
|
||||
if (sizeof(buf)-len < 5+pubkey->u.rsa.modulus.len)
|
||||
goto fail;
|
||||
n = pubkey->u.rsa.modulus.len;
|
||||
if (pubkey->u.rsa.modulus.data[0] & 0x80) n++;
|
||||
buf[len++]=(n >>24) & 0xff;
|
||||
buf[len++]=(n >>16) & 0xff;
|
||||
buf[len++]=(n >>8) & 0xff;
|
||||
buf[len++]=(n) & 0xff;
|
||||
if (pubkey->u.rsa.modulus.data[0] & 0x80)
|
||||
buf[len++]= 0;
|
||||
|
||||
memcpy(buf+len,pubkey->u.rsa.modulus.data,
|
||||
pubkey->u.rsa.modulus.len);
|
||||
len += pubkey->u.rsa.modulus.len;
|
||||
|
||||
uu = malloc(len*2);
|
||||
r = sc_base64_encode(buf, len, uu, 2*len, 2*len);
|
||||
|
||||
printf("ssh-rsa %s", uu);
|
||||
free(uu);
|
||||
|
||||
}
|
||||
|
||||
if (pubkey->algorithm == SC_ALGORITHM_DSA) {
|
||||
char buf[2048];
|
||||
char *uu;
|
||||
__u32 len;
|
||||
__u32 n;
|
||||
|
||||
buf[0]=0;
|
||||
buf[1]=0;
|
||||
buf[2]=0;
|
||||
buf[3]=7;
|
||||
|
||||
len = sprintf(buf+4,"ssh-dss");
|
||||
len+=4;
|
||||
|
||||
if (sizeof(buf)-len < 5+pubkey->u.dsa.p.len)
|
||||
goto fail;
|
||||
n = pubkey->u.dsa.p.len;
|
||||
if (pubkey->u.dsa.p.data[0] & 0x80) n++;
|
||||
buf[len++]=(n >>24) & 0xff;
|
||||
buf[len++]=(n >>16) & 0xff;
|
||||
buf[len++]=(n >>8) & 0xff;
|
||||
buf[len++]=(n) & 0xff;
|
||||
if (pubkey->u.dsa.p.data[0] & 0x80)
|
||||
buf[len++]= 0;
|
||||
|
||||
memcpy(buf+len,pubkey->u.dsa.p.data,
|
||||
pubkey->u.dsa.p.len);
|
||||
len += pubkey->u.dsa.p.len;
|
||||
|
||||
if (sizeof(buf)-len < 5+pubkey->u.dsa.q.len)
|
||||
goto fail;
|
||||
n = pubkey->u.dsa.q.len;
|
||||
if (pubkey->u.dsa.q.data[0] & 0x80) n++;
|
||||
buf[len++]=(n >>24) & 0xff;
|
||||
buf[len++]=(n >>16) & 0xff;
|
||||
buf[len++]=(n >>8) & 0xff;
|
||||
buf[len++]=(n) & 0xff;
|
||||
if (pubkey->u.dsa.q.data[0] & 0x80)
|
||||
buf[len++]= 0;
|
||||
|
||||
memcpy(buf+len,pubkey->u.dsa.q.data,
|
||||
pubkey->u.dsa.q.len);
|
||||
len += pubkey->u.dsa.q.len;
|
||||
|
||||
if (sizeof(buf)-len < 5+pubkey->u.dsa.g.len)
|
||||
goto fail;
|
||||
n = pubkey->u.dsa.g.len;
|
||||
if (pubkey->u.dsa.g.data[0] & 0x80) n++;
|
||||
buf[len++]=(n >>24) & 0xff;
|
||||
buf[len++]=(n >>16) & 0xff;
|
||||
buf[len++]=(n >>8) & 0xff;
|
||||
buf[len++]=(n) & 0xff;
|
||||
if (pubkey->u.dsa.g.data[0] & 0x80)
|
||||
buf[len++]= 0;
|
||||
|
||||
memcpy(buf+len,pubkey->u.dsa.g.data,
|
||||
pubkey->u.dsa.g.len);
|
||||
len += pubkey->u.dsa.g.len;
|
||||
|
||||
if (sizeof(buf)-len < 5+pubkey->u.dsa.pub.len)
|
||||
goto fail;
|
||||
n = pubkey->u.dsa.pub.len;
|
||||
if (pubkey->u.dsa.pub.data[0] & 0x80) n++;
|
||||
buf[len++]=(n >>24) & 0xff;
|
||||
buf[len++]=(n >>16) & 0xff;
|
||||
buf[len++]=(n >>8) & 0xff;
|
||||
buf[len++]=(n) & 0xff;
|
||||
if (pubkey->u.dsa.pub.data[0] & 0x80)
|
||||
buf[len++]= 0;
|
||||
|
||||
memcpy(buf+len,pubkey->u.dsa.pub.data,
|
||||
pubkey->u.dsa.pub.len);
|
||||
len += pubkey->u.dsa.pub.len;
|
||||
|
||||
uu = malloc(len*2);
|
||||
r = sc_base64_encode(buf, len, uu, 2*len, 2*len);
|
||||
|
||||
printf("ssh-dss %s", uu);
|
||||
free(uu);
|
||||
|
||||
}
|
||||
|
||||
if (cert)
|
||||
sc_pkcs15_free_certificate(cert);
|
||||
else if (pubkey)
|
||||
sc_pkcs15_free_pubkey(pubkey);
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
printf("can't convert key: buffer too small\n");
|
||||
if (cert)
|
||||
sc_pkcs15_free_certificate(cert);
|
||||
else if (pubkey)
|
||||
sc_pkcs15_free_pubkey(pubkey);
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
#endif
|
||||
|
||||
static sc_pkcs15_object_t *
|
||||
get_pin_info(void)
|
||||
|
@ -875,6 +1111,7 @@ int main(int argc, char * const argv[])
|
|||
int do_list_prkeys = 0;
|
||||
int do_list_pubkeys = 0;
|
||||
int do_read_pubkey = 0;
|
||||
int do_read_sshkey = 0;
|
||||
int do_change_pin = 0;
|
||||
int do_unblock_pin = 0;
|
||||
int do_learn_card = 0;
|
||||
|
@ -930,6 +1167,11 @@ int main(int argc, char * const argv[])
|
|||
do_read_pubkey = 1;
|
||||
action_count++;
|
||||
break;
|
||||
case OPT_READ_SSH:
|
||||
opt_pubkey = optarg;
|
||||
do_read_sshkey = 1;
|
||||
action_count++;
|
||||
break;
|
||||
case 'L':
|
||||
do_learn_card = 1;
|
||||
action_count++;
|
||||
|
@ -1029,6 +1271,11 @@ int main(int argc, char * const argv[])
|
|||
goto end;
|
||||
action_count--;
|
||||
}
|
||||
if (do_read_sshkey) {
|
||||
if ((err = read_ssh_key()))
|
||||
goto end;
|
||||
action_count--;
|
||||
}
|
||||
if (do_list_pins) {
|
||||
if ((err = list_pins()))
|
||||
goto end;
|
||||
|
|
Loading…
Reference in New Issue