const char **errmsg_p)
{
struct openssh_key *ret;
- FILE *fp;
+ FILE *fp = NULL;
char *line = NULL;
char *errmsg, *p;
int headers_done;
ret->encrypted = 0;
memset(ret->iv, 0, sizeof(ret->iv));
- fp = f_open(*filename, "r", FALSE);
+ fp = f_open(filename, "r", FALSE);
if (!fp) {
errmsg = "unable to open key file";
goto error;
errmsg = "unrecognised key type";
goto error;
}
- memset(line, 0, strlen(line));
+ smemclr(line, strlen(line));
sfree(line);
line = NULL;
memcpy(ret->keyblob + ret->keyblob_len, out, len);
ret->keyblob_len += len;
- memset(out, 0, sizeof(out));
+ smemclr(out, sizeof(out));
}
p++;
}
}
- memset(line, 0, strlen(line));
+ smemclr(line, strlen(line));
sfree(line);
line = NULL;
}
+ fclose(fp);
+ fp = NULL;
+
if (ret->keyblob_len == 0 || !ret->keyblob) {
errmsg = "key body not present";
goto error;
goto error;
}
- memset(base64_bit, 0, sizeof(base64_bit));
+ smemclr(base64_bit, sizeof(base64_bit));
if (errmsg_p) *errmsg_p = NULL;
return ret;
error:
if (line) {
- memset(line, 0, strlen(line));
+ smemclr(line, strlen(line));
sfree(line);
line = NULL;
}
- memset(base64_bit, 0, sizeof(base64_bit));
+ smemclr(base64_bit, sizeof(base64_bit));
if (ret) {
if (ret->keyblob) {
- memset(ret->keyblob, 0, ret->keyblob_size);
+ smemclr(ret->keyblob, ret->keyblob_size);
sfree(ret->keyblob);
}
- memset(ret, 0, sizeof(*ret));
+ smemclr(ret, sizeof(*ret));
sfree(ret);
}
if (errmsg_p) *errmsg_p = errmsg;
+ if (fp) fclose(fp);
return NULL;
}
if (!key)
return 0;
ret = key->encrypted;
- memset(key->keyblob, 0, key->keyblob_size);
+ smemclr(key->keyblob, key->keyblob_size);
sfree(key->keyblob);
- memset(key, 0, sizeof(*key));
+ smemclr(key, sizeof(*key));
sfree(key);
return ret;
}
* - let block B equal MD5(A || passphrase || iv)
* - block C would be MD5(B || passphrase || iv) and so on
* - encryption key is the first N bytes of A || B
+ *
+ * (Note that only 8 bytes of the iv are used for key
+ * derivation, even when the key is encrypted with AES and
+ * hence there are 16 bytes available.)
*/
struct MD5Context md5c;
unsigned char keybuf[32];
aes_free_context(ctx);
}
- memset(&md5c, 0, sizeof(md5c));
- memset(keybuf, 0, sizeof(keybuf));
+ smemclr(&md5c, sizeof(md5c));
+ smemclr(keybuf, sizeof(keybuf));
}
/*
p = key->keyblob;
- /* Expect the SEQUENCE header. Take its absence as a failure to decrypt. */
+ /* Expect the SEQUENCE header. Take its absence as a failure to
+ * decrypt, if the key was encrypted. */
ret = ber_read_id_len(p, key->keyblob_len, &id, &len, &flags);
p += ret;
if (ret < 0 || id != 16) {
errmsg = "ASN.1 decoding failure";
- retval = SSH2_WRONG_PASSPHRASE;
+ retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
goto error;
}
if (ret < 0 || id != 2 ||
key->keyblob+key->keyblob_len-p < len) {
errmsg = "ASN.1 decoding failure";
- retval = SSH2_WRONG_PASSPHRASE;
+ retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
goto error;
}
error:
if (blob) {
- memset(blob, 0, blobsize);
+ smemclr(blob, blobsize);
sfree(blob);
}
- memset(key->keyblob, 0, key->keyblob_size);
+ smemclr(key->keyblob, key->keyblob_size);
sfree(key->keyblob);
- memset(key, 0, sizeof(*key));
+ smemclr(key, sizeof(*key));
sfree(key);
if (errmsg_p) *errmsg_p = errmsg;
return retval;
/*
* Encrypt the key.
+ *
+ * For the moment, we still encrypt our OpenSSH keys using
+ * old-style 3DES.
*/
if (passphrase) {
/*
*/
des3_encrypt_pubkey_ossh(keybuf, iv, outblob, outlen);
- memset(&md5c, 0, sizeof(md5c));
- memset(keybuf, 0, sizeof(keybuf));
+ smemclr(&md5c, sizeof(md5c));
+ smemclr(keybuf, sizeof(keybuf));
}
/*
* And save it. We'll use Unix line endings just in case it's
* subsequently transferred in binary mode.
*/
- fp = f_open(*filename, "wb", TRUE); /* ensure Unix line endings */
+ fp = f_open(filename, "wb", TRUE); /* ensure Unix line endings */
if (!fp)
goto error;
fputs(header, fp);
error:
if (outblob) {
- memset(outblob, 0, outlen);
+ smemclr(outblob, outlen);
sfree(outblob);
}
if (spareblob) {
- memset(spareblob, 0, sparelen);
+ smemclr(spareblob, sparelen);
sfree(spareblob);
}
if (privblob) {
- memset(privblob, 0, privlen);
+ smemclr(privblob, privlen);
sfree(privblob);
}
if (pubblob) {
- memset(pubblob, 0, publen);
+ smemclr(pubblob, publen);
sfree(pubblob);
}
return ret;
ret->keyblob = NULL;
ret->keyblob_len = ret->keyblob_size = 0;
- fp = f_open(*filename, "r", FALSE);
+ fp = f_open(filename, "r", FALSE);
if (!fp) {
errmsg = "unable to open key file";
goto error;
errmsg = "file does not begin with ssh.com key header";
goto error;
}
- memset(line, 0, strlen(line));
+ smemclr(line, strlen(line));
sfree(line);
line = NULL;
len += line2len - 1;
assert(!line[len]);
- memset(line2, 0, strlen(line2));
+ smemclr(line2, strlen(line2));
sfree(line2);
line2 = NULL;
}
p++;
}
}
- memset(line, 0, strlen(line));
+ smemclr(line, strlen(line));
sfree(line);
line = NULL;
}
error:
if (line) {
- memset(line, 0, strlen(line));
+ smemclr(line, strlen(line));
sfree(line);
line = NULL;
}
if (ret) {
if (ret->keyblob) {
- memset(ret->keyblob, 0, ret->keyblob_size);
+ smemclr(ret->keyblob, ret->keyblob_size);
sfree(ret->keyblob);
}
- memset(ret, 0, sizeof(*ret));
+ smemclr(ret, sizeof(*ret));
sfree(ret);
}
if (errmsg_p) *errmsg_p = errmsg;
done:
*comment = dupstr(key->comment);
- memset(key->keyblob, 0, key->keyblob_size);
+ smemclr(key->keyblob, key->keyblob_size);
sfree(key->keyblob);
- memset(key, 0, sizeof(*key));
+ smemclr(key, sizeof(*key));
sfree(key);
return answer;
}
des3_decrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
cipherlen);
- memset(&md5c, 0, sizeof(md5c));
- memset(keybuf, 0, sizeof(keybuf));
+ smemclr(&md5c, sizeof(md5c));
+ smemclr(keybuf, sizeof(keybuf));
/*
* Hereafter we return WRONG_PASSPHRASE for any parsing
error:
if (blob) {
- memset(blob, 0, blobsize);
+ smemclr(blob, blobsize);
sfree(blob);
}
- memset(key->keyblob, 0, key->keyblob_size);
+ smemclr(key->keyblob, key->keyblob_size);
sfree(key->keyblob);
- memset(key, 0, sizeof(*key));
+ smemclr(key, sizeof(*key));
sfree(key);
if (errmsg_p) *errmsg_p = errmsg;
return ret;
des3_encrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
cipherlen);
- memset(&md5c, 0, sizeof(md5c));
- memset(keybuf, 0, sizeof(keybuf));
+ smemclr(&md5c, sizeof(md5c));
+ smemclr(keybuf, sizeof(keybuf));
}
/*
* And save it. We'll use Unix line endings just in case it's
* subsequently transferred in binary mode.
*/
- fp = f_open(*filename, "wb", TRUE); /* ensure Unix line endings */
+ fp = f_open(filename, "wb", TRUE); /* ensure Unix line endings */
if (!fp)
goto error;
fputs("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);
error:
if (outblob) {
- memset(outblob, 0, outlen);
+ smemclr(outblob, outlen);
sfree(outblob);
}
if (privblob) {
- memset(privblob, 0, privlen);
+ smemclr(privblob, privlen);
sfree(privblob);
}
if (pubblob) {
- memset(pubblob, 0, publen);
+ smemclr(pubblob, publen);
sfree(pubblob);
}
return ret;