- will now display a reason when it fails to load a key
- uses existing error return from native keys
- import.c had a lot of error descriptions which weren't going anywhere;
since the strings are probably taking up space in the binary, we
may as well use them
[originally from svn r5408]
case SSH_KEYTYPE_OPENSSH:
case SSH_KEYTYPE_SSHCOM:
case SSH_KEYTYPE_OPENSSH:
case SSH_KEYTYPE_SSHCOM:
- ssh2key = import_ssh2(&infilename, intype, passphrase);
- if (ssh2key && ssh2key != SSH2_WRONG_PASSPHRASE)
- error = NULL;
- else if (!error) {
- if (ssh2key == SSH2_WRONG_PASSPHRASE)
- error = "wrong passphrase";
+ ssh2key = import_ssh2(&infilename, intype, passphrase, &error);
+ if (ssh2key) {
+ if (ssh2key != SSH2_WRONG_PASSPHRASE)
+ error = NULL;
- error = "unknown error";
- }
+ error = "wrong passphrase";
+ } else if (!error)
+ error = "unknown error";
((unsigned long)(unsigned char)(cp)[3]))
int openssh_encrypted(const Filename *filename);
((unsigned long)(unsigned char)(cp)[3]))
int openssh_encrypted(const Filename *filename);
-struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase);
+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 sshcom_encrypted(const Filename *filename, char **comment);
int openssh_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);
+struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
+ const char **errmsg_p);
int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
char *passphrase);
int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
char *passphrase);
* Import an SSH1 key.
*/
int import_ssh1(const Filename *filename, int type,
* Import an SSH1 key.
*/
int import_ssh1(const Filename *filename, int type,
- struct RSAKey *key, char *passphrase)
+ struct RSAKey *key, char *passphrase, const char **errmsg_p)
* Import an SSH2 key.
*/
struct ssh2_userkey *import_ssh2(const Filename *filename, int type,
* Import an SSH2 key.
*/
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)
- return openssh_read(filename, passphrase);
+ return openssh_read(filename, passphrase, errmsg_p);
if (type == SSH_KEYTYPE_SSHCOM)
if (type == SSH_KEYTYPE_SSHCOM)
- return sshcom_read(filename, passphrase);
+ return sshcom_read(filename, passphrase, errmsg_p);
int keyblob_len, keyblob_size;
};
int keyblob_len, keyblob_size;
};
-static struct openssh_key *load_openssh_key(const Filename *filename)
+static struct openssh_key *load_openssh_key(const Filename *filename,
+ const char **errmsg_p)
{
struct openssh_key *ret;
FILE *fp;
{
struct openssh_key *ret;
FILE *fp;
fp = f_open(*filename, "r");
if (!fp) {
fp = f_open(*filename, "r");
if (!fp) {
- errmsg = "Unable to open key file";
+ errmsg = "unable to open key file";
goto error;
}
if (!fgets(buffer, sizeof(buffer), fp) ||
0 != strncmp(buffer, "-----BEGIN ", 11) ||
0 != strcmp(buffer+strlen(buffer)-17, "PRIVATE KEY-----\n")) {
goto error;
}
if (!fgets(buffer, sizeof(buffer), fp) ||
0 != strncmp(buffer, "-----BEGIN ", 11) ||
0 != strcmp(buffer+strlen(buffer)-17, "PRIVATE KEY-----\n")) {
- errmsg = "File does not begin with OpenSSH key header";
+ errmsg = "file does not begin with OpenSSH key header";
goto error;
}
if (!strcmp(buffer, "-----BEGIN RSA PRIVATE KEY-----\n"))
goto error;
}
if (!strcmp(buffer, "-----BEGIN RSA PRIVATE KEY-----\n"))
else if (!strcmp(buffer, "-----BEGIN DSA PRIVATE KEY-----\n"))
ret->type = OSSH_DSA;
else {
else if (!strcmp(buffer, "-----BEGIN DSA PRIVATE KEY-----\n"))
ret->type = OSSH_DSA;
else {
- errmsg = "Unrecognised key type";
+ errmsg = "unrecognised key type";
goto error;
}
headers_done = 0;
while (1) {
if (!fgets(buffer, sizeof(buffer), fp)) {
goto error;
}
headers_done = 0;
while (1) {
if (!fgets(buffer, sizeof(buffer), fp)) {
- errmsg = "Unexpected end of file";
+ errmsg = "unexpected end of file";
goto error;
}
if (0 == strncmp(buffer, "-----END ", 9) &&
goto error;
}
if (0 == strncmp(buffer, "-----END ", 9) &&
break; /* done */
if ((p = strchr(buffer, ':')) != NULL) {
if (headers_done) {
break; /* done */
if ((p = strchr(buffer, ':')) != NULL) {
if (headers_done) {
- errmsg = "Header found in body of key data";
+ errmsg = "header found in body of key data";
goto error;
}
*p++ = '\0';
goto error;
}
*p++ = '\0';
int i, j;
if (strncmp(p, "DES-EDE3-CBC,", 13)) {
int i, j;
if (strncmp(p, "DES-EDE3-CBC,", 13)) {
- errmsg = "Ciphers other than DES-EDE3-CBC not supported";
+ errmsg = "ciphers other than DES-EDE3-CBC not supported";
- errmsg = "Expected 16-digit iv in DEK-Info";
+ errmsg = "expected 16-digit iv in DEK-Info";
len = base64_decode_atom(base64_bit, out);
if (len <= 0) {
len = base64_decode_atom(base64_bit, out);
if (len <= 0) {
- errmsg = "Invalid base64 encoding";
+ errmsg = "invalid base64 encoding";
}
if (ret->keyblob_len == 0 || !ret->keyblob) {
}
if (ret->keyblob_len == 0 || !ret->keyblob) {
- errmsg = "Key body not present";
+ errmsg = "key body not present";
goto error;
}
if (ret->encrypted && ret->keyblob_len % 8 != 0) {
goto error;
}
if (ret->encrypted && ret->keyblob_len % 8 != 0) {
- errmsg = "Encrypted key blob is not a multiple of cipher block size";
+ errmsg = "encrypted key blob is not a multiple of cipher block size";
goto error;
}
memset(buffer, 0, sizeof(buffer));
memset(base64_bit, 0, sizeof(base64_bit));
goto error;
}
memset(buffer, 0, sizeof(buffer));
memset(base64_bit, 0, sizeof(base64_bit));
+ if (errmsg_p) *errmsg_p = NULL;
memset(&ret, 0, sizeof(ret));
sfree(ret);
}
memset(&ret, 0, sizeof(ret));
sfree(ret);
}
+ if (errmsg_p) *errmsg_p = errmsg;
return NULL;
}
int openssh_encrypted(const Filename *filename)
{
return NULL;
}
int openssh_encrypted(const Filename *filename)
{
- struct openssh_key *key = load_openssh_key(filename);
+ struct openssh_key *key = load_openssh_key(filename, NULL);
-struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase)
+struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase,
+ const char **errmsg_p)
- struct openssh_key *key = load_openssh_key(filename);
+ struct openssh_key *key = load_openssh_key(filename, errmsg_p);
struct ssh2_userkey *retkey;
unsigned char *p;
int ret, id, len, flags;
struct ssh2_userkey *retkey;
unsigned char *p;
int ret, id, len, flags;
* this is some sort of version indication).
*/
if (len != 1 || p[0] != 0) {
* this is some sort of version indication).
*/
if (len != 1 || p[0] != 0) {
- errmsg = "Version number mismatch";
+ errmsg = "version number mismatch";
goto error;
}
} else if (key->type == OSSH_RSA) {
goto error;
}
} else if (key->type == OSSH_RSA) {
sfree(key->keyblob);
memset(&key, 0, sizeof(key));
sfree(key);
sfree(key->keyblob);
memset(&key, 0, sizeof(key));
sfree(key);
+ if (errmsg_p) *errmsg_p = errmsg;
int keyblob_len, keyblob_size;
};
int keyblob_len, keyblob_size;
};
-static struct sshcom_key *load_sshcom_key(const Filename *filename)
+static struct sshcom_key *load_sshcom_key(const Filename *filename,
+ const char **errmsg_p)
{
struct sshcom_key *ret;
FILE *fp;
{
struct sshcom_key *ret;
FILE *fp;
fp = f_open(*filename, "r");
if (!fp) {
fp = f_open(*filename, "r");
if (!fp) {
- errmsg = "Unable to open key file";
+ errmsg = "unable to open key file";
goto error;
}
if (!fgets(buffer, sizeof(buffer), fp) ||
0 != strcmp(buffer, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n")) {
goto error;
}
if (!fgets(buffer, sizeof(buffer), fp) ||
0 != strcmp(buffer, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n")) {
- errmsg = "File does not begin with ssh.com key header";
+ errmsg = "file does not begin with ssh.com key header";
goto error;
}
headers_done = 0;
while (1) {
if (!fgets(buffer, sizeof(buffer), fp)) {
goto error;
}
headers_done = 0;
while (1) {
if (!fgets(buffer, sizeof(buffer), fp)) {
- errmsg = "Unexpected end of file";
+ errmsg = "unexpected end of file";
goto error;
}
if (!strcmp(buffer, "---- END SSH2 ENCRYPTED PRIVATE KEY ----\n"))
break; /* done */
if ((p = strchr(buffer, ':')) != NULL) {
if (headers_done) {
goto error;
}
if (!strcmp(buffer, "---- END SSH2 ENCRYPTED PRIVATE KEY ----\n"))
break; /* done */
if ((p = strchr(buffer, ':')) != NULL) {
if (headers_done) {
- errmsg = "Header found in body of key data";
+ errmsg = "header found in body of key data";
goto error;
}
*p++ = '\0';
goto error;
}
*p++ = '\0';
while ((len = strlen(p)) > (int)(sizeof(buffer) - (p-buffer) -1) ||
p[len-1] != '\n' || p[len-2] == '\\') {
if (len > (int)((p-buffer) + sizeof(buffer)-2)) {
while ((len = strlen(p)) > (int)(sizeof(buffer) - (p-buffer) -1) ||
p[len-1] != '\n' || p[len-2] == '\\') {
if (len > (int)((p-buffer) + sizeof(buffer)-2)) {
- errmsg = "Header line too long to deal with";
+ errmsg = "header line too long to deal with";
goto error;
}
if (!fgets(p+len-2, sizeof(buffer)-(p-buffer)-(len-2), fp)) {
goto error;
}
if (!fgets(p+len-2, sizeof(buffer)-(p-buffer)-(len-2), fp)) {
- errmsg = "Unexpected end of file";
+ errmsg = "unexpected end of file";
len = base64_decode_atom(base64_bit, out);
if (len <= 0) {
len = base64_decode_atom(base64_bit, out);
if (len <= 0) {
- errmsg = "Invalid base64 encoding";
+ errmsg = "invalid base64 encoding";
}
if (ret->keyblob_len == 0 || !ret->keyblob) {
}
if (ret->keyblob_len == 0 || !ret->keyblob) {
- errmsg = "Key body not present";
+ errmsg = "key body not present";
+ if (errmsg_p) *errmsg_p = NULL;
memset(&ret, 0, sizeof(ret));
sfree(ret);
}
memset(&ret, 0, sizeof(ret));
sfree(ret);
}
+ if (errmsg_p) *errmsg_p = errmsg;
return NULL;
}
int sshcom_encrypted(const Filename *filename, char **comment)
{
return NULL;
}
int sshcom_encrypted(const Filename *filename, char **comment)
{
- struct sshcom_key *key = load_sshcom_key(filename);
+ struct sshcom_key *key = load_sshcom_key(filename, NULL);
int pos, len, answer;
*comment = NULL;
int pos, len, answer;
*comment = NULL;
-struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase)
+struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
+ const char **errmsg_p)
- struct sshcom_key *key = load_sshcom_key(filename);
+ struct sshcom_key *key = load_sshcom_key(filename, errmsg_p);
char *errmsg;
int pos, len;
const char prefix_rsa[] = "if-modn{sign{rsa";
char *errmsg;
int pos, len;
const char prefix_rsa[] = "if-modn{sign{rsa";
* Check magic number.
*/
if (GET_32BIT(key->keyblob) != SSHCOM_MAGIC_NUMBER) {
* Check magic number.
*/
if (GET_32BIT(key->keyblob) != SSHCOM_MAGIC_NUMBER) {
- errmsg = "Key does not begin with magic number";
+ errmsg = "key does not begin with magic number";
pos = 8;
if (key->keyblob_len < pos+4 ||
(len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
pos = 8;
if (key->keyblob_len < pos+4 ||
(len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
- errmsg = "Key blob does not contain a key type string";
+ errmsg = "key blob does not contain a key type string";
goto error;
}
if (len > sizeof(prefix_rsa) - 1 &&
goto error;
}
if (len > sizeof(prefix_rsa) - 1 &&
!memcmp(key->keyblob+pos+4, prefix_dsa, sizeof(prefix_dsa) - 1)) {
type = DSA;
} else {
!memcmp(key->keyblob+pos+4, prefix_dsa, sizeof(prefix_dsa) - 1)) {
type = DSA;
} else {
- errmsg = "Key is of unknown type";
+ errmsg = "key is of unknown type";
goto error;
}
pos += 4+len;
goto error;
}
pos += 4+len;
*/
if (key->keyblob_len < pos+4 ||
(len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
*/
if (key->keyblob_len < pos+4 ||
(len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
- errmsg = "Key blob does not contain a cipher type string";
+ errmsg = "key blob does not contain a cipher type string";
goto error;
}
if (len == 4 && !memcmp(key->keyblob+pos+4, "none", 4))
goto error;
}
if (len == 4 && !memcmp(key->keyblob+pos+4, "none", 4))
else if (len == 8 && !memcmp(key->keyblob+pos+4, "3des-cbc", 8))
encrypted = 1;
else {
else if (len == 8 && !memcmp(key->keyblob+pos+4, "3des-cbc", 8))
encrypted = 1;
else {
- errmsg = "Key encryption is of unknown type";
+ errmsg = "key encryption is of unknown type";
goto error;
}
pos += 4+len;
goto error;
}
pos += 4+len;
*/
if (key->keyblob_len < pos+4 ||
(len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
*/
if (key->keyblob_len < pos+4 ||
(len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
- errmsg = "Key blob does not contain actual key data";
+ errmsg = "key blob does not contain actual key data";
goto error;
}
ciphertext = (char *)key->keyblob + pos + 4;
cipherlen = len;
if (cipherlen == 0) {
goto error;
}
ciphertext = (char *)key->keyblob + pos + 4;
cipherlen = len;
if (cipherlen == 0) {
- errmsg = "Length of key data is zero";
+ errmsg = "length of key data is zero";
unsigned char keybuf[32], iv[8];
if (cipherlen % 8 != 0) {
unsigned char keybuf[32], iv[8];
if (cipherlen % 8 != 0) {
- errmsg = "Encrypted part of key is not a multiple of cipher block"
+ errmsg = "encrypted part of key is not a multiple of cipher block"
sfree(key->keyblob);
memset(&key, 0, sizeof(key));
sfree(key);
sfree(key->keyblob);
memset(&key, 0, sizeof(key));
sfree(key);
+ if (errmsg_p) *errmsg_p = errmsg;
int import_target_type(int type);
int import_encrypted(const Filename *filename, int type, char **comment);
int import_ssh1(const Filename *filename, int type,
int import_target_type(int type);
int import_encrypted(const Filename *filename, int type, char **comment);
int import_ssh1(const Filename *filename, int type,
- struct RSAKey *key, char *passphrase);
+ struct RSAKey *key, char *passphrase, const char **errmsg_p);
struct ssh2_userkey *import_ssh2(const Filename *filename, int type,
struct ssh2_userkey *import_ssh2(const Filename *filename, int type,
+ char *passphrase, const char **errmsg_p);
int export_ssh1(const Filename *filename, int type,
struct RSAKey *key, char *passphrase);
int export_ssh2(const Filename *filename, int type,
int export_ssh1(const Filename *filename, int type,
struct RSAKey *key, char *passphrase);
int export_ssh2(const Filename *filename, int type,
int needs_pass;
int type, realtype;
int ret;
int needs_pass;
int type, realtype;
int ret;
+ const char *errmsg = NULL;
char *comment;
struct PassphraseProcStruct pps;
struct RSAKey newkey1;
char *comment;
struct PassphraseProcStruct pps;
struct RSAKey newkey1;
if (type != SSH_KEYTYPE_SSH1 &&
type != SSH_KEYTYPE_SSH2 &&
!import_possible(type)) {
if (type != SSH_KEYTYPE_SSH1 &&
type != SSH_KEYTYPE_SSH2 &&
!import_possible(type)) {
- char msg[256];
- sprintf(msg, "Couldn't load private key (%s)",
- key_type_to_str(type));
+ char *msg = dupprintf("Couldn't load private key (%s)",
+ key_type_to_str(type));
MessageBox(NULL, msg,
"PuTTYgen Error", MB_OK | MB_ICONERROR);
MessageBox(NULL, msg,
"PuTTYgen Error", MB_OK | MB_ICONERROR);
if (type == SSH_KEYTYPE_SSH1) {
if (realtype == type)
ret = loadrsakey(&filename, &newkey1,
if (type == SSH_KEYTYPE_SSH1) {
if (realtype == type)
ret = loadrsakey(&filename, &newkey1,
else
ret = import_ssh1(&filename, realtype,
else
ret = import_ssh1(&filename, realtype,
+ &newkey1, passphrase, &errmsg);
} else {
if (realtype == type)
newkey2 = ssh2_load_userkey(&filename,
} else {
if (realtype == type)
newkey2 = ssh2_load_userkey(&filename,
else
newkey2 = import_ssh2(&filename, realtype,
else
newkey2 = import_ssh2(&filename, realtype,
if (newkey2 == SSH2_WRONG_PASSPHRASE)
ret = -1;
else if (!newkey2)
if (newkey2 == SSH2_WRONG_PASSPHRASE)
ret = -1;
else if (!newkey2)
if (comment)
sfree(comment);
if (ret == 0) {
if (comment)
sfree(comment);
if (ret == 0) {
- MessageBox(NULL, "Couldn't load private key.",
- "PuTTYgen Error", MB_OK | MB_ICONERROR);
+ char *msg = dupprintf("Couldn't load private key (%s)", errmsg);
+ MessageBox(NULL, msg, "PuTTYgen Error", MB_OK | MB_ICONERROR);
+ sfree(msg);
} else if (ret == 1) {
/*
* Now update the key controls with all the
} else if (ret == 1) {
/*
* Now update the key controls with all the