X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/51e9d3c00a3471f284e89ec1f59f38ca25f10c5f..HEAD:/import.c diff --git a/import.c b/import.c index 25012d28..bc35a4ab 100644 --- a/import.c +++ b/import.c @@ -109,6 +109,17 @@ int export_ssh2(const Filename *filename, int type, return 0; } +/* + * Strip trailing CRs and LFs at the end of a line of text. + */ +void strip_crlf(char *str) +{ + char *p = str + strlen(str); + + while (p > str && (p[-1] == '\r' || p[-1] == '\n')) + *--p = '\0'; +} + /* ---------------------------------------------------------------------- * Helper routines. (The base64 ones are defined in sshpubk.c.) */ @@ -278,8 +289,8 @@ static int ssh2_read_mpint(void *data, int len, struct mpint_pos *ret) if (len < 4) goto error; - bytes = GET_32BIT(d); - if (len < 4+bytes) + bytes = toint(GET_32BIT(d)); + if (bytes < 0 || len-4 < bytes) goto error; ret->start = d + 4; @@ -297,9 +308,10 @@ static int ssh2_read_mpint(void *data, int len, struct mpint_pos *ret) */ enum { OSSH_DSA, OSSH_RSA }; +enum { OSSH_ENC_3DES, OSSH_ENC_AES }; struct openssh_key { int type; - int encrypted; + int encrypted, encryption; char iv[32]; unsigned char *keyblob; int keyblob_len, keyblob_size; @@ -309,8 +321,8 @@ static struct openssh_key *load_openssh_key(const Filename *filename, const char **errmsg_p) { struct openssh_key *ret; - FILE *fp; - char buffer[256]; + FILE *fp = NULL; + char *line = NULL; char *errmsg, *p; int headers_done; char base64_bit[4]; @@ -322,73 +334,93 @@ static struct openssh_key *load_openssh_key(const Filename *filename, ret->encrypted = 0; memset(ret->iv, 0, sizeof(ret->iv)); - fp = f_open(*filename, "r"); + fp = f_open(filename, "r", FALSE); if (!fp) { 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")) { + + if (!(line = fgetline(fp))) { + errmsg = "unexpected end of file"; + goto error; + } + strip_crlf(line); + if (0 != strncmp(line, "-----BEGIN ", 11) || + 0 != strcmp(line+strlen(line)-16, "PRIVATE KEY-----")) { errmsg = "file does not begin with OpenSSH key header"; goto error; } - if (!strcmp(buffer, "-----BEGIN RSA PRIVATE KEY-----\n")) + if (!strcmp(line, "-----BEGIN RSA PRIVATE KEY-----")) ret->type = OSSH_RSA; - else if (!strcmp(buffer, "-----BEGIN DSA PRIVATE KEY-----\n")) + else if (!strcmp(line, "-----BEGIN DSA PRIVATE KEY-----")) ret->type = OSSH_DSA; else { errmsg = "unrecognised key type"; goto error; } + smemclr(line, strlen(line)); + sfree(line); + line = NULL; headers_done = 0; while (1) { - if (!fgets(buffer, sizeof(buffer), fp)) { + if (!(line = fgetline(fp))) { errmsg = "unexpected end of file"; goto error; } - if (0 == strncmp(buffer, "-----END ", 9) && - 0 == strcmp(buffer+strlen(buffer)-17, "PRIVATE KEY-----\n")) + strip_crlf(line); + if (0 == strncmp(line, "-----END ", 9) && + 0 == strcmp(line+strlen(line)-16, "PRIVATE KEY-----")) { + sfree(line); + line = NULL; break; /* done */ - if ((p = strchr(buffer, ':')) != NULL) { + } + if ((p = strchr(line, ':')) != NULL) { if (headers_done) { errmsg = "header found in body of key data"; goto error; } *p++ = '\0'; while (*p && isspace((unsigned char)*p)) p++; - if (!strcmp(buffer, "Proc-Type")) { + if (!strcmp(line, "Proc-Type")) { if (p[0] != '4' || p[1] != ',') { errmsg = "Proc-Type is not 4 (only 4 is supported)"; goto error; } p += 2; - if (!strcmp(p, "ENCRYPTED\n")) + if (!strcmp(p, "ENCRYPTED")) ret->encrypted = 1; - } else if (!strcmp(buffer, "DEK-Info")) { - int i, j; - - if (strncmp(p, "DES-EDE3-CBC,", 13)) { - errmsg = "ciphers other than DES-EDE3-CBC not supported"; + } else if (!strcmp(line, "DEK-Info")) { + int i, j, ivlen; + + if (!strncmp(p, "DES-EDE3-CBC,", 13)) { + ret->encryption = OSSH_ENC_3DES; + ivlen = 8; + } else if (!strncmp(p, "AES-128-CBC,", 12)) { + ret->encryption = OSSH_ENC_AES; + ivlen = 16; + } else { + errmsg = "unsupported cipher"; goto error; } - p += 13; - for (i = 0; i < 8; i++) { - if (1 != sscanf(p, "%2x", &j)) - break; + p = strchr(p, ',') + 1;/* always non-NULL, by above checks */ + for (i = 0; i < ivlen; i++) { + if (1 != sscanf(p, "%2x", &j)) { + errmsg = "expected more iv data in DEK-Info"; + goto error; + } ret->iv[i] = j; p += 2; } - if (i < 8) { - errmsg = "expected 16-digit iv in DEK-Info"; + if (*p) { + errmsg = "more iv data than expected in DEK-Info"; goto error; } } } else { headers_done = 1; - p = buffer; + p = line; while (isbase64(*p)) { base64_bit[base64_chars++] = *p; if (base64_chars == 4) { @@ -413,14 +445,20 @@ static struct openssh_key *load_openssh_key(const Filename *filename, memcpy(ret->keyblob + ret->keyblob_len, out, len); ret->keyblob_len += len; - memset(out, 0, sizeof(out)); + smemclr(out, sizeof(out)); } p++; } } + 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; @@ -431,23 +469,27 @@ static struct openssh_key *load_openssh_key(const Filename *filename, goto error; } - memset(buffer, 0, sizeof(buffer)); - memset(base64_bit, 0, sizeof(base64_bit)); + smemclr(base64_bit, sizeof(base64_bit)); if (errmsg_p) *errmsg_p = NULL; return ret; error: - memset(buffer, 0, sizeof(buffer)); - memset(base64_bit, 0, sizeof(base64_bit)); + if (line) { + smemclr(line, strlen(line)); + sfree(line); + line = NULL; + } + 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; } @@ -459,9 +501,9 @@ int openssh_encrypted(const Filename *filename) 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; } @@ -494,6 +536,10 @@ struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase, * - 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]; @@ -512,11 +558,21 @@ struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase, /* * Now decrypt the key blob. */ - des3_decrypt_pubkey_ossh(keybuf, (unsigned char *)key->iv, - key->keyblob, key->keyblob_len); + if (key->encryption == OSSH_ENC_3DES) + des3_decrypt_pubkey_ossh(keybuf, (unsigned char *)key->iv, + key->keyblob, key->keyblob_len); + else { + void *ctx; + assert(key->encryption == OSSH_ENC_AES); + ctx = aes_make_context(); + aes128_key(ctx, keybuf); + aes_iv(ctx, (unsigned char *)key->iv); + aes_ssh2_decrypt_blk(ctx, key->keyblob, key->keyblob_len); + aes_free_context(ctx); + } - memset(&md5c, 0, sizeof(md5c)); - memset(keybuf, 0, sizeof(keybuf)); + smemclr(&md5c, sizeof(md5c)); + smemclr(keybuf, sizeof(keybuf)); } /* @@ -539,12 +595,13 @@ struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase, 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; } @@ -576,7 +633,7 @@ struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase, 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; } @@ -649,12 +706,12 @@ struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase, 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; @@ -691,6 +748,10 @@ int openssh_write(const Filename *filename, struct ssh2_userkey *key, struct mpint_pos n, e, d, p, q, iqmp, dmp1, dmq1; Bignum bd, bp, bq, bdmp1, bdmq1; + /* + * These blobs were generated from inside PuTTY, so we needn't + * treat them as untrusted. + */ pos = 4 + GET_32BIT(pubblob); pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e); pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n); @@ -744,6 +805,10 @@ int openssh_write(const Filename *filename, struct ssh2_userkey *key, int pos; struct mpint_pos p, q, g, y, x; + /* + * These blobs were generated from inside PuTTY, so we needn't + * treat them as untrusted. + */ pos = 4 + GET_32BIT(pubblob); pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p); pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q); @@ -766,6 +831,7 @@ int openssh_write(const Filename *filename, struct ssh2_userkey *key, footer = "-----END DSA PRIVATE KEY-----\n"; } else { assert(0); /* zoinks! */ + exit(1); /* XXX: GCC doesn't understand assert() on some systems. */ } /* @@ -826,6 +892,9 @@ int openssh_write(const Filename *filename, struct ssh2_userkey *key, /* * Encrypt the key. + * + * For the moment, we still encrypt our OpenSSH keys using + * old-style 3DES. */ if (passphrase) { /* @@ -858,15 +927,15 @@ int openssh_write(const Filename *filename, struct ssh2_userkey *key, */ 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"); /* ensure Unix line endings */ + fp = f_open(filename, "wb", TRUE); /* ensure Unix line endings */ if (!fp) goto error; fputs(header, fp); @@ -883,19 +952,19 @@ int openssh_write(const Filename *filename, struct ssh2_userkey *key, 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; @@ -988,8 +1057,8 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename, { struct sshcom_key *ret; FILE *fp; - char buffer[256]; - int len; + char *line = NULL; + int hdrstart, len; char *errmsg, *p; int headers_done; char base64_bit[4]; @@ -1000,49 +1069,75 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename, ret->keyblob = NULL; ret->keyblob_len = ret->keyblob_size = 0; - fp = f_open(*filename, "r"); + fp = f_open(filename, "r", FALSE); if (!fp) { errmsg = "unable to open key file"; goto error; } - if (!fgets(buffer, sizeof(buffer), fp) || - 0 != strcmp(buffer, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n")) { + if (!(line = fgetline(fp))) { + errmsg = "unexpected end of file"; + goto error; + } + strip_crlf(line); + if (0 != strcmp(line, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----")) { errmsg = "file does not begin with ssh.com key header"; goto error; } + smemclr(line, strlen(line)); + sfree(line); + line = NULL; headers_done = 0; while (1) { - if (!fgets(buffer, sizeof(buffer), fp)) { + if (!(line = fgetline(fp))) { errmsg = "unexpected end of file"; goto error; } - if (!strcmp(buffer, "---- END SSH2 ENCRYPTED PRIVATE KEY ----\n")) + strip_crlf(line); + if (!strcmp(line, "---- END SSH2 ENCRYPTED PRIVATE KEY ----")) { + sfree(line); + line = NULL; break; /* done */ - if ((p = strchr(buffer, ':')) != NULL) { + } + if ((p = strchr(line, ':')) != NULL) { if (headers_done) { errmsg = "header found in body of key data"; goto error; } *p++ = '\0'; while (*p && isspace((unsigned char)*p)) p++; + hdrstart = p - line; + /* * Header lines can end in a trailing backslash for * continuation. */ - 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"; - goto error; - } - if (!fgets(p+len-2, sizeof(buffer)-(p-buffer)-(len-2), fp)) { + len = hdrstart + strlen(line+hdrstart); + assert(!line[len]); + while (line[len-1] == '\\') { + char *line2; + int line2len; + + line2 = fgetline(fp); + if (!line2) { errmsg = "unexpected end of file"; goto error; } + strip_crlf(line2); + + line2len = strlen(line2); + line = sresize(line, len + line2len + 1, char); + strcpy(line + len - 1, line2); + len += line2len - 1; + assert(!line[len]); + + smemclr(line2, strlen(line2)); + sfree(line2); + line2 = NULL; } - p[strcspn(p, "\n")] = '\0'; - if (!strcmp(buffer, "Comment")) { + p = line + hdrstart; + strip_crlf(p); + if (!strcmp(line, "Comment")) { /* Strip quotes in comment if present. */ if (p[0] == '"' && p[strlen(p)-1] == '"') { p++; @@ -1054,7 +1149,7 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename, } else { headers_done = 1; - p = buffer; + p = line; while (isbase64(*p)) { base64_bit[base64_chars++] = *p; if (base64_chars == 4) { @@ -1082,6 +1177,9 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename, p++; } } + smemclr(line, strlen(line)); + sfree(line); + line = NULL; } if (ret->keyblob_len == 0 || !ret->keyblob) { @@ -1089,16 +1187,25 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename, goto error; } + fclose(fp); if (errmsg_p) *errmsg_p = NULL; return ret; error: + if (fp) + fclose(fp); + + if (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; @@ -1110,45 +1217,51 @@ int sshcom_encrypted(const Filename *filename, char **comment) struct sshcom_key *key = load_sshcom_key(filename, NULL); int pos, len, answer; + answer = 0; + *comment = NULL; if (!key) - return 0; + goto done; /* * Check magic number. */ - if (GET_32BIT(key->keyblob) != 0x3f6ff9eb) - return 0; /* key is invalid */ + if (GET_32BIT(key->keyblob) != 0x3f6ff9eb) { + goto done; /* key is invalid */ + } /* * Find the cipher-type string. */ - answer = 0; pos = 8; if (key->keyblob_len < pos+4) goto done; /* key is far too short */ - pos += 4 + GET_32BIT(key->keyblob + pos); /* skip key type */ - if (key->keyblob_len < pos+4) + len = toint(GET_32BIT(key->keyblob + pos)); + if (len < 0 || len > key->keyblob_len - pos - 4) goto done; /* key is far too short */ - len = GET_32BIT(key->keyblob + pos); /* find cipher-type length */ - if (key->keyblob_len < pos+4+len) + pos += 4 + len; /* skip key type */ + len = toint(GET_32BIT(key->keyblob + pos)); /* find cipher-type length */ + if (len < 0 || len > key->keyblob_len - pos - 4) goto done; /* cipher type string is incomplete */ if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4)) answer = 1; done: - *comment = dupstr(key->comment); - memset(key->keyblob, 0, key->keyblob_size); - sfree(key->keyblob); - memset(&key, 0, sizeof(key)); - sfree(key); + if (key) { + *comment = dupstr(key->comment); + smemclr(key->keyblob, key->keyblob_size); + sfree(key->keyblob); + smemclr(key, sizeof(*key)); + sfree(key); + } else { + *comment = dupstr(""); + } return answer; } static int sshcom_read_mpint(void *data, int len, struct mpint_pos *ret) { - int bits; - int bytes; + unsigned bits, bytes; unsigned char *d = (unsigned char *) data; if (len < 4) @@ -1220,7 +1333,8 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase, */ pos = 8; if (key->keyblob_len < pos+4 || - (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) { + (len = toint(GET_32BIT(key->keyblob + pos))) < 0 || + len > key->keyblob_len - pos - 4) { errmsg = "key blob does not contain a key type string"; goto error; } @@ -1240,7 +1354,8 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase, * Determine the cipher type. */ if (key->keyblob_len < pos+4 || - (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) { + (len = toint(GET_32BIT(key->keyblob + pos))) < 0 || + len > key->keyblob_len - pos - 4) { errmsg = "key blob does not contain a cipher type string"; goto error; } @@ -1258,7 +1373,8 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase, * Get hold of the encrypted part of the key. */ if (key->keyblob_len < pos+4 || - (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) { + (len = toint(GET_32BIT(key->keyblob + pos))) < 0 || + len > key->keyblob_len - pos - 4) { errmsg = "key blob does not contain actual key data"; goto error; } @@ -1306,8 +1422,8 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase, 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 @@ -1322,7 +1438,7 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase, /* * Strip away the containing string to get to the real meat. */ - len = GET_32BIT(ciphertext); + len = toint(GET_32BIT(ciphertext)); if (len < 0 || len > cipherlen-4) { errmsg = "containing string was ill-formed"; goto error; @@ -1363,9 +1479,12 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase, pos += put_mp(blob+pos, p.start, p.bytes); pos += put_mp(blob+pos, u.start, u.bytes); privlen = pos - publen; - } else if (type == DSA) { + } else { struct mpint_pos p, q, g, x, y; int pos = 4; + + assert(type == DSA); /* the only other option from the if above */ + if (GET_32BIT(ciphertext) != 0) { errmsg = "predefined DSA parameters not supported"; goto error; @@ -1390,8 +1509,7 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase, publen = pos; pos += put_mp(blob+pos, x.start, x.bytes); privlen = pos - publen; - } else - return NULL; + } assert(privlen > 0); /* should have bombed by now if not */ @@ -1410,12 +1528,12 @@ struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase, 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; @@ -1451,6 +1569,10 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key, int pos; struct mpint_pos n, e, d, p, q, iqmp; + /* + * These blobs were generated from inside PuTTY, so we needn't + * treat them as untrusted. + */ pos = 4 + GET_32BIT(pubblob); pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e); pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n); @@ -1476,6 +1598,10 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key, int pos; struct mpint_pos p, q, g, y, x; + /* + * These blobs were generated from inside PuTTY, so we needn't + * treat them as untrusted. + */ pos = 4 + GET_32BIT(pubblob); pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p); pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q); @@ -1497,6 +1623,7 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key, type = "dl-modp{sign{dsa-nist-sha1},dh{plain}}"; } else { assert(0); /* zoinks! */ + exit(1); /* XXX: GCC doesn't understand assert() on some systems. */ } /* @@ -1579,15 +1706,15 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key, 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"); /* 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); @@ -1615,15 +1742,15 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key, 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;