diff options
Diffstat (limited to 'ports/winnt/libntp/randfile.c')
-rw-r--r-- | ports/winnt/libntp/randfile.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/ports/winnt/libntp/randfile.c b/ports/winnt/libntp/randfile.c new file mode 100644 index 0000000..7de80b8 --- /dev/null +++ b/ports/winnt/libntp/randfile.c @@ -0,0 +1,109 @@ +/* + * Make sure that there is a good source of random characters + * so that OpenSSL can work properly and securely. + */ + +#include <config.h> +#include <wincrypt.h> + +#include <stdio.h> + +unsigned int getrandom_chars(int desired, unsigned char *buf, int lenbuf); +BOOL create_random_file(char *filename); + +BOOL +init_randfile() +{ + FILE *rf; + char *randfile; + char *homedir; + char tmp[256]; + /* See if the environmental variable RANDFILE is defined + * and the file exists + */ + randfile = getenv("RANDFILE"); + if (randfile != NULL) { + rf = fopen(randfile, "rb"); + if (rf != NULL) { + fclose(rf); + return (TRUE); + } + else { + /* The environmental variable exists but not the file */ + return (create_random_file(randfile)); + } + } + /* + * If the RANDFILE environmental variable does not exist, + * see if the HOME enviromental variable exists and + * a .rnd file is in there. + */ + homedir = getenv("HOME"); + if (homedir != NULL && + (strlen(homedir) + 5 /* \.rnd */) < sizeof(tmp)) { + snprintf(tmp, sizeof(tmp), "%s\\.rnd", homedir); + rf = fopen(tmp, "rb"); + if (rf != NULL) { + fclose(rf); + return (TRUE); + } + else { + /* The HOME environmental variable exists but not the file */ + return (create_random_file(tmp)); + } + } + /* + * Final try. Look for it on the C:\ directory + * NOTE: This is a really bad place for it security-wise + * However, OpenSSL looks for it there if it can't find it elsewhere + */ + rf = fopen("C:\\.rnd", "rb"); + if (rf != NULL) { + fclose(rf); + return (TRUE); + } + /* The file does not exist */ + return (create_random_file("C:\\.rnd")); +} +/* + * Routine to create the random file with 1024 random characters + */ +BOOL +create_random_file(char *filename) { + FILE *rf; + int nchars; + unsigned char buf[1025]; + + nchars = getrandom_chars(1024, buf, sizeof(buf)); + rf = fopen(filename, "wb"); + if (rf == NULL) + return (FALSE); + fwrite(buf, sizeof(unsigned char), nchars, rf); + fclose(rf); + return (TRUE); +} + +unsigned int +getrandom_chars(int desired, unsigned char *buf, int lenbuf) { + HCRYPTPROV hcryptprov; + BOOL err; + + if (buf == NULL || lenbuf <= 0 || desired > lenbuf) + return (0); + /* + * The first time we just try to acquire the context + */ + err = CryptAcquireContext(&hcryptprov, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT); + if (!err){ + return (0); + } + if (!CryptGenRandom(hcryptprov, desired, buf)) { + CryptReleaseContext(hcryptprov, 0); + return (0); + } + + CryptReleaseContext(hcryptprov, 0); + return (desired); +} + |