tool: RFC4716 compliant key output

Add a comment field to the ssh key output if a label is set on the key. Add RFC4716 compliant key output for the new breed of modern (mobile) SSH clients.

VTA: use short form of log call in iso7816
This commit is contained in:
Dirk-Willem van Gulik 2015-03-17 12:42:01 +01:00 committed by Viktor Tarasov
parent 0790969b97
commit 88ec461bc5
3 changed files with 58 additions and 16 deletions

View File

@ -185,7 +185,21 @@
</term>
<listitem><para>Reads the public key with id <replaceable>id</replaceable>,
writing the output in format suitable for
<filename>$HOME/.ssh/authorized_keys</filename>.</para></listitem>
<filename>$HOME/.ssh/authorized_keys</filename>.</para>
<para>The key label, if any will be shown in the 'Comment' field.</para>
<varlistentry>
<term>
<option>--rfc4716</option>
</term>
<listitem><para>When used in conjunction with option <option>--read-ssh-key</option> the
output format of the public key follows rfc4716.</para></listitem>
</varlistentry>
<para></para>
<para> The default output format is a single line (openssh).</para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -1016,8 +1016,7 @@ iso7816_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu,
* but expect the new one to be entered on the keypad.
*/
if (data->pin1.len && data->pin2.len == 0) {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
"Special case - initial pin provided - but new pin asked on keypad");
sc_log(card->ctx, "Special case - initial pin provided - but new pin asked on keypad");
data->flags |= SC_PIN_CMD_IMPLICIT_CHANGE;
};
len += r;

View File

@ -57,6 +57,9 @@ static const char * opt_pin = NULL;
static const char * opt_puk = NULL;
static int verbose = 0;
static int opt_no_prompt = 0;
#if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
static int opt_rfc4716 = 0;
#endif
enum {
OPT_CHANGE_PIN = 0x100,
@ -68,6 +71,7 @@ enum {
OPT_READ_PUB,
#if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
OPT_READ_SSH,
OPT_RFC4716,
#endif
OPT_PIN,
OPT_NEWPIN,
@ -76,7 +80,7 @@ enum {
OPT_BIND_TO_AID,
OPT_LIST_APPLICATIONS,
OPT_LIST_SKEYS,
OPT_NO_PROMPT
OPT_NO_PROMPT,
};
#define NELEMENTS(x) (sizeof(x)/sizeof((x)[0]))
@ -100,6 +104,7 @@ static const struct option options[] = {
{ "read-public-key", required_argument, NULL, OPT_READ_PUB },
#if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
{ "read-ssh-key", required_argument, NULL, OPT_READ_SSH },
{ "rfc4716", no_argument, NULL, OPT_RFC4716 },
#endif
{ "test-update", no_argument, NULL, 'T' },
{ "update", no_argument, NULL, 'U' },
@ -786,6 +791,36 @@ static int list_skeys(void)
#if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
static void print_ssh_key(FILE *outf, const char * alg, struct sc_pkcs15_object *obj, unsigned char * buf, uint32_t len) {
unsigned char *uu;
int r;
uu = malloc(len*2); // Way over - even if we have extra LFs; as each 6 bits take one byte.
if (opt_rfc4716) {
r = sc_base64_encode(buf, len, uu, 2*len, 64);
fprintf(outf,"---- BEGIN SSH2 PUBLIC KEY ----\n");
if (obj->label && strlen(obj->label))
fprintf(outf,"Comment: \"%s\"\n", obj->label);
fprintf(outf,"%s", uu);
fprintf(outf,"---- END SSH2 PUBLIC KEY ----\n");
} else {
// Old style openssh - [<quote protected options> <whitespace> <keytype> <whitespace> <key> [<whitespace> anything else]
//
r = sc_base64_encode(buf, len, uu, 2*len, 0);
if (obj->label && strlen(obj->label))
fprintf(outf,"ssh-%s %s %s\n", alg, uu, obj->label);
else
fprintf(outf,"ssh-%s %s\n", alg, uu);
}
free(uu);
return;
}
static int read_ssh_key(void)
{
int r;
@ -844,7 +879,6 @@ static int read_ssh_key(void)
if (pubkey->algorithm == SC_ALGORITHM_RSA) {
unsigned char buf[2048];
unsigned char *uu;
uint32_t len, n;
if (!pubkey->u.rsa.modulus.data || !pubkey->u.rsa.modulus.len ||
@ -895,16 +929,11 @@ static int read_ssh_key(void)
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);
fprintf(outf,"ssh-rsa %s", uu);
free(uu);
print_ssh_key(outf, "rsa", obj, buf, len);
}
if (pubkey->algorithm == SC_ALGORITHM_DSA) {
unsigned char buf[2048];
unsigned char *uu;
uint32_t len;
uint32_t n;
@ -991,11 +1020,7 @@ static int read_ssh_key(void)
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);
fprintf(outf,"ssh-dss %s", uu);
free(uu);
print_ssh_key(outf, "dss", obj, buf, len);
}
if (outf != stdout)
@ -1016,6 +1041,7 @@ fail2:
sc_pkcs15_free_pubkey(pubkey);
return SC_ERROR_OUT_OF_MEMORY;
}
#endif
static sc_pkcs15_object_t *
@ -1900,6 +1926,9 @@ int main(int argc, char * const argv[])
do_read_sshkey = 1;
action_count++;
break;
case OPT_RFC4716:
opt_rfc4716 = 1;
break;
#endif
case 'L':
do_learn_card = 1;