int attempts;
char *comment;
struct PassphraseProcStruct pps;
- int ver;
+ int type;
int original_pass;
- ver = keyfile_version(filename);
- if (ver == 0) {
- MessageBox(NULL, "Couldn't load private key.", APPNAME,
- MB_OK | MB_ICONERROR);
+ type = key_type(filename);
+ if (type != SSH_KEYTYPE_SSH1 && type != SSH_KEYTYPE_SSH2) {
+ char msg[256];
+ sprintf(msg, "Couldn't load this key (%s)", key_type_to_str(type));
+ MessageBox(NULL, msg, APPNAME, MB_OK | MB_ICONERROR);
return;
}
unsigned char *keylist, *p;
int i, nkeys, bloblen;
- if (ver == 1) {
+ if (type == SSH_KEYTYPE_SSH1) {
if (!rsakey_pubblob(filename, &blob, &bloblen)) {
MessageBox(NULL, "Couldn't load private key.", APPNAME,
MB_OK | MB_ICONERROR);
return;
}
/* Now skip over public blob */
- if (ver == 1)
+ if (type == SSH_KEYTYPE_SSH1)
p += rsa_public_blob_len(p);
else
p += 4 + GET_32BIT(p);
sfree(blob);
}
- if (ver == 1)
+ if (type == SSH_KEYTYPE_SSH1)
needs_pass = rsakey_encrypted(filename, &comment);
else
needs_pass = ssh2_userkey_encrypted(filename, &comment);
attempts = 0;
- if (ver == 1)
+ if (type == SSH_KEYTYPE_SSH1)
rkey = smalloc(sizeof(*rkey));
pps.passphrase = passphrase;
pps.comment = comment;
if (!dlgret) {
if (comment)
sfree(comment);
- if (ver == 1)
+ if (type == SSH_KEYTYPE_SSH1)
sfree(rkey);
return; /* operation cancelled */
}
}
} else
*passphrase = '\0';
- if (ver == 1)
+ if (type == SSH_KEYTYPE_SSH1)
ret = loadrsakey(filename, rkey, passphrase);
else {
skey = ssh2_load_userkey(filename, passphrase);
if (ret == 0) {
MessageBox(NULL, "Couldn't load private key.", APPNAME,
MB_OK | MB_ICONERROR);
- if (ver == 1)
+ if (type == SSH_KEYTYPE_SSH1)
sfree(rkey);
return;
}
- if (ver == 1) {
+ if (type == SSH_KEYTYPE_SSH1) {
if (already_running) {
unsigned char *request, *response;
void *vresponse;
if (prompt_keyfile(hwnd, "Load private key:", filename, 0)) {
char passphrase[PASSPHRASE_MAXLEN];
int needs_pass;
- int ver;
+ int type;
int ret;
char *comment;
struct PassphraseProcStruct pps;
struct RSAKey newkey1;
struct ssh2_userkey *newkey2 = NULL;
- ver = keyfile_version(filename);
- if (ver == 0) {
- MessageBox(NULL, "Couldn't load private key.",
+ type = key_type(filename);
+ if (type != SSH_KEYTYPE_SSH1 && type != SSH_KEYTYPE_SSH2) {
+ char msg[256];
+ sprintf(msg, "Couldn't load private key (%s)",
+ key_type_to_str(type));
+ MessageBox(NULL, msg,
"PuTTYgen Error", MB_OK | MB_ICONERROR);
break;
}
comment = NULL;
- if (ver == 1)
+ if (type == SSH_KEYTYPE_SSH1)
needs_pass = rsakey_encrypted(filename, &comment);
else
needs_pass =
}
} else
*passphrase = '\0';
- if (ver == 1)
+ if (type == SSH_KEYTYPE_SSH1)
ret =
loadrsakey(filename, &newkey1, passphrase);
else {
passphrase);
SetDlgItemText(hwnd, IDC_PASSPHRASE2EDIT,
passphrase);
- if (ver == 1) {
+ if (type == SSH_KEYTYPE_SSH1) {
char buf[128];
char *savecomment;
}
if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
char *comment = NULL;
+ int type;
+ char msgbuf[256];
if (flags & FLAG_VERBOSE)
c_write_str("Trying public key authentication.\r\n");
+ sprintf(msgbuf, "Trying public key \"%.200s\"", cfg.keyfile);
+ logevent(msgbuf);
+ type = key_type(cfg.keyfile);
+ if (type != SSH_KEYTYPE_SSH1) {
+ sprintf(msgbuf, "Key is of wrong type (%s)",
+ key_type_to_str(type));
+ logevent(msgbuf);
+ c_write_str(msgbuf);
+ c_write_str("\r\n");
+ tried_publickey = 1;
+ continue;
+ }
if (!rsakey_encrypted(cfg.keyfile, &comment)) {
if (flags & FLAG_VERBOSE)
c_write_str("No passphrase required.\r\n");
kbd_inter_running = FALSE;
/* Load the pub half of cfg.keyfile so we notice if it's in Pageant */
if (*cfg.keyfile) {
- publickey_blob = ssh2_userkey_loadpub(cfg.keyfile, NULL,
- &publickey_bloblen);
+ int keytype;
+ logeventf("Reading private key file \"%.150s\"", cfg.keyfile);
+ keytype = key_type(cfg.keyfile);
+ if (keytype == SSH_KEYTYPE_SSH2)
+ publickey_blob = ssh2_userkey_loadpub(cfg.keyfile, NULL,
+ &publickey_bloblen);
+ else {
+ char msgbuf[256];
+ logeventf("Unable to use this key file (%s)",
+ key_type_to_str(keytype));
+ sprintf(msgbuf, "Unable to use key file \"%.150s\" (%s)\r\n",
+ cfg.keyfile, key_type_to_str(keytype));
+ c_write_str(msgbuf);
+ publickey_blob = NULL;
+ }
} else
publickey_blob = NULL;
}
}
- if (!method && can_pubkey && *cfg.keyfile
+ if (!method && can_pubkey && publickey_blob
&& !tried_pubkey_config) {
unsigned char *pub_blob;
char *algorithm, *comment;
int ssh2_save_userkey(char *filename, struct ssh2_userkey *key,
char *passphrase);
-int keyfile_version(char *filename);
+enum {
+ SSH_KEYTYPE_UNOPENABLE,
+ SSH_KEYTYPE_UNKNOWN,
+ SSH_KEYTYPE_SSH1, SSH_KEYTYPE_SSH2,
+ SSH_KEYTYPE_OPENSSH, SSH_KEYTYPE_SSHCOM
+};
+int key_type(char *filename);
+char *key_type_to_str(int type);
void des3_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len);
void des3_encrypt_pubkey(unsigned char *key, unsigned char *blk, int len);
}
/* ----------------------------------------------------------------------
- * A function to determine which version of SSH to try on a private
- * key file. Returns 0 on failure, 1 or 2 on success.
+ * A function to determine the type of a private key file. Returns
+ * 0 on failure, 1 or 2 on success.
*/
-int keyfile_version(char *filename)
+int key_type(char *filename)
{
FILE *fp;
+ char buf[32];
+ const char putty2_sig[] = "PuTTY-User-Key-File-";
+ const char sshcom_sig[] = "---- BEGIN SSH2 ENCRYPTED PRIVAT";
+ const char openssh_sig[] = "-----BEGIN ";
int i;
fp = fopen(filename, "r");
if (!fp)
- return 0;
- i = fgetc(fp);
+ return SSH_KEYTYPE_UNOPENABLE;
+ i = fread(buf, 1, sizeof(buf), fp);
fclose(fp);
- if (i == 'S')
- return 1; /* "SSH PRIVATE KEY FORMAT" etc */
- if (i == 'P') /* "PuTTY-User-Key-File" etc */
- return 2;
- return 0; /* unrecognised or EOF */
+ if (i < 0)
+ return SSH_KEYTYPE_UNOPENABLE;
+ if (i < 32)
+ return SSH_KEYTYPE_UNKNOWN;
+ if (!memcmp(buf, rsa_signature, sizeof(rsa_signature)-1))
+ return SSH_KEYTYPE_SSH1;
+ if (!memcmp(buf, putty2_sig, sizeof(putty2_sig)-1))
+ return SSH_KEYTYPE_SSH2;
+ if (!memcmp(buf, openssh_sig, sizeof(openssh_sig)-1))
+ return SSH_KEYTYPE_OPENSSH;
+ if (!memcmp(buf, sshcom_sig, sizeof(sshcom_sig)-1))
+ return SSH_KEYTYPE_SSHCOM;
+ return SSH_KEYTYPE_UNKNOWN; /* unrecognised or EOF */
+}
+
+/*
+ * Convert the type word to a string, for `wrong type' error
+ * messages.
+ */
+char *key_type_to_str(int type)
+{
+ switch (type) {
+ case SSH_KEYTYPE_UNOPENABLE: return "unable to open file"; break;
+ case SSH_KEYTYPE_UNKNOWN: return "not a private key"; break;
+ case SSH_KEYTYPE_SSH1: return "SSH1 private key"; break;
+ case SSH_KEYTYPE_SSH2: return "PuTTY SSH2 private key"; break;
+ case SSH_KEYTYPE_OPENSSH: return "OpenSSH SSH2 private key"; break;
+ case SSH_KEYTYPE_SSHCOM: return "ssh.com SSH2 private key"; break;
+ default: return "INTERNAL ERROR"; break;
+ }
}