move random data generation out to category for easier use

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@37558 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2014-01-08 11:14:53 +00:00
parent 150289de30
commit 99517dd9b1
4 changed files with 102 additions and 39 deletions

View file

@ -31,11 +31,87 @@
#include <ctype.h>
#if defined(__MINGW32__)
#include <wincrypt.h>
#else
#include <fcntl.h>
#endif
static int
randombytes(uint8_t *buf, unsigned len)
{
#if defined(__MINGW32__)
HCRYPTPROV hProvider = 0;
if (!CryptAcquireContextW(&hProvider, 0, 0,
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
{
return -1;
}
if (!CryptGenRandom(hProvider, len, buf))
{
CryptReleaseContext(hProvider, 0);
return -1;
}
CryptReleaseContext(hProvider, 0);
#else
int devUrandom;
ssize_t bytesRead;
devUrandom = open("/dev/urandom", O_RDONLY);
if (devUrandom == -1)
{
return -1;
}
bytesRead = read(devUrandom, buf, len);
close(devUrandom);
if (bytesRead != len)
{
return -1;
}
#endif
return 0;
}
/**
* Extension methods for the NSData class.
*/
@implementation NSData (GNUstepBase)
+ (id) dataWithRandomBytesOfLength: (NSUInteger)length
{
uint8_t *buf = 0;
NSData *d;
if (0 == length || length > 0xffffffff)
{
return nil; // Unreasonable length for random data
}
buf = malloc(length);
if (0 == buf)
{
return nil; // Not enough memory for random data
}
if (randombytes(buf, (unsigned)length) < 0)
{
free(buf);
return nil; // Unable to generate the random data
}
d = [[self alloc] initWithBytesNoCopy: buf length: length freeWhenDone: YES];
if (nil == d)
{
free(buf);
return nil; // Unable to create NSData instance
}
return AUTORELEASE(d);
}
/**
* Returns an NSString object containing an ASCII hexadecimal representation
* of the receiver. This means that the returned object will contain