summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2020-10-23 13:34:22 +0200
committerWerner Koch <wk@gnupg.org>2020-10-23 13:43:15 +0200
commit24341f58f0d38bd62c45d285bcf8472f82b56135 (patch)
tree6b2a360592ff360b64360bfc816fdf18fc523963
parent4a50c6b88d6d8d843e50add851a8a5e691349097 (diff)
downloadlibgcrypt-24341f58f0d38bd62c45d285bcf8472f82b56135.tar.gz
random: Allow for a Unicode random seed file on Windows.
* random/random-csprng.c (utf8_to_wchar) [W32]: New. (any8bitchar) [W32]: New. (my_open): New. Replace all calls to open with this. -- Users with account names having an Unicode character in their name may now create a random_see file without running into an error. Note that depending on the code page this used to work but for sure no if more than one byte is required. For testing I used "â’¶nne". GnuPG-bug-id: 5098 Signed-off-by: Werner Koch <wk@gnupg.org>
-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