mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Separate key-type enum values for old and new OpenSSH keys.
It's all very well for these two different formats to share a type code as long as we're only loading them and not saving, but as soon as we need to save one or the other, we'll need different type codes after all. This commit introduces the openssh_new_write() function, but for the moment, it always returns failure.
This commit is contained in:
parent
78b8bde7af
commit
79bbf37c9e
48
cmdgen.c
48
cmdgen.c
@ -160,6 +160,10 @@ void help(void)
|
||||
" -O specify output type:\n"
|
||||
" private output PuTTY private key format\n"
|
||||
" private-openssh export OpenSSH private key\n"
|
||||
" private-openssh-pem export OpenSSH private key "
|
||||
"(force old PEM format)\n"
|
||||
" private-openssh-new export OpenSSH private key "
|
||||
"(force new format)\n"
|
||||
" private-sshcom export ssh.com private key\n"
|
||||
" public standard / ssh.com public key\n"
|
||||
" public-openssh OpenSSH public key\n"
|
||||
@ -267,7 +271,8 @@ int main(int argc, char **argv)
|
||||
Filename *infilename = NULL, *outfilename = NULL;
|
||||
enum { NOKEYGEN, RSA1, RSA2, DSA, ECDSA } keytype = NOKEYGEN;
|
||||
char *outfile = NULL, *outfiletmp = NULL;
|
||||
enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH, SSHCOM } outtype = PRIVATE;
|
||||
enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH_PEM,
|
||||
OPENSSH_NEW, SSHCOM } outtype = PRIVATE;
|
||||
int bits = 2048;
|
||||
char *comment = NULL, *origcomment = NULL;
|
||||
int change_passphrase = FALSE;
|
||||
@ -460,8 +465,11 @@ int main(int argc, char **argv)
|
||||
outtype = PRIVATE;
|
||||
else if (!strcmp(p, "fingerprint"))
|
||||
outtype = FP;
|
||||
else if (!strcmp(p, "private-openssh"))
|
||||
outtype = OPENSSH, sshver = 2;
|
||||
else if (!strcmp(p, "private-openssh") ||
|
||||
!strcmp(p, "private-openssh-pem"))
|
||||
outtype = OPENSSH_PEM, 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 {
|
||||
@ -536,7 +544,8 @@ int main(int argc, char **argv)
|
||||
* We must save the private part when generating a new key.
|
||||
*/
|
||||
if (keytype != NOKEYGEN &&
|
||||
(outtype != PRIVATE && outtype != OPENSSH && outtype != SSHCOM)) {
|
||||
(outtype != PRIVATE && outtype != OPENSSH_PEM &&
|
||||
outtype != OPENSSH_NEW && outtype != SSHCOM)) {
|
||||
fprintf(stderr, "puttygen: this would generate a new key but "
|
||||
"discard the private part\n");
|
||||
return 1;
|
||||
@ -590,7 +599,8 @@ int main(int argc, char **argv)
|
||||
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"
|
||||
@ -614,7 +624,8 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
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_PEM) ||
|
||||
(intype == SSH_KEYTYPE_OPENSSH_NEW && outtype == OPENSSH_NEW) ||
|
||||
(intype == SSH_KEYTYPE_SSHCOM && outtype == SSHCOM)) {
|
||||
if (!outfile) {
|
||||
outfile = infile;
|
||||
@ -632,7 +643,8 @@ int main(int argc, char **argv)
|
||||
* 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_PEM ||
|
||||
outtype == OPENSSH_NEW || outtype == SSHCOM) {
|
||||
fprintf(stderr, "puttygen: need to specify an output file\n");
|
||||
return 1;
|
||||
}
|
||||
@ -645,8 +657,11 @@ int main(int argc, char **argv)
|
||||
* 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_PEM ||
|
||||
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;
|
||||
@ -831,7 +846,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
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) {
|
||||
@ -1052,19 +1068,25 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
|
||||
case OPENSSH:
|
||||
case OPENSSH_PEM:
|
||||
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_PEM:
|
||||
real_outtype = SSH_KEYTYPE_OPENSSH_PEM;
|
||||
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) {
|
||||
|
35
import.c
35
import.c
@ -15,8 +15,10 @@
|
||||
int openssh_encrypted(const Filename *filename);
|
||||
struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase,
|
||||
const char **errmsg_p);
|
||||
int openssh_write(const Filename *filename, struct ssh2_userkey *key,
|
||||
char *passphrase);
|
||||
int openssh_pem_write(const Filename *filename, struct ssh2_userkey *key,
|
||||
char *passphrase);
|
||||
int openssh_new_write(const Filename *filename, struct ssh2_userkey *key,
|
||||
char *passphrase);
|
||||
|
||||
int sshcom_encrypted(const Filename *filename, char **comment);
|
||||
struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
|
||||
@ -29,7 +31,9 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
|
||||
*/
|
||||
int import_possible(int type)
|
||||
{
|
||||
if (type == SSH_KEYTYPE_OPENSSH)
|
||||
if (type == SSH_KEYTYPE_OPENSSH_PEM)
|
||||
return 1;
|
||||
if (type == SSH_KEYTYPE_OPENSSH_NEW)
|
||||
return 1;
|
||||
if (type == SSH_KEYTYPE_SSHCOM)
|
||||
return 1;
|
||||
@ -54,7 +58,7 @@ int import_target_type(int type)
|
||||
*/
|
||||
int import_encrypted(const Filename *filename, int type, char **comment)
|
||||
{
|
||||
if (type == SSH_KEYTYPE_OPENSSH) {
|
||||
if (type == SSH_KEYTYPE_OPENSSH_PEM || type == SSH_KEYTYPE_OPENSSH_NEW) {
|
||||
/* OpenSSH doesn't do key comments */
|
||||
*comment = dupstr(filename_to_str(filename));
|
||||
return openssh_encrypted(filename);
|
||||
@ -80,7 +84,7 @@ int import_ssh1(const Filename *filename, int type,
|
||||
struct ssh2_userkey *import_ssh2(const Filename *filename, int type,
|
||||
char *passphrase, const char **errmsg_p)
|
||||
{
|
||||
if (type == SSH_KEYTYPE_OPENSSH)
|
||||
if (type == SSH_KEYTYPE_OPENSSH_PEM || type == SSH_KEYTYPE_OPENSSH_NEW)
|
||||
return openssh_read(filename, passphrase, errmsg_p);
|
||||
if (type == SSH_KEYTYPE_SSHCOM)
|
||||
return sshcom_read(filename, passphrase, errmsg_p);
|
||||
@ -102,8 +106,10 @@ int export_ssh1(const Filename *filename, int type, struct RSAKey *key,
|
||||
int export_ssh2(const Filename *filename, int type,
|
||||
struct ssh2_userkey *key, char *passphrase)
|
||||
{
|
||||
if (type == SSH_KEYTYPE_OPENSSH)
|
||||
return openssh_write(filename, key, passphrase);
|
||||
if (type == SSH_KEYTYPE_OPENSSH_PEM)
|
||||
return openssh_pem_write(filename, key, passphrase);
|
||||
if (type == SSH_KEYTYPE_OPENSSH_NEW)
|
||||
return openssh_new_write(filename, key, passphrase);
|
||||
if (type == SSH_KEYTYPE_SSHCOM)
|
||||
return sshcom_write(filename, key, passphrase);
|
||||
return 0;
|
||||
@ -305,6 +311,11 @@ static int ssh2_read_mpint(void *data, int len, struct mpint_pos *ret)
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Code to read and write OpenSSH private keys.
|
||||
*
|
||||
* These come in two more or less entirely different formats, except
|
||||
* that the base64 wrapper is similar enough to handle with the same
|
||||
* code. Accordingly, there's just one function to load OpenSSH keys
|
||||
* in both formats, but separate functions to write the two formats.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
@ -1263,8 +1274,8 @@ struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase,
|
||||
return retval;
|
||||
}
|
||||
|
||||
int openssh_write(const Filename *filename, struct ssh2_userkey *key,
|
||||
char *passphrase)
|
||||
int openssh_pem_write(const Filename *filename, struct ssh2_userkey *key,
|
||||
char *passphrase)
|
||||
{
|
||||
unsigned char *pubblob, *privblob, *spareblob;
|
||||
int publen, privlen, sparelen = 0;
|
||||
@ -1626,6 +1637,12 @@ int openssh_write(const Filename *filename, struct ssh2_userkey *key,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int openssh_new_write(const Filename *filename, struct ssh2_userkey *key,
|
||||
char *passphrase)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Code to read ssh.com private keys.
|
||||
*/
|
||||
|
4
ssh.h
4
ssh.h
@ -630,7 +630,9 @@ enum {
|
||||
SSH_KEYTYPE_UNOPENABLE,
|
||||
SSH_KEYTYPE_UNKNOWN,
|
||||
SSH_KEYTYPE_SSH1, SSH_KEYTYPE_SSH2,
|
||||
SSH_KEYTYPE_OPENSSH, SSH_KEYTYPE_SSHCOM
|
||||
SSH_KEYTYPE_OPENSSH_PEM,
|
||||
SSH_KEYTYPE_OPENSSH_NEW,
|
||||
SSH_KEYTYPE_SSHCOM
|
||||
};
|
||||
int key_type(const Filename *filename);
|
||||
char *key_type_to_str(int type);
|
||||
|
@ -1157,6 +1157,7 @@ int key_type(const Filename *filename)
|
||||
char buf[32];
|
||||
const char putty2_sig[] = "PuTTY-User-Key-File-";
|
||||
const char sshcom_sig[] = "---- BEGIN SSH2 ENCRYPTED PRIVAT";
|
||||
const char openssh_new_sig[] = "-----BEGIN OPENSSH PRIVATE KEY";
|
||||
const char openssh_sig[] = "-----BEGIN ";
|
||||
int i;
|
||||
|
||||
@ -1173,8 +1174,10 @@ int key_type(const Filename *filename)
|
||||
return SSH_KEYTYPE_SSH1;
|
||||
if (!memcmp(buf, putty2_sig, sizeof(putty2_sig)-1))
|
||||
return SSH_KEYTYPE_SSH2;
|
||||
if (!memcmp(buf, openssh_new_sig, sizeof(openssh_new_sig)-1))
|
||||
return SSH_KEYTYPE_OPENSSH_NEW;
|
||||
if (!memcmp(buf, openssh_sig, sizeof(openssh_sig)-1))
|
||||
return SSH_KEYTYPE_OPENSSH;
|
||||
return SSH_KEYTYPE_OPENSSH_PEM;
|
||||
if (!memcmp(buf, sshcom_sig, sizeof(sshcom_sig)-1))
|
||||
return SSH_KEYTYPE_SSHCOM;
|
||||
return SSH_KEYTYPE_UNKNOWN; /* unrecognised or EOF */
|
||||
@ -1191,7 +1194,8 @@ char *key_type_to_str(int type)
|
||||
case SSH_KEYTYPE_UNKNOWN: return "not a private key"; break;
|
||||
case SSH_KEYTYPE_SSH1: return "SSH-1 private key"; break;
|
||||
case SSH_KEYTYPE_SSH2: return "PuTTY SSH-2 private key"; break;
|
||||
case SSH_KEYTYPE_OPENSSH: return "OpenSSH SSH-2 private key"; break;
|
||||
case SSH_KEYTYPE_OPENSSH_PEM: return "OpenSSH SSH-2 private key (old PEM format)"; break;
|
||||
case SSH_KEYTYPE_OPENSSH_NEW: return "OpenSSH SSH-2 private key (new format)"; break;
|
||||
case SSH_KEYTYPE_SSHCOM: return "ssh.com SSH-2 private key"; break;
|
||||
default: return "INTERNAL ERROR"; break;
|
||||
}
|
||||
|
@ -534,7 +534,9 @@ enum {
|
||||
IDC_BITSSTATIC, IDC_BITS,
|
||||
IDC_ABOUT,
|
||||
IDC_GIVEHELP,
|
||||
IDC_IMPORT, IDC_EXPORT_OPENSSH, IDC_EXPORT_SSHCOM
|
||||
IDC_IMPORT,
|
||||
IDC_EXPORT_OPENSSH_PEM, IDC_EXPORT_OPENSSH_NEW,
|
||||
IDC_EXPORT_SSHCOM
|
||||
};
|
||||
|
||||
static const int nokey_ids[] = { IDC_NOKEY, 0 };
|
||||
@ -579,7 +581,9 @@ void ui_set_state(HWND hwnd, struct MainDlgState *state, int status)
|
||||
EnableMenuItem(state->keymenu, IDC_KEYSSH2ECDSA,
|
||||
MF_ENABLED|MF_BYCOMMAND);
|
||||
EnableMenuItem(state->cvtmenu, IDC_IMPORT, MF_ENABLED|MF_BYCOMMAND);
|
||||
EnableMenuItem(state->cvtmenu, IDC_EXPORT_OPENSSH,
|
||||
EnableMenuItem(state->cvtmenu, IDC_EXPORT_OPENSSH_PEM,
|
||||
MF_GRAYED|MF_BYCOMMAND);
|
||||
EnableMenuItem(state->cvtmenu, IDC_EXPORT_OPENSSH_NEW,
|
||||
MF_GRAYED|MF_BYCOMMAND);
|
||||
EnableMenuItem(state->cvtmenu, IDC_EXPORT_SSHCOM,
|
||||
MF_GRAYED|MF_BYCOMMAND);
|
||||
@ -607,7 +611,9 @@ void ui_set_state(HWND hwnd, struct MainDlgState *state, int status)
|
||||
EnableMenuItem(state->keymenu, IDC_KEYSSH2ECDSA,
|
||||
MF_GRAYED|MF_BYCOMMAND);
|
||||
EnableMenuItem(state->cvtmenu, IDC_IMPORT, MF_GRAYED|MF_BYCOMMAND);
|
||||
EnableMenuItem(state->cvtmenu, IDC_EXPORT_OPENSSH,
|
||||
EnableMenuItem(state->cvtmenu, IDC_EXPORT_OPENSSH_PEM,
|
||||
MF_GRAYED|MF_BYCOMMAND);
|
||||
EnableMenuItem(state->cvtmenu, IDC_EXPORT_OPENSSH_NEW,
|
||||
MF_GRAYED|MF_BYCOMMAND);
|
||||
EnableMenuItem(state->cvtmenu, IDC_EXPORT_SSHCOM,
|
||||
MF_GRAYED|MF_BYCOMMAND);
|
||||
@ -643,7 +649,8 @@ void ui_set_state(HWND hwnd, struct MainDlgState *state, int status)
|
||||
#define do_export_menuitem(x,y) \
|
||||
EnableMenuItem(state->cvtmenu, x, MF_BYCOMMAND | \
|
||||
(import_target_type(y)==type?MF_ENABLED:MF_GRAYED))
|
||||
do_export_menuitem(IDC_EXPORT_OPENSSH, SSH_KEYTYPE_OPENSSH);
|
||||
do_export_menuitem(IDC_EXPORT_OPENSSH_PEM, SSH_KEYTYPE_OPENSSH_PEM);
|
||||
do_export_menuitem(IDC_EXPORT_OPENSSH_NEW, SSH_KEYTYPE_OPENSSH_NEW);
|
||||
do_export_menuitem(IDC_EXPORT_SSHCOM, SSH_KEYTYPE_SSHCOM);
|
||||
#undef do_export_menuitem
|
||||
break;
|
||||
@ -883,8 +890,10 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
|
||||
menu1 = CreateMenu();
|
||||
AppendMenu(menu1, MF_ENABLED, IDC_IMPORT, "&Import key");
|
||||
AppendMenu(menu1, MF_SEPARATOR, 0, 0);
|
||||
AppendMenu(menu1, MF_ENABLED, IDC_EXPORT_OPENSSH,
|
||||
"Export &OpenSSH key");
|
||||
AppendMenu(menu1, MF_ENABLED, IDC_EXPORT_OPENSSH_PEM,
|
||||
"Export &OpenSSH key (old PEM format)");
|
||||
AppendMenu(menu1, MF_ENABLED, IDC_EXPORT_OPENSSH_NEW,
|
||||
"Export &OpenSSH key (new format)");
|
||||
AppendMenu(menu1, MF_ENABLED, IDC_EXPORT_SSHCOM,
|
||||
"Export &ssh.com key");
|
||||
AppendMenu(menu, MF_POPUP | MF_ENABLED, (UINT) menu1,
|
||||
@ -1161,7 +1170,8 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
|
||||
}
|
||||
break;
|
||||
case IDC_SAVE:
|
||||
case IDC_EXPORT_OPENSSH:
|
||||
case IDC_EXPORT_OPENSSH_PEM:
|
||||
case IDC_EXPORT_OPENSSH_NEW:
|
||||
case IDC_EXPORT_SSHCOM:
|
||||
if (HIWORD(wParam) != BN_CLICKED)
|
||||
break;
|
||||
@ -1177,8 +1187,10 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
|
||||
else
|
||||
realtype = SSH_KEYTYPE_SSH1;
|
||||
|
||||
if (LOWORD(wParam) == IDC_EXPORT_OPENSSH)
|
||||
type = SSH_KEYTYPE_OPENSSH;
|
||||
if (LOWORD(wParam) == IDC_EXPORT_OPENSSH_PEM)
|
||||
type = SSH_KEYTYPE_OPENSSH_PEM;
|
||||
else if (LOWORD(wParam) == IDC_EXPORT_OPENSSH_NEW)
|
||||
type = SSH_KEYTYPE_OPENSSH_NEW;
|
||||
else if (LOWORD(wParam) == IDC_EXPORT_SSHCOM)
|
||||
type = SSH_KEYTYPE_SSHCOM;
|
||||
else
|
||||
@ -1453,7 +1465,8 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
|
||||
case IDC_BITS:
|
||||
topic = WINHELP_CTX_puttygen_bits; break;
|
||||
case IDC_IMPORT:
|
||||
case IDC_EXPORT_OPENSSH:
|
||||
case IDC_EXPORT_OPENSSH_PEM:
|
||||
case IDC_EXPORT_OPENSSH_NEW:
|
||||
case IDC_EXPORT_SSHCOM:
|
||||
topic = WINHELP_CTX_puttygen_conversions; break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user