" -O specify output type:\n"
" private output PuTTY private key format\n"
" private-openssh export OpenSSH private key\n"
+ " private-openssh-new export OpenSSH private key "
+ "(force new file format)\n"
" private-sshcom export ssh.com private key\n"
" public standard / ssh.com public key\n"
" public-openssh OpenSSH public key\n"
{
char *infile = NULL;
Filename *infilename = NULL, *outfilename = NULL;
- enum { NOKEYGEN, RSA1, RSA2, DSA, ECDSA } keytype = NOKEYGEN;
+ enum { NOKEYGEN, RSA1, RSA2, DSA, ECDSA, ED25519 } keytype = NOKEYGEN;
char *outfile = NULL, *outfiletmp = NULL;
- enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH, SSHCOM } outtype = PRIVATE;
- int bits = 2048;
+ enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH_AUTO,
+ OPENSSH_NEW, SSHCOM } outtype = PRIVATE;
+ int bits = -1;
char *comment = NULL, *origcomment = NULL;
int change_passphrase = FALSE;
int errs = FALSE, nogo = FALSE;
keytype = DSA, sshver = 2;
else if (!strcmp(p, "ecdsa"))
keytype = ECDSA, sshver = 2;
+ else if (!strcmp(p, "ed25519"))
+ keytype = ED25519, sshver = 2;
else {
fprintf(stderr,
"puttygen: unknown key type `%s'\n", p);
else if (!strcmp(p, "fingerprint"))
outtype = FP;
else if (!strcmp(p, "private-openssh"))
- outtype = OPENSSH, sshver = 2;
+ outtype = OPENSSH_AUTO, sshver = 2;
+ else if (!strcmp(p, "private-openssh-new"))
+ outtype = OPENSSH_NEW, sshver = 2;
else if (!strcmp(p, "private-sshcom"))
outtype = SSHCOM, sshver = 2;
else {
}
}
+ if (bits == -1) {
+ /*
+ * No explicit key size was specified. Default varies
+ * depending on key type.
+ */
+ switch (keytype) {
+ case ECDSA:
+ bits = 384;
+ break;
+ case ED25519:
+ bits = 256;
+ break;
+ default:
+ bits = 2048;
+ break;
+ }
+ }
+
if (keytype == ECDSA && (bits != 256 && bits != 384 && bits != 521)) {
fprintf(stderr, "puttygen: invalid bits for ECDSA, choose 256, 384 or 521\n");
errs = TRUE;
}
+ if (keytype == ED25519 && (bits != 256)) {
+ fprintf(stderr, "puttygen: invalid bits for ED25519, choose 256\n");
+ errs = TRUE;
+ }
+
if (errs)
return 1;
* We must save the private part when generating a new key.
*/
if (keytype != NOKEYGEN &&
- (outtype != PRIVATE && outtype != OPENSSH && outtype != SSHCOM)) {
+ (outtype != PRIVATE && outtype != OPENSSH_AUTO &&
+ outtype != OPENSSH_NEW && outtype != SSHCOM)) {
fprintf(stderr, "puttygen: this would generate a new key but "
"discard the private part\n");
return 1;
break;
case SSH_KEYTYPE_SSH2:
- case SSH_KEYTYPE_OPENSSH:
+ case SSH_KEYTYPE_OPENSSH_PEM:
+ case SSH_KEYTYPE_OPENSSH_NEW:
case SSH_KEYTYPE_SSHCOM:
if (sshver == 1) {
fprintf(stderr, "puttygen: conversion from SSH-2 to SSH-1 keys"
}
sshver = 2;
break;
+
+ case SSH_KEYTYPE_OPENSSH_AUTO:
+ default:
+ assert(0 && "Should never see these types on an input file");
}
}
*/
if ((intype == SSH_KEYTYPE_SSH1 && outtype == PRIVATE) ||
(intype == SSH_KEYTYPE_SSH2 && outtype == PRIVATE) ||
- (intype == SSH_KEYTYPE_OPENSSH && outtype == OPENSSH) ||
+ (intype == SSH_KEYTYPE_OPENSSH_PEM && outtype == OPENSSH_AUTO) ||
+ (intype == SSH_KEYTYPE_OPENSSH_NEW && outtype == OPENSSH_NEW) ||
(intype == SSH_KEYTYPE_SSHCOM && outtype == SSHCOM)) {
if (!outfile) {
outfile = infile;
* Bomb out rather than automatically choosing to write
* a private key file to stdout.
*/
- if (outtype==PRIVATE || outtype==OPENSSH || outtype==SSHCOM) {
+ if (outtype == PRIVATE || outtype == OPENSSH_AUTO ||
+ outtype == OPENSSH_NEW || outtype == SSHCOM) {
fprintf(stderr, "puttygen: need to specify an output file\n");
return 1;
}
* out a private key format, or (b) the entire input key file
* is encrypted.
*/
- if (outtype == PRIVATE || outtype == OPENSSH || outtype == SSHCOM ||
- intype == SSH_KEYTYPE_OPENSSH || intype == SSH_KEYTYPE_SSHCOM)
+ if (outtype == PRIVATE || outtype == OPENSSH_AUTO ||
+ outtype == OPENSSH_NEW || outtype == SSHCOM ||
+ intype == SSH_KEYTYPE_OPENSSH_PEM ||
+ intype == SSH_KEYTYPE_OPENSSH_NEW ||
+ intype == SSH_KEYTYPE_SSHCOM)
load_encrypted = TRUE;
else
load_encrypted = FALSE;
strftime(default_comment, 30, "dsa-key-%Y%m%d", &tm);
else if (keytype == ECDSA)
strftime(default_comment, 30, "ecdsa-key-%Y%m%d", &tm);
+ else if (keytype == ED25519)
+ strftime(default_comment, 30, "ed25519-key-%Y%m%d", &tm);
else
strftime(default_comment, 30, "rsa-key-%Y%m%d", &tm);
ssh2key->alg = &ssh_ecdsa_nistp521;
}
ssh1key = NULL;
+ } else if (keytype == ED25519) {
+ struct ec_key *ec = snew(struct ec_key);
+ ec_edgenerate(ec, bits, progressfn, &prog);
+ ssh2key = snew(struct ssh2_userkey);
+ ssh2key->data = ec;
+ ssh2key->alg = &ssh_ecdsa_ed25519;
+ ssh1key = NULL;
} else {
struct RSAKey *rsakey = snew(struct RSAKey);
rsa_generate(rsakey, bits, progressfn, &prog);
}
break;
- case SSH_KEYTYPE_OPENSSH:
+ case SSH_KEYTYPE_OPENSSH_PEM:
+ case SSH_KEYTYPE_OPENSSH_NEW:
case SSH_KEYTYPE_SSHCOM:
ssh2key = import_ssh2(infilename, intype, passphrase, &error);
if (ssh2key) {
}
break;
- case OPENSSH:
+ case OPENSSH_AUTO:
+ case OPENSSH_NEW:
case SSHCOM:
assert(sshver == 2);
assert(ssh2key);
random_ref(); /* both foreign key types require randomness,
* for IV or padding */
switch (outtype) {
- case OPENSSH:
- real_outtype = SSH_KEYTYPE_OPENSSH;
+ case OPENSSH_AUTO:
+ real_outtype = SSH_KEYTYPE_OPENSSH_AUTO;
+ break;
+ case OPENSSH_NEW:
+ real_outtype = SSH_KEYTYPE_OPENSSH_NEW;
break;
case SSHCOM:
real_outtype = SSH_KEYTYPE_SSHCOM;
break;
+ default:
+ assert(0 && "control flow goof");
}
ret = export_ssh2(outfilename, real_outtype, ssh2key, passphrase);
if (!ret) {