summaryrefslogtreecommitdiff
path: root/ports/winnt/libntp/randfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'ports/winnt/libntp/randfile.c')
-rw-r--r--ports/winnt/libntp/randfile.c109
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);
+}
+