mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
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:
parent
150289de30
commit
99517dd9b1
4 changed files with 102 additions and 39 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,10 +1,17 @@
|
|||
2014-01-08 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSUUID.m:
|
||||
* Source/Additions/NSData+GNUstepBase.m:
|
||||
* Headers/GNUstepBase/NSData+GNUstepBase.h:
|
||||
Move random data generation out to the NSData(GNUstepBase) category.
|
||||
|
||||
2014-01-07 Quentin Mathe <quentin.mathe@gmail.com>
|
||||
|
||||
* Source/NSJSONSerialization.m (writeObject()): Fixed double number
|
||||
serialization to encode 17 significant digits (this matches the max number
|
||||
of significant digits in the double-precision floating point format). This
|
||||
prevents a loss of precision, in case the number has more than 3 digits
|
||||
after the decimal point.
|
||||
serialization to encode 17 significant digits (this matches the max
|
||||
number of significant digits in the double-precision floating point
|
||||
format). This prevents a loss of precision, in case the number has
|
||||
more than 3 digits after the decimal point.
|
||||
* Tests/base/NSJSONSerialization/json.m: Updated to test double number
|
||||
serialization.
|
||||
|
||||
|
|
|
@ -37,6 +37,16 @@ extern "C" {
|
|||
#if OS_API_VERSION(GS_API_NONE,GS_API_LATEST)
|
||||
|
||||
@interface NSData (GNUstepBase)
|
||||
|
||||
/** Returns an autoreleased data instance initialised with pseudo-random
|
||||
* bytes of the specified length.<br />
|
||||
* On failure returns nil. This may be due to:<br />
|
||||
* A zero length or unreasonably large length argument or,<br />
|
||||
* Failure to allocate memory to hold the random data or,<br />
|
||||
* Failure of the underlying random data generation.
|
||||
*/
|
||||
+ (id) dataWithRandomBytesOfLength: (NSUInteger)length;
|
||||
|
||||
/**
|
||||
* Returns an NSString object containing an ASCII hexadecimal representation
|
||||
* of the receiver. This means that the returned object will contain
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -26,12 +26,8 @@
|
|||
#import "common.h"
|
||||
#import "Foundation/NSCoder.h"
|
||||
#import "Foundation/NSUUID.h"
|
||||
#import "GNUstepBase/NSData+GNUstepBase.h"
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
#include <wincrypt.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
static int uuid_from_string(const char *string, unsigned char *uuid);
|
||||
static void string_from_uuid(const unsigned char *uuid, char *string);
|
||||
|
@ -260,6 +256,7 @@ static void string_from_uuid(const unsigned char *uuid, char *string)
|
|||
|
||||
static int random_uuid(unsigned char *uuid)
|
||||
{
|
||||
NSData *rnd;
|
||||
unsigned char timeByte;
|
||||
unsigned char sequenceByte;
|
||||
|
||||
|
@ -268,40 +265,13 @@ static int random_uuid(unsigned char *uuid)
|
|||
* problems (and are more work...)
|
||||
*/
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
|
||||
HCRYPTPROV hProvider = 0;
|
||||
|
||||
if (!CryptAcquireContextW(&hProvider, 0, 0,
|
||||
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
|
||||
rnd = [NSData dataWithRandomBytesOfLength: kUUIDByteCount];
|
||||
if (nil == rnd)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!CryptGenRandom(hProvider, kUUIDByteCount, uuid))
|
||||
{
|
||||
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, uuid, kUUIDByteCount);
|
||||
close(devUrandom);
|
||||
if (bytesRead != kUUIDByteCount)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
memcpy(uuid, [rnd bytes], kUUIDByteCount);
|
||||
|
||||
/* as required by the RFC, bits 48-51 should contain 0b0100 (4)
|
||||
* and bits 64-65 should contain 0b01 (1)
|
||||
|
|
Loading…
Reference in a new issue