diff options
author | Damien Miller <djm@mindrot.org> | 2010-07-02 13:35:01 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2010-07-02 13:35:01 +1000 |
commit | 44b25040110a224a79ff371ee548be9a10ba8bfa (patch) | |
tree | 19e7e606355d900658326870a984fac97e6d3940 | |
parent | b96c441ee2e4d8ffae756d0d74e2777149c91067 (diff) |
- djm@cvs.openbsd.org 2010/06/29 23:15:30
[ssh-keygen.1 ssh-keygen.c]
allow import (-i) and export (-e) of PEM and PKCS#8 encoded keys;
bz#1749; ok markus@
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | ssh-keygen.1 | 47 | ||||
-rw-r--r-- | ssh-keygen.c | 281 |
3 files changed, 266 insertions, 66 deletions
@@ -6,6 +6,10 @@ | |||
6 | - djm@cvs.openbsd.org 2010/06/26 23:04:04 | 6 | - djm@cvs.openbsd.org 2010/06/26 23:04:04 |
7 | [ssh.c] | 7 | [ssh.c] |
8 | oops, forgot to #include <canohost.h>; spotted and patch from chl@ | 8 | oops, forgot to #include <canohost.h>; spotted and patch from chl@ |
9 | - djm@cvs.openbsd.org 2010/06/29 23:15:30 | ||
10 | [ssh-keygen.1 ssh-keygen.c] | ||
11 | allow import (-i) and export (-e) of PEM and PKCS#8 encoded keys; | ||
12 | bz#1749; ok markus@ | ||
9 | 13 | ||
10 | 20100627 | 14 | 20100627 |
11 | - (tim) [openbsd-compat/port-uw.c] Reorder includes. auth-options.h now needs | 15 | - (tim) [openbsd-compat/port-uw.c] Reorder includes. auth-options.h now needs |
diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 26ae31f5e..0d62255ba 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: ssh-keygen.1,v 1.94 2010/04/16 06:47:04 jmc Exp $ | 1 | .\" $OpenBSD: ssh-keygen.1,v 1.95 2010/06/29 23:15:30 djm Exp $ |
2 | .\" | 2 | .\" |
3 | .\" -*- nroff -*- | 3 | .\" -*- nroff -*- |
4 | .\" | 4 | .\" |
@@ -37,7 +37,7 @@ | |||
37 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 37 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
38 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 38 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
39 | .\" | 39 | .\" |
40 | .Dd $Mdocdate: April 16 2010 $ | 40 | .Dd $Mdocdate: June 29 2010 $ |
41 | .Dt SSH-KEYGEN 1 | 41 | .Dt SSH-KEYGEN 1 |
42 | .Os | 42 | .Os |
43 | .Sh NAME | 43 | .Sh NAME |
@@ -59,9 +59,11 @@ | |||
59 | .Op Fl f Ar keyfile | 59 | .Op Fl f Ar keyfile |
60 | .Nm ssh-keygen | 60 | .Nm ssh-keygen |
61 | .Fl i | 61 | .Fl i |
62 | .Op Fl m Ar key_format | ||
62 | .Op Fl f Ar input_keyfile | 63 | .Op Fl f Ar input_keyfile |
63 | .Nm ssh-keygen | 64 | .Nm ssh-keygen |
64 | .Fl e | 65 | .Fl e |
66 | .Op Fl m Ar key_format | ||
65 | .Op Fl f Ar input_keyfile | 67 | .Op Fl f Ar input_keyfile |
66 | .Nm ssh-keygen | 68 | .Nm ssh-keygen |
67 | .Fl y | 69 | .Fl y |
@@ -215,11 +217,13 @@ Download the RSA public keys provided by the PKCS#11 shared library | |||
215 | .Ar pkcs11 . | 217 | .Ar pkcs11 . |
216 | .It Fl e | 218 | .It Fl e |
217 | This option will read a private or public OpenSSH key file and | 219 | This option will read a private or public OpenSSH key file and |
218 | print the key in | 220 | print to stdout the key in one of the formats specified by the |
219 | RFC 4716 SSH Public Key File Format | 221 | .Fl m |
220 | to stdout. | 222 | option. |
221 | This option allows exporting keys for use by several commercial | 223 | The default export format is |
222 | SSH implementations. | 224 | .Dq RFC4716 . |
225 | This option allows exporting OpenSSH key for use by other programs, including | ||
226 | several commercial SSH implementations. | ||
223 | .It Fl F Ar hostname | 227 | .It Fl F Ar hostname |
224 | Search for the specified | 228 | Search for the specified |
225 | .Ar hostname | 229 | .Ar hostname |
@@ -270,13 +274,14 @@ Please see the | |||
270 | section for details. | 274 | section for details. |
271 | .It Fl i | 275 | .It Fl i |
272 | This option will read an unencrypted private (or public) key file | 276 | This option will read an unencrypted private (or public) key file |
273 | in SSH2-compatible format and print an OpenSSH compatible private | 277 | in the format specified by the |
278 | .Fl m | ||
279 | option and print an OpenSSH compatible private | ||
274 | (or public) key to stdout. | 280 | (or public) key to stdout. |
275 | .Nm | 281 | This option allows importing keys from other software, including several |
276 | also reads the | 282 | commercial SSH implementations. |
277 | RFC 4716 SSH Public Key File Format. | 283 | The default import format is |
278 | This option allows importing keys from several commercial | 284 | .Dq RFC4716 . |
279 | SSH implementations. | ||
280 | .It Fl L | 285 | .It Fl L |
281 | Prints the contents of a certificate. | 286 | Prints the contents of a certificate. |
282 | .It Fl l | 287 | .It Fl l |
@@ -288,6 +293,22 @@ tries to find the matching public key file and prints its fingerprint. | |||
288 | If combined with | 293 | If combined with |
289 | .Fl v , | 294 | .Fl v , |
290 | an ASCII art representation of the key is supplied with the fingerprint. | 295 | an ASCII art representation of the key is supplied with the fingerprint. |
296 | .It Fl m Ar key_format | ||
297 | Specify a key format for the | ||
298 | .Fl i | ||
299 | (import) or | ||
300 | .Fl e | ||
301 | (export) coversion options. | ||
302 | The supported key formats are: | ||
303 | .Dq RFC4716 | ||
304 | (RFC4716/SSH2 public or private key), | ||
305 | .Dq PKCS8 | ||
306 | (PEM PKCS8 public key) | ||
307 | or | ||
308 | .Dq PEM | ||
309 | (PEM public key). | ||
310 | The default conversion format is | ||
311 | .Dq RFC4716 . | ||
291 | .It Fl M Ar memory | 312 | .It Fl M Ar memory |
292 | Specify the amount of memory to use (in megabytes) when generating | 313 | Specify the amount of memory to use (in megabytes) when generating |
293 | candidate moduli for DH-GEX. | 314 | candidate moduli for DH-GEX. |
diff --git a/ssh-keygen.c b/ssh-keygen.c index de7c4409d..be08fbda6 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keygen.c,v 1.192 2010/06/23 02:59:02 djm Exp $ */ | 1 | /* $OpenBSD: ssh-keygen.c,v 1.193 2010/06/29 23:15:30 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -133,14 +133,20 @@ u_int32_t certflags_flags = CERTOPT_DEFAULT; | |||
133 | char *certflags_command = NULL; | 133 | char *certflags_command = NULL; |
134 | char *certflags_src_addr = NULL; | 134 | char *certflags_src_addr = NULL; |
135 | 135 | ||
136 | /* Dump public key file in format used by real and the original SSH 2 */ | 136 | /* Conversion to/from various formats */ |
137 | int convert_to_ssh2 = 0; | 137 | int convert_to = 0; |
138 | int convert_from_ssh2 = 0; | 138 | int convert_from = 0; |
139 | enum { | ||
140 | FMT_RFC4716, | ||
141 | FMT_PKCS8, | ||
142 | FMT_PEM | ||
143 | } convert_format = FMT_RFC4716; | ||
139 | int print_public = 0; | 144 | int print_public = 0; |
140 | int print_generic = 0; | 145 | int print_generic = 0; |
141 | 146 | ||
142 | char *key_type_name = NULL; | 147 | char *key_type_name = NULL; |
143 | 148 | ||
149 | |||
144 | /* argv0 */ | 150 | /* argv0 */ |
145 | extern char *__progname; | 151 | extern char *__progname; |
146 | 152 | ||
@@ -215,30 +221,12 @@ load_identity(char *filename) | |||
215 | #define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb | 221 | #define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb |
216 | 222 | ||
217 | static void | 223 | static void |
218 | do_convert_to_ssh2(struct passwd *pw) | 224 | do_convert_to_ssh2(struct passwd *pw, Key *k) |
219 | { | 225 | { |
220 | Key *k; | ||
221 | u_int len; | 226 | u_int len; |
222 | u_char *blob; | 227 | u_char *blob; |
223 | char comment[61]; | 228 | char comment[61]; |
224 | struct stat st; | ||
225 | 229 | ||
226 | if (!have_identity) | ||
227 | ask_filename(pw, "Enter file in which the key is"); | ||
228 | if (stat(identity_file, &st) < 0) { | ||
229 | perror(identity_file); | ||
230 | exit(1); | ||
231 | } | ||
232 | if ((k = key_load_public(identity_file, NULL)) == NULL) { | ||
233 | if ((k = load_identity(identity_file)) == NULL) { | ||
234 | fprintf(stderr, "load failed\n"); | ||
235 | exit(1); | ||
236 | } | ||
237 | } | ||
238 | if (k->type == KEY_RSA1) { | ||
239 | fprintf(stderr, "version 1 keys are not supported\n"); | ||
240 | exit(1); | ||
241 | } | ||
242 | if (key_to_blob(k, &blob, &len) <= 0) { | 230 | if (key_to_blob(k, &blob, &len) <= 0) { |
243 | fprintf(stderr, "key_to_blob failed\n"); | 231 | fprintf(stderr, "key_to_blob failed\n"); |
244 | exit(1); | 232 | exit(1); |
@@ -259,6 +247,81 @@ do_convert_to_ssh2(struct passwd *pw) | |||
259 | } | 247 | } |
260 | 248 | ||
261 | static void | 249 | static void |
250 | do_convert_to_pkcs8(Key *k) | ||
251 | { | ||
252 | switch (key_type_plain(k->type)) { | ||
253 | case KEY_RSA: | ||
254 | if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) | ||
255 | fatal("PEM_write_RSA_PUBKEY failed"); | ||
256 | break; | ||
257 | case KEY_DSA: | ||
258 | if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) | ||
259 | fatal("PEM_write_DSA_PUBKEY failed"); | ||
260 | break; | ||
261 | default: | ||
262 | fatal("%s: unsupported key type %s", __func__, key_type(k)); | ||
263 | } | ||
264 | exit(0); | ||
265 | } | ||
266 | |||
267 | static void | ||
268 | do_convert_to_pem(Key *k) | ||
269 | { | ||
270 | switch (key_type_plain(k->type)) { | ||
271 | case KEY_RSA: | ||
272 | if (!PEM_write_RSAPublicKey(stdout, k->rsa)) | ||
273 | fatal("PEM_write_RSAPublicKey failed"); | ||
274 | break; | ||
275 | #if notyet /* OpenSSH 0.9.8 lacks this function */ | ||
276 | case KEY_DSA: | ||
277 | if (!PEM_write_DSAPublicKey(stdout, k->dsa)) | ||
278 | fatal("PEM_write_DSAPublicKey failed"); | ||
279 | break; | ||
280 | #endif | ||
281 | default: | ||
282 | fatal("%s: unsupported key type %s", __func__, key_type(k)); | ||
283 | } | ||
284 | exit(0); | ||
285 | } | ||
286 | |||
287 | static void | ||
288 | do_convert_to(struct passwd *pw) | ||
289 | { | ||
290 | Key *k; | ||
291 | struct stat st; | ||
292 | |||
293 | if (!have_identity) | ||
294 | ask_filename(pw, "Enter file in which the key is"); | ||
295 | if (stat(identity_file, &st) < 0) | ||
296 | fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); | ||
297 | if ((k = key_load_public(identity_file, NULL)) == NULL) { | ||
298 | if ((k = load_identity(identity_file)) == NULL) { | ||
299 | fprintf(stderr, "load failed\n"); | ||
300 | exit(1); | ||
301 | } | ||
302 | } | ||
303 | if (k->type == KEY_RSA1) { | ||
304 | fprintf(stderr, "version 1 keys are not supported\n"); | ||
305 | exit(1); | ||
306 | } | ||
307 | |||
308 | switch (convert_format) { | ||
309 | case FMT_RFC4716: | ||
310 | do_convert_to_ssh2(pw, k); | ||
311 | break; | ||
312 | case FMT_PKCS8: | ||
313 | do_convert_to_pkcs8(k); | ||
314 | break; | ||
315 | case FMT_PEM: | ||
316 | do_convert_to_pem(k); | ||
317 | break; | ||
318 | default: | ||
319 | fatal("%s: unknown key format %d", __func__, convert_format); | ||
320 | } | ||
321 | exit(0); | ||
322 | } | ||
323 | |||
324 | static void | ||
262 | buffer_get_bignum_bits(Buffer *b, BIGNUM *value) | 325 | buffer_get_bignum_bits(Buffer *b, BIGNUM *value) |
263 | { | 326 | { |
264 | u_int bignum_bits = buffer_get_int(b); | 327 | u_int bignum_bits = buffer_get_int(b); |
@@ -396,24 +459,16 @@ get_line(FILE *fp, char *line, size_t len) | |||
396 | } | 459 | } |
397 | 460 | ||
398 | static void | 461 | static void |
399 | do_convert_from_ssh2(struct passwd *pw) | 462 | do_convert_from_ssh2(struct passwd *pw, Key **k, int *private) |
400 | { | 463 | { |
401 | Key *k; | ||
402 | int blen; | 464 | int blen; |
403 | u_int len; | 465 | u_int len; |
404 | char line[1024]; | 466 | char line[1024]; |
405 | u_char blob[8096]; | 467 | u_char blob[8096]; |
406 | char encoded[8096]; | 468 | char encoded[8096]; |
407 | struct stat st; | 469 | int escaped = 0; |
408 | int escaped = 0, private = 0, ok; | ||
409 | FILE *fp; | 470 | FILE *fp; |
410 | 471 | ||
411 | if (!have_identity) | ||
412 | ask_filename(pw, "Enter file in which the key is"); | ||
413 | if (stat(identity_file, &st) < 0) { | ||
414 | perror(identity_file); | ||
415 | exit(1); | ||
416 | } | ||
417 | if ((fp = fopen(identity_file, "r")) == NULL) | 472 | if ((fp = fopen(identity_file, "r")) == NULL) |
418 | fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); | 473 | fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); |
419 | encoded[0] = '\0'; | 474 | encoded[0] = '\0'; |
@@ -423,7 +478,7 @@ do_convert_from_ssh2(struct passwd *pw) | |||
423 | if (strncmp(line, "----", 4) == 0 || | 478 | if (strncmp(line, "----", 4) == 0 || |
424 | strstr(line, ": ") != NULL) { | 479 | strstr(line, ": ") != NULL) { |
425 | if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL) | 480 | if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL) |
426 | private = 1; | 481 | *private = 1; |
427 | if (strstr(line, " END ") != NULL) { | 482 | if (strstr(line, " END ") != NULL) { |
428 | break; | 483 | break; |
429 | } | 484 | } |
@@ -448,26 +503,130 @@ do_convert_from_ssh2(struct passwd *pw) | |||
448 | fprintf(stderr, "uudecode failed.\n"); | 503 | fprintf(stderr, "uudecode failed.\n"); |
449 | exit(1); | 504 | exit(1); |
450 | } | 505 | } |
451 | k = private ? | 506 | *k = *private ? |
452 | do_convert_private_ssh2_from_blob(blob, blen) : | 507 | do_convert_private_ssh2_from_blob(blob, blen) : |
453 | key_from_blob(blob, blen); | 508 | key_from_blob(blob, blen); |
454 | if (k == NULL) { | 509 | if (*k == NULL) { |
455 | fprintf(stderr, "decode blob failed.\n"); | 510 | fprintf(stderr, "decode blob failed.\n"); |
456 | exit(1); | 511 | exit(1); |
457 | } | 512 | } |
458 | ok = private ? | 513 | fclose(fp); |
459 | (k->type == KEY_DSA ? | 514 | } |
460 | PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL) : | 515 | |
461 | PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL)) : | 516 | static void |
462 | key_write(k, stdout); | 517 | do_convert_from_pkcs8(Key **k, int *private) |
518 | { | ||
519 | EVP_PKEY *pubkey; | ||
520 | FILE *fp; | ||
521 | |||
522 | if ((fp = fopen(identity_file, "r")) == NULL) | ||
523 | fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); | ||
524 | if ((pubkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL)) == NULL) { | ||
525 | fatal("%s: %s is not a recognised public key format", __func__, | ||
526 | identity_file); | ||
527 | } | ||
528 | fclose(fp); | ||
529 | switch (EVP_PKEY_type(pubkey->type)) { | ||
530 | case EVP_PKEY_RSA: | ||
531 | *k = key_new(KEY_UNSPEC); | ||
532 | (*k)->type = KEY_RSA; | ||
533 | (*k)->rsa = EVP_PKEY_get1_RSA(pubkey); | ||
534 | break; | ||
535 | case EVP_PKEY_DSA: | ||
536 | *k = key_new(KEY_UNSPEC); | ||
537 | (*k)->type = KEY_DSA; | ||
538 | (*k)->dsa = EVP_PKEY_get1_DSA(pubkey); | ||
539 | break; | ||
540 | default: | ||
541 | fatal("%s: unsupported pubkey type %d", __func__, | ||
542 | EVP_PKEY_type(pubkey->type)); | ||
543 | } | ||
544 | EVP_PKEY_free(pubkey); | ||
545 | return; | ||
546 | } | ||
547 | |||
548 | static void | ||
549 | do_convert_from_pem(Key **k, int *private) | ||
550 | { | ||
551 | FILE *fp; | ||
552 | RSA *rsa; | ||
553 | #ifdef notyet | ||
554 | DSA *dsa; | ||
555 | #endif | ||
556 | |||
557 | if ((fp = fopen(identity_file, "r")) == NULL) | ||
558 | fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); | ||
559 | if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { | ||
560 | *k = key_new(KEY_UNSPEC); | ||
561 | (*k)->type = KEY_RSA; | ||
562 | (*k)->rsa = rsa; | ||
563 | fclose(fp); | ||
564 | return; | ||
565 | } | ||
566 | #if notyet /* OpenSSH 0.9.8 lacks this function */ | ||
567 | rewind(fp); | ||
568 | if ((dsa = PEM_read_DSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { | ||
569 | *k = key_new(KEY_UNSPEC); | ||
570 | (*k)->type = KEY_DSA; | ||
571 | (*k)->dsa = dsa; | ||
572 | fclose(fp); | ||
573 | return; | ||
574 | } | ||
575 | #endif | ||
576 | fatal("%s: unrecognised raw private key format", __func__); | ||
577 | } | ||
578 | |||
579 | static void | ||
580 | do_convert_from(struct passwd *pw) | ||
581 | { | ||
582 | Key *k = NULL; | ||
583 | int private = 0, ok; | ||
584 | struct stat st; | ||
585 | |||
586 | if (!have_identity) | ||
587 | ask_filename(pw, "Enter file in which the key is"); | ||
588 | if (stat(identity_file, &st) < 0) | ||
589 | fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); | ||
590 | |||
591 | switch (convert_format) { | ||
592 | case FMT_RFC4716: | ||
593 | do_convert_from_ssh2(pw, &k, &private); | ||
594 | break; | ||
595 | case FMT_PKCS8: | ||
596 | do_convert_from_pkcs8(&k, &private); | ||
597 | break; | ||
598 | case FMT_PEM: | ||
599 | do_convert_from_pem(&k, &private); | ||
600 | break; | ||
601 | default: | ||
602 | fatal("%s: unknown key format %d", __func__, convert_format); | ||
603 | } | ||
604 | |||
605 | if (!private) | ||
606 | ok = key_write(k, stdout); | ||
607 | if (ok) | ||
608 | fprintf(stdout, "\n"); | ||
609 | else { | ||
610 | switch (k->type) { | ||
611 | case KEY_DSA: | ||
612 | ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, | ||
613 | NULL, 0, NULL, NULL); | ||
614 | break; | ||
615 | case KEY_RSA: | ||
616 | ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, | ||
617 | NULL, 0, NULL, NULL); | ||
618 | break; | ||
619 | default: | ||
620 | fatal("%s: unsupported key type %s", __func__, | ||
621 | key_type(k)); | ||
622 | } | ||
623 | } | ||
624 | |||
463 | if (!ok) { | 625 | if (!ok) { |
464 | fprintf(stderr, "key write failed\n"); | 626 | fprintf(stderr, "key write failed\n"); |
465 | exit(1); | 627 | exit(1); |
466 | } | 628 | } |
467 | key_free(k); | 629 | key_free(k); |
468 | if (!private) | ||
469 | fprintf(stdout, "\n"); | ||
470 | fclose(fp); | ||
471 | exit(0); | 630 | exit(0); |
472 | } | 631 | } |
473 | 632 | ||
@@ -1525,7 +1684,7 @@ usage(void) | |||
1525 | #ifdef ENABLE_PKCS11 | 1684 | #ifdef ENABLE_PKCS11 |
1526 | fprintf(stderr, " -D pkcs11 Download public key from pkcs11 token.\n"); | 1685 | fprintf(stderr, " -D pkcs11 Download public key from pkcs11 token.\n"); |
1527 | #endif | 1686 | #endif |
1528 | fprintf(stderr, " -e Convert OpenSSH to RFC 4716 key file.\n"); | 1687 | fprintf(stderr, " -e Export OpenSSH to foreign format key file.\n"); |
1529 | fprintf(stderr, " -F hostname Find hostname in known hosts file.\n"); | 1688 | fprintf(stderr, " -F hostname Find hostname in known hosts file.\n"); |
1530 | fprintf(stderr, " -f filename Filename of the key file.\n"); | 1689 | fprintf(stderr, " -f filename Filename of the key file.\n"); |
1531 | fprintf(stderr, " -G file Generate candidates for DH-GEX moduli.\n"); | 1690 | fprintf(stderr, " -G file Generate candidates for DH-GEX moduli.\n"); |
@@ -1533,9 +1692,10 @@ usage(void) | |||
1533 | fprintf(stderr, " -H Hash names in known_hosts file.\n"); | 1692 | fprintf(stderr, " -H Hash names in known_hosts file.\n"); |
1534 | fprintf(stderr, " -h Generate host certificate instead of a user certificate.\n"); | 1693 | fprintf(stderr, " -h Generate host certificate instead of a user certificate.\n"); |
1535 | fprintf(stderr, " -I key_id Key identifier to include in certificate.\n"); | 1694 | fprintf(stderr, " -I key_id Key identifier to include in certificate.\n"); |
1536 | fprintf(stderr, " -i Convert RFC 4716 to OpenSSH key file.\n"); | 1695 | fprintf(stderr, " -i Import foreign format to OpenSSH key file.\n"); |
1537 | fprintf(stderr, " -L Print the contents of a certificate.\n"); | 1696 | fprintf(stderr, " -L Print the contents of a certificate.\n"); |
1538 | fprintf(stderr, " -l Show fingerprint of key file.\n"); | 1697 | fprintf(stderr, " -l Show fingerprint of key file.\n"); |
1698 | fprintf(stderr, " -m key_fmt Conversion format for -e/-i (PEM|PKCS8|RFC4716).\n"); | ||
1539 | fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n"); | 1699 | fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n"); |
1540 | fprintf(stderr, " -n name,... User/host principal names to include in certificate\n"); | 1700 | fprintf(stderr, " -n name,... User/host principal names to include in certificate\n"); |
1541 | fprintf(stderr, " -N phrase Provide new passphrase.\n"); | 1701 | fprintf(stderr, " -N phrase Provide new passphrase.\n"); |
@@ -1603,7 +1763,7 @@ main(int argc, char **argv) | |||
1603 | exit(1); | 1763 | exit(1); |
1604 | } | 1764 | } |
1605 | 1765 | ||
1606 | while ((opt = getopt(argc, argv, "degiqpclBHLhvxXyF:b:f:t:D:I:P:N:n:" | 1766 | while ((opt = getopt(argc, argv, "degiqpclBHLhvxXyF:b:f:t:D:I:P:m:N:n:" |
1607 | "O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -1) { | 1767 | "O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -1) { |
1608 | switch (opt) { | 1768 | switch (opt) { |
1609 | case 'b': | 1769 | case 'b': |
@@ -1635,6 +1795,21 @@ main(int argc, char **argv) | |||
1635 | case 'B': | 1795 | case 'B': |
1636 | print_bubblebabble = 1; | 1796 | print_bubblebabble = 1; |
1637 | break; | 1797 | break; |
1798 | case 'm': | ||
1799 | if (strcasecmp(optarg, "RFC4716") == 0 || | ||
1800 | strcasecmp(optarg, "ssh2") == 0) { | ||
1801 | convert_format = FMT_RFC4716; | ||
1802 | break; | ||
1803 | } | ||
1804 | if (strcasecmp(optarg, "PKCS8") == 0) { | ||
1805 | convert_format = FMT_PKCS8; | ||
1806 | break; | ||
1807 | } | ||
1808 | if (strcasecmp(optarg, "PEM") == 0) { | ||
1809 | convert_format = FMT_PEM; | ||
1810 | break; | ||
1811 | } | ||
1812 | fatal("Unsupported conversion format \"%s\"", optarg); | ||
1638 | case 'n': | 1813 | case 'n': |
1639 | cert_principals = optarg; | 1814 | cert_principals = optarg; |
1640 | break; | 1815 | break; |
@@ -1671,7 +1846,7 @@ main(int argc, char **argv) | |||
1671 | case 'e': | 1846 | case 'e': |
1672 | case 'x': | 1847 | case 'x': |
1673 | /* export key */ | 1848 | /* export key */ |
1674 | convert_to_ssh2 = 1; | 1849 | convert_to = 1; |
1675 | break; | 1850 | break; |
1676 | case 'h': | 1851 | case 'h': |
1677 | cert_key_type = SSH2_CERT_TYPE_HOST; | 1852 | cert_key_type = SSH2_CERT_TYPE_HOST; |
@@ -1680,7 +1855,7 @@ main(int argc, char **argv) | |||
1680 | case 'i': | 1855 | case 'i': |
1681 | case 'X': | 1856 | case 'X': |
1682 | /* import key */ | 1857 | /* import key */ |
1683 | convert_from_ssh2 = 1; | 1858 | convert_from = 1; |
1684 | break; | 1859 | break; |
1685 | case 'y': | 1860 | case 'y': |
1686 | print_public = 1; | 1861 | print_public = 1; |
@@ -1796,10 +1971,10 @@ main(int argc, char **argv) | |||
1796 | do_change_passphrase(pw); | 1971 | do_change_passphrase(pw); |
1797 | if (change_comment) | 1972 | if (change_comment) |
1798 | do_change_comment(pw); | 1973 | do_change_comment(pw); |
1799 | if (convert_to_ssh2) | 1974 | if (convert_to) |
1800 | do_convert_to_ssh2(pw); | 1975 | do_convert_to(pw); |
1801 | if (convert_from_ssh2) | 1976 | if (convert_from) |
1802 | do_convert_from_ssh2(pw); | 1977 | do_convert_from(pw); |
1803 | if (print_public) | 1978 | if (print_public) |
1804 | do_print_public(pw); | 1979 | do_print_public(pw); |
1805 | if (rr_hostname != NULL) { | 1980 | if (rr_hostname != NULL) { |