]> granicus.if.org Git - php/commitdiff
- add striped down version of RNG layer to have a reliable random src on windows
authorPierre Joye <pajoye@php.net>
Tue, 8 Jun 2010 13:00:11 +0000 (13:00 +0000)
committerPierre Joye <pajoye@php.net>
Tue, 8 Jun 2010 13:00:11 +0000 (13:00 +0000)
win32/winutil.c

index 24b00edfae438c4cccb92126483e2914a0a71367..b3bb90f16e5061334522704c88b16b99ab4509e9 100644 (file)
    | obtain it through the world-wide-web, please send a note to          |
    | license@php.net so we can mail you a copy immediately.               |
    +----------------------------------------------------------------------+
-   | Author:                                                              |
+   | Author: Zeev Suraski <zeev@zend.com>                                 |
+   *         Pierre Joye <pierre@php.net>                                 |
    +----------------------------------------------------------------------+
  */
 
 /* $Id$ */
 
 #include "php.h"
+#include <wincrypt.h>
 
 PHPAPI char *php_win_err(int error)
 {
@@ -46,3 +48,35 @@ int php_win32_check_trailing_space(const char * path, const int path_len) {
                return 0;
        }
 }
+
+PHPAPI int php_win32_get_random_bytes(unsigned char *buf, size_t size) {  /* {{{ */
+       HCRYPTPROV   hCryptProv;
+       int has_context = 0;
+       BOOL ret;
+       size_t i = 0;
+
+       if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) {
+               /* Could mean that the key container does not exist, let try 
+                  again by asking for a new one */
+               if (GetLastError() == NTE_BAD_KEYSET) {
+                       if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
+                               has_context = 1;
+                       } else {
+                               return FAILURE;
+                       }
+               }
+       }
+
+       ret = CryptGenRandom(hCryptProv, size, buf);
+       CryptReleaseContext(hCryptProv, 0);
+       if (ret) {
+               while (i < size && buf[i] != 0) {
+                       i++;
+               }
+               if (i == size) {
+                       return SUCCESS;
+               }
+   }
+       return FAILURE;
+}
+/* }}} */