ifeq "$(RELEASE)" "" set Ndate $(!builddate)
ifneq "$(Ndate)" "" in . do echo $(Ndate) | perl -pe 's/(....)(..)(..)/$$1-$$2-$$3/' > date
ifneq "$(Ndate)" "" read Date date
-set Epoch 6000 # update this at every release
+set Epoch 15493 # update this at every release
ifneq "$(Ndate)" "" in . do echo $(Ndate) | perl -ne 'use Time::Local; /(....)(..)(..)/ and print timegm(0,0,0,$$3,$$2-1,$$1) / 86400 - $(Epoch)' > days
ifneq "$(Ndate)" "" read Days days
\c Z:\sysosd>plink
\c Plink: command-line connection utility
-\c Release 0.XX
+\c Release 0.64
\c Usage: plink [options] [user@]host [command]
\c ("host" can also be a PuTTY saved session name)
\c Options:
\c Z:\owendadmin>pscp
\c PuTTY Secure Copy client
-\c Release 0.XX
+\c Release 0.64
\c Usage: pscp [options] [user@]host:source target
\c pscp [options] source [source...] [user@]host:target
\c pscp [options] -ls [user@]host:filespec
}
ssh_pkt_getstring(pktin, &s->sigdata, &s->siglen);
+ {
+ const char *err = dh_validate_f(ssh->kex_ctx, s->f);
+ if (err) {
+ bombout(("key exchange reply failed validation: %s", err));
+ crStopV;
+ }
+ }
s->K = dh_find_K(ssh->kex_ctx, s->f);
/* We assume everything from now on will be quick, and it might
void *dh_setup_gex(Bignum pval, Bignum gval);
void dh_cleanup(void *);
Bignum dh_create_e(void *, int nbits);
+const char *dh_validate_f(void *handle, Bignum f);
Bignum dh_find_K(void *, Bignum f);
int loadrsakey(const Filename *filename, struct RSAKey *key,
return ctx->e;
}
+/*
+ * DH stage 2-epsilon: given a number f, validate it to ensure it's in
+ * range. (RFC 4253 section 8: "Values of 'e' or 'f' that are not in
+ * the range [1, p-1] MUST NOT be sent or accepted by either side."
+ * Also, we rule out 1 and p-1 too, since that's easy to do and since
+ * they lead to obviously weak keys that even a passive eavesdropper
+ * can figure out.)
+ */
+const char *dh_validate_f(void *handle, Bignum f)
+{
+ struct dh_ctx *ctx = (struct dh_ctx *)handle;
+ if (bignum_cmp(f, One) <= 0) {
+ return "f value received is too small";
+ } else {
+ Bignum pm1 = bigsub(ctx->p, One);
+ int cmp = bignum_cmp(f, pm1);
+ freebn(pm1);
+ if (cmp >= 0)
+ return "f value received is too large";
+ }
+ return NULL;
+}
+
/*
* DH stage 2: given a number f, compute K = f^x mod p.
*/
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;
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;
}
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;
}
\r
[Setup]\r
AppName=PuTTY\r
-AppVerName=PuTTY version 0.63\r
-VersionInfoTextVersion=Release 0.63\r
-AppVersion=0.63\r
-VersionInfoVersion=0.63.0.0\r
+AppVerName=PuTTY version 0.64\r
+VersionInfoTextVersion=Release 0.64\r
+AppVersion=0.64\r
+VersionInfoVersion=0.64.0.0\r
AppPublisher=Simon Tatham\r
AppPublisherURL=http://www.chiark.greenend.org.uk/~sgtatham/putty/\r
AppReadmeFile={app}\README.txt\r