Commit 88fadf6a authored by Niels Möller's avatar Niels Möller

(enum output_mode): New enum.

(encode_base64_line): New function.
(sexp_to_ssh2_key): Alternative output formats, fingerprint and
openssh single-line format.
(main_options): New options --fingerprint and --openssh.
(make_options): Make standard format the default output format.
(main_argp_parser): Handle new options.

Rev: src/lsh-export-key.c:1.20
parent 9dbca13b
......@@ -63,6 +63,13 @@ B2CTISEmV3KYx5NJpyKC3IBw/ckP6Q==
#include "werror.h"
#include "xalloc.h"
enum output_mode
{
OUTPUT_STANDARD = 0,
OUTPUT_FINGERPRINT = 1,
OUTPUT_OPENSSH = 2,
};
#include "lsh-export-key.c.x"
static struct lsh_string *
......@@ -122,12 +129,41 @@ encode_base64(const struct lsh_string *s)
return res;
}
static struct lsh_string *
encode_base64_line(const struct lsh_string *s)
{
uint32_t input_length = lsh_string_length(s);
const uint8_t *data = lsh_string_data(s);
unsigned encoded_length = BASE64_ENCODE_RAW_LENGTH(input_length);
struct base64_encode_ctx ctx;
unsigned out;
struct lsh_string *res = lsh_string_alloc(encoded_length + BASE64_ENCODE_FINAL_LENGTH);
base64_encode_init(&ctx);
out = lsh_string_base64_encode_update(res, 0,
&ctx,
input_length, data);
out += lsh_string_base64_encode_final(res, out, &ctx);
assert (out == encoded_length);
lsh_string_trunc(res, out);
lsh_string_free(s);
return res;
}
static struct lsh_string *
sexp_to_ssh2_key(struct lsh_string *expr,
struct export_key_options *options)
{
struct sexp_iterator i;
struct verifier *v;
int algorithm_name;
struct lsh_string *key;
if (!(lsh_string_transport_iterator_first(expr, &i)
&& sexp_iterator_check_type(&i, "public-key")))
......@@ -136,21 +172,64 @@ sexp_to_ssh2_key(struct lsh_string *expr,
return NULL;
}
v = spki_make_verifier(options->algorithms, &i);
v = spki_make_verifier(options->algorithms, &i, &algorithm_name);
if (!v)
{
werror("Unsupported algorithm\n");
return NULL;
}
return ssh_format("---- BEGIN SSH2 PUBLIC KEY ----\n"
"%lfS"
"%lfS"
"\n%lfS"
"---- END SSH2 PUBLIC KEY ----\n",
make_header("Subject", options->subject),
make_header("Comment", options->comment),
encode_base64(PUBLIC_KEY(v)));
key = PUBLIC_KEY(v);
switch (options->mode)
{
default:
fatal("Internal error.\n");
case OUTPUT_STANDARD:
return ssh_format("---- BEGIN SSH2 PUBLIC KEY ----\n"
"%lfS"
"%lfS"
"\n%lfS"
"---- END SSH2 PUBLIC KEY ----\n",
make_header("Subject", options->subject),
make_header("Comment", options->comment),
encode_base64(key));
case OUTPUT_FINGERPRINT:
{
struct lsh_string *output
= ssh_format("MD5 fingerprint: %lfS\n"
"Bubble Babble: %lfS\n",
lsh_string_colonize(
ssh_format("%lfxS",
hash_string(&crypto_md5_algorithm, key, 0)),
2, 1),
lsh_string_bubblebabble(
hash_string(&crypto_sha1_algorithm, key, 0), 1));
lsh_string_free(key);
return output;
}
case OUTPUT_OPENSSH:
{
key = encode_base64_line(key);
switch (algorithm_name)
{
default:
werror("Keys of type %a not supported.\n");
lsh_string_free(key);
return NULL;
case ATOM_RSA_PKCS1_SHA1:
case ATOM_RSA_PKCS1_MD5:
case ATOM_RSA_PKCS1:
return ssh_format("%la %lfS\n", ATOM_SSH_RSA, key);
case ATOM_DSA:
return ssh_format("%la %lfS\n", ATOM_SSH_DSS, key);
}
}
}
}
/* Option parsing */
......@@ -164,6 +243,8 @@ const char *argp_program_bug_address = BUG_ADDRESS;
#define OPT_OUTFILE 'o'
#define OPT_SUBJECT 's'
#define OPT_COMMENT 'c'
#define OPT_OPENSSH 0x100
#define OPT_FINGERPRINT 0x101
static const struct argp_option
main_options[] =
......@@ -173,6 +254,8 @@ main_options[] =
{ "output-file", OPT_OUTFILE, "Filename", 0, "Default is stdout", 0 },
{ "subject", OPT_SUBJECT, "subject string", 0, "Add subject to output key.", 0 },
{ "comment", OPT_COMMENT, "comment string", 0, "Add comment to output key.", 0 },
{ "fingerprint", OPT_FINGERPRINT, NULL, 0, "Show key fingerprint.", 0 },
{ "openssh", OPT_OPENSSH, NULL, 0, "Output key in openssh single-line format.", 0 },
{ NULL, 0, NULL, 0, NULL, 0 }
};
......@@ -181,6 +264,7 @@ main_options[] =
(name export_key_options)
(vars
(algorithms object alist)
(mode . "enum output_mode")
(infile . "const char *")
(outfile . "const char *")
(subject . "const char *")
......@@ -194,6 +278,7 @@ make_options(void)
self->infile = NULL;
self->subject = NULL;
self->comment = NULL;
self->mode = OUTPUT_STANDARD;
self->algorithms = all_signature_algorithms(NULL);
return self;
......@@ -232,6 +317,12 @@ main_argp_parser(int key, char *arg, struct argp_state *state)
case OPT_COMMENT:
self->comment = arg;
break;
case OPT_FINGERPRINT:
self->mode = OUTPUT_FINGERPRINT;
break;
case OPT_OPENSSH:
self->mode = OUTPUT_OPENSSH;
break;
}
return 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment