diff --git a/cmdgen.c b/cmdgen.c index 4722a8ad..4e83336c 100644 --- a/cmdgen.c +++ b/cmdgen.c @@ -37,7 +37,7 @@ * run tests. */ #define get_random_data get_random_data_diagnostic -char *get_random_data(int len) +char *get_random_data(int len, const char *device) { char *buf = snewn(len, char); memset(buf, 'x', len); @@ -177,6 +177,8 @@ void help(void) " specify file containing old key passphrase\n" " --new-passphrase file\n" " specify file containing new key passphrase\n" + " --random-device device\n" + " specify device to read entropy from (e.g. /dev/urandom)\n" ); } @@ -245,6 +247,7 @@ int main(int argc, char **argv) char *old_passphrase = NULL, *new_passphrase = NULL; int load_encrypted; progfn_t progressfn = is_interactive() ? progress_update : no_progress; + const char *random_device = NULL; /* ------------------------------------------------------------------ * Parse the command line to figure out what we've been asked to do. @@ -338,6 +341,16 @@ int main(int argc, char **argv) if (!new_passphrase) errs = TRUE; } + } else if (!strcmp(opt, "-random-device")) { + if (!val && argc > 1) + --argc, val = *++argv; + if (!val) { + errs = TRUE; + fprintf(stderr, "puttygen: option `-%s'" + " expects an argument\n", opt); + } else { + random_device = val; + } } else { errs = TRUE; fprintf(stderr, @@ -677,7 +690,7 @@ int main(int argc, char **argv) strftime(default_comment, 30, "rsa-key-%Y%m%d", &tm); random_ref(); - entropy = get_random_data(bits / 8); + entropy = get_random_data(bits / 8, random_device); if (!entropy) { fprintf(stderr, "puttygen: failed to collect entropy, " "could not generate key\n"); diff --git a/putty.h b/putty.h index c02e00f1..73bfd9e4 100644 --- a/putty.h +++ b/putty.h @@ -1352,7 +1352,7 @@ void filename_free(Filename *fn); int filename_serialise(const Filename *f, void *data); Filename *filename_deserialise(void *data, int maxsize, int *used); char *get_username(void); /* return value needs freeing */ -char *get_random_data(int bytes); /* used in cmdgen.c */ +char *get_random_data(int bytes, const char *device); /* used in cmdgen.c */ char filename_char_sanitise(char c); /* rewrite special pathname chars */ /* diff --git a/unix/uxgen.c b/unix/uxgen.c index 156d4efe..f593a960 100644 --- a/unix/uxgen.c +++ b/unix/uxgen.c @@ -3,21 +3,27 @@ */ #include +#include + #include #include #include "putty.h" -char *get_random_data(int len) +char *get_random_data(int len, const char *device) { char *buf = snewn(len, char); int fd; int ngot, ret; - fd = open("/dev/random", O_RDONLY); + if (!device) + device = "/dev/random"; + + fd = open(device, O_RDONLY); if (fd < 0) { sfree(buf); - perror("puttygen: unable to open /dev/random"); + fprintf(stderr, "puttygen: %s: open: %s\n", + device, strerror(errno)); return NULL; } @@ -27,7 +33,8 @@ char *get_random_data(int len) if (ret < 0) { close(fd); sfree(buf); - perror("puttygen: unable to read /dev/random"); + fprintf(stderr, "puttygen: %s: read: %s\n", + device, strerror(errno)); return NULL; } ngot += ret;