summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--random/random-csprng.c96
1 files changed, 89 insertions, 7 deletions
diff --git a/random/random-csprng.c b/random/random-csprng.c
index b06810a0..66f57864 100644
--- a/random/random-csprng.c
+++ b/random/random-csprng.c
@@ -140,7 +140,7 @@ static int pool_balance;
static int just_mixed;
/* The name of the seed file or NULL if no seed file has been defined.
- The seed file needs to be regsitered at initialiation time. We
+ The seed file needs to be registered at initialization time. We
keep a malloced copy here. */
static char *seed_file_name;
@@ -667,6 +667,88 @@ _gcry_rngcsprng_set_seed_file (const char *name)
}
+
+/* Helper for my_open.
+ * Return a malloced wide char string from an UTF-8 encoded input
+ * string STRING. Caller must free this value. Returns NULL and sets
+ * ERRNO on failure. Calling this function with STRING set to NULL is
+ * not defined. */
+#ifdef HAVE_W32_SYSTEM
+static wchar_t *
+utf8_to_wchar (const char *string)
+{
+ int n;
+ size_t nbytes;
+ wchar_t *result;
+
+ n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
+ if (n < 0)
+ {
+ gpg_err_set_errno (EINVAL);
+ return NULL;
+ }
+
+ nbytes = (size_t)(n+1) * sizeof(*result);
+ if (nbytes / sizeof(*result) != (n+1))
+ {
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+ result = xtrymalloc (nbytes);
+ if (!result)
+ return NULL;
+
+ n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
+ if (n < 0)
+ {
+ xfree (result);
+ gpg_err_set_errno (EINVAL);
+ result = NULL;
+ }
+ return result;
+}
+#endif /*HAVE_W32_SYSTEM*/
+
+
+/* Helper for my_open. */
+#ifdef HAVE_W32_SYSTEM
+static int
+any8bitchar (const char *string)
+{
+ if (string)
+ for ( ; *string; string++)
+ if ((*string & 0x80))
+ return 1;
+ return 0;
+}
+#endif /*HAVE_W32_SYSTEM*/
+
+
+/* A wrapper around open to handle Unicode file names under Windows. */
+static int
+my_open (const char *name, int flags, unsigned int mode)
+{
+#ifdef HAVE_W32_SYSTEM
+ if (any8bitchar (name))
+ {
+ wchar_t *wname;
+ int ret;
+
+ wname = utf8_to_wchar (name);
+ if (!wname)
+ return -1;
+ ret = _wopen (wname, flags, mode);
+ xfree (wname);
+ return ret;
+ }
+ else
+ return open (name, flags, mode);
+#else
+ return open (name, flags, mode);
+#endif
+}
+
+
/* Lock an open file identified by file descriptor FD and wait a
reasonable time to succeed. With FOR_WRITE set to true a write
lock will be taken. FNAME is used only for diagnostics. Returns 0
@@ -742,9 +824,9 @@ read_seed_file (void)
return 0;
#ifdef HAVE_DOSISH_SYSTEM
- fd = open( seed_file_name, O_RDONLY | O_BINARY );
+ fd = my_open (seed_file_name, O_RDONLY | O_BINARY, 0);
#else
- fd = open( seed_file_name, O_RDONLY );
+ fd = my_open (seed_file_name, O_RDONLY, 0);
#endif
if( fd == -1 && errno == ENOENT)
{
@@ -873,13 +955,13 @@ _gcry_rngcsprng_update_seed_file (void)
mix_pool(keypool); rndstats.mixkey++;
#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
- fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
- S_IRUSR|S_IWUSR );
+ fd = my_open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
+ S_IRUSR|S_IWUSR );
#else
# if LOCK_SEED_FILE
- fd = open (seed_file_name, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR );
+ fd = my_open (seed_file_name, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR );
# else
- fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
+ fd = my_open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
# endif
#endif