1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "apr.h" 18#include <rpc.h> 19#include <wincrypt.h> 20#include "apr_private.h" 21#include "apr_general.h" 22#include "apr_portable.h" 23#include "apr_arch_misc.h" 24 25 26APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char * buf, 27 apr_size_t length) 28{ 29 HCRYPTPROV hProv; 30 apr_status_t res = APR_SUCCESS; 31 32 /* 0x40 bit = CRYPT_SILENT, only introduced in more recent PSDKs 33 * and will only work for Win2K and later. 34 */ 35 DWORD flags = CRYPT_VERIFYCONTEXT 36 | ((apr_os_level >= APR_WIN_2000) ? 0x40 : 0); 37 38 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, flags)) { 39 return apr_get_os_error(); 40 } 41 /* XXX: An ugly hack for Win64, randomness is such that noone should 42 * ever expect > 2^31 bytes of data at once without the prng 43 * coming to a complete halt. 44 */ 45 if (!CryptGenRandom(hProv, (DWORD)length, buf)) { 46 res = apr_get_os_error(); 47 } 48 CryptReleaseContext(hProv, 0); 49 return res; 50} 51 52 53APR_DECLARE(apr_status_t) apr_os_uuid_get(unsigned char *uuid_data) 54{ 55 /* Note: this call doesn't actually require CoInitialize() first 56 * 57 * XXX: we should scramble the bytes or some such to eliminate the 58 * possible misuse/abuse since uuid is based on the NIC address, and 59 * is therefore not only a uniqifier, but an identity (which might not 60 * be appropriate in all cases. 61 * 62 * Note that Win2000, XP and later no longer suffer from this problem, 63 * a scrambling fix is only needed for (apr_os_level < APR_WIN_2000) 64 */ 65 if (FAILED(UuidCreate((UUID *)uuid_data))) { 66 return APR_EGENERAL; 67 } 68 return APR_SUCCESS; 69} 70