mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
Use a proper PRNG for GTK askpass.
Coverity complained that it was wrong to use rand() in a security context, and although in this case it's _very_ marginal, I can't actually disagree that the choice of which light to light up to avoid giving information about passphrase length is a security context. So, no more rand(); instead we instantiate a shiny Fortuna PRNG instance, seed it in more or less the usual way, and use that as an overkill-level method of choosing which light to light up next. (Acknowledging that this is a slightly unusual application and less critical than most, I don't actually put the passphrase characters themselves into the PRNG, and I don't use a random-seed file.)
This commit is contained in:
parent
4fb20b15f3
commit
03aeabfbea
2
Recipe
2
Recipe
@ -376,7 +376,7 @@ pageant : [X] uxpgnt uxagentc aqsync pageant sshrsa sshpubk sshdes ARITH
|
||||
+ sshmd5 version tree234 misc sshaes sshsha sshdss sshsh256 sshsh512
|
||||
+ sshecc CONF uxsignal nocproxy nogss be_none x11fwd ux_x11 uxcons
|
||||
+ gtkask gtkmisc nullplug logging UXMISC uxagentsock utils memory
|
||||
+ sshauxcrypt sshhmac
|
||||
+ sshauxcrypt sshhmac sshprng uxnoise
|
||||
|
||||
ptermapp : [XT] GTKTERM uxmisc misc ldisc settings uxpty uxsel BE_NONE uxstore
|
||||
+ uxsignal CHARSET uxpterm version time xpmpterm xpmptcfg
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "gtkcompat.h"
|
||||
#include "gtkmisc.h"
|
||||
|
||||
#include "putty.h"
|
||||
#include "ssh.h"
|
||||
#include "misc.h"
|
||||
|
||||
#define N_DRAWING_AREAS 3
|
||||
@ -55,12 +57,39 @@ struct askpass_ctx {
|
||||
int nattempts;
|
||||
};
|
||||
|
||||
static prng *keypress_prng = NULL;
|
||||
static void feed_keypress_prng(void *data, int size)
|
||||
{
|
||||
put_data(keypress_prng, data, size);
|
||||
}
|
||||
void random_add_noise(NoiseSourceId source, const void *noise, int length)
|
||||
{
|
||||
if (keypress_prng)
|
||||
prng_add_entropy(keypress_prng, source, make_ptrlen(noise, length));
|
||||
}
|
||||
static void setup_keypress_prng(void)
|
||||
{
|
||||
keypress_prng = prng_new(&ssh_sha256);
|
||||
prng_seed_begin(keypress_prng);
|
||||
noise_get_heavy(feed_keypress_prng);
|
||||
prng_seed_finish(keypress_prng);
|
||||
}
|
||||
static void cleanup_keypress_prng(void)
|
||||
{
|
||||
prng_free(keypress_prng);
|
||||
}
|
||||
static int choose_new_area(int prev_area)
|
||||
{
|
||||
uint8_t data[8];
|
||||
prng_read(keypress_prng, data, 8);
|
||||
uint64_t randval = GET_64BIT_MSB_FIRST(data);
|
||||
int reduced = randval % (N_DRAWING_AREAS - 1);
|
||||
return (prev_area + 1 + reduced) % N_DRAWING_AREAS;
|
||||
}
|
||||
|
||||
static void visually_acknowledge_keypress(struct askpass_ctx *ctx)
|
||||
{
|
||||
int new_active;
|
||||
new_active = rand() % (N_DRAWING_AREAS - 1);
|
||||
if (new_active >= ctx->active_area)
|
||||
new_active++;
|
||||
int new_active = choose_new_area(ctx->active_area);
|
||||
ctx->drawingareas[ctx->active_area].state = NOT_CURRENT;
|
||||
gtk_widget_queue_draw(ctx->drawingareas[ctx->active_area].area);
|
||||
ctx->drawingareas[new_active].state = CURRENT;
|
||||
@ -546,7 +575,9 @@ char *gtk_askpass_main(const char *display, const char *wintitle,
|
||||
*success = false;
|
||||
return dupprintf("%s", err);
|
||||
}
|
||||
setup_keypress_prng();
|
||||
gtk_main();
|
||||
cleanup_keypress_prng();
|
||||
gtk_askpass_cleanup(ctx);
|
||||
|
||||
if (ctx->passphrase) {
|
||||
@ -582,7 +613,6 @@ int main(int argc, char **argv)
|
||||
success = false;
|
||||
ret = dupprintf("usage: %s <prompt text>", argv[0]);
|
||||
} else {
|
||||
srand(time(NULL));
|
||||
ret = gtk_askpass_main(NULL, "Enter passphrase", argv[1], &success);
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,6 @@ void uxsel_input_remove(uxsel_id *id) { }
|
||||
*/
|
||||
void random_save_seed(void) {}
|
||||
void random_destroy_seed(void) {}
|
||||
void noise_ultralight(NoiseSourceId id, unsigned long data) {}
|
||||
char *platform_default_s(const char *name) { return NULL; }
|
||||
bool platform_default_b(const char *name, bool def) { return def; }
|
||||
int platform_default_i(const char *name, int def) { return def; }
|
||||
|
Loading…
Reference in New Issue
Block a user