i += 4;
/* Now the serious stuff. An ordinary SSH-1 public key. */
- j = makekey(buf + i, len, key, NULL, 1);
+ j = makekey(buf + i, len - i, key, NULL, 1);
if (j < 0)
goto end; /* overran */
i += j;
NULL, NULL, NULL
};
-const struct ssh_signkey *find_pubkey_alg(const char *name)
+const struct ssh_signkey *find_pubkey_alg_len(int namelen, const char *name)
{
- if (!strcmp(name, "ssh-rsa"))
+ if (match_ssh_id(namelen, name, "ssh-rsa"))
return &ssh_rsa;
- else if (!strcmp(name, "ssh-dss"))
+ else if (match_ssh_id(namelen, name, "ssh-dss"))
return &ssh_dss;
- else if (!strcmp(name, "ecdsa-sha2-nistp256"))
+ else if (match_ssh_id(namelen, name, "ecdsa-sha2-nistp256"))
return &ssh_ecdsa_nistp256;
- else if (!strcmp(name, "ecdsa-sha2-nistp384"))
+ else if (match_ssh_id(namelen, name, "ecdsa-sha2-nistp384"))
return &ssh_ecdsa_nistp384;
- else if (!strcmp(name, "ecdsa-sha2-nistp521"))
+ else if (match_ssh_id(namelen, name, "ecdsa-sha2-nistp521"))
return &ssh_ecdsa_nistp521;
+ else if (match_ssh_id(namelen, name, "ssh-ed25519"))
+ return &ssh_ecdsa_ed25519;
else
return NULL;
}
+const struct ssh_signkey *find_pubkey_alg(const char *name)
+{
+ return find_pubkey_alg_len(strlen(name), name);
+}
+
struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
char *passphrase, const char **errorstr)
{
goto error;
}
sfree(public_blob);
+ smemclr(private_blob, private_blob_len);
sfree(private_blob);
sfree(encryption);
if (errorstr)
sfree(mac);
if (public_blob)
sfree(public_blob);
- if (private_blob)
- sfree(private_blob);
+ if (private_blob) {
+ smemclr(private_blob, private_blob_len);
+ sfree(private_blob);
+ }
if (errorstr)
*errorstr = error;
return ret;
int public_blob_len;
int i;
const char *error = NULL;
- char *comment;
+ char *comment = NULL;
public_blob = NULL;
goto error;
/* Select key algorithm structure. */
alg = find_pubkey_alg(b);
+ sfree(b);
if (!alg) {
- sfree(b);
goto error;
}
- sfree(b);
/* Read the Encryption header line. */
if (!read_header(fp, header) || 0 != strcmp(header, "Encryption"))
sfree(public_blob);
if (errorstr)
*errorstr = error;
+ if (comment && commentptr) {
+ sfree(comment);
+ *commentptr = NULL;
+ }
return NULL;
}
}
fp = f_open(filename, "w", TRUE);
- if (!fp)
- return 0;
+ if (!fp) {
+ sfree(pub_blob);
+ smemclr(priv_blob, priv_blob_len);
+ sfree(priv_blob);
+ smemclr(priv_blob_encrypted, priv_blob_len);
+ sfree(priv_blob_encrypted);
+ return 0;
+ }
fprintf(fp, "PuTTY-User-Key-File-2: %s\n", key->alg->name);
fprintf(fp, "Encryption: %s\n", cipherstr);
fprintf(fp, "Comment: %s\n", key->comment);
sfree(pub_blob);
smemclr(priv_blob, priv_blob_len);
sfree(priv_blob);
+ smemclr(priv_blob_encrypted, priv_blob_len);
sfree(priv_blob_encrypted);
return 1;
}
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;
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 */
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;
+ /*
+ * This function is called with a key type derived from
+ * looking at an actual key file, so the output-only type
+ * OPENSSH_AUTO should never get here, and is much an INTERNAL
+ * ERROR as a code we don't even understand.
+ */
+ case SSH_KEYTYPE_OPENSSH_AUTO: return "INTERNAL ERROR (OPENSSH_AUTO)"; break;
default: return "INTERNAL ERROR"; break;
}
}