Author: rfm
Date: Thu Jul 24 11:34:32 2014
New Revision: 38004

URL: http://svn.gna.org/viewcvs/gnustep?rev=38004&view=rev
Log:
Expose salt (random data) generation code and improve reliability.

Modified:
    libs/webservices/trunk/ChangeLog
    libs/webservices/trunk/GNUmakefile
    libs/webservices/trunk/GWSHash.h
    libs/webservices/trunk/GWSHash.m
    libs/webservices/trunk/WSSUsernameToken.m

Modified: libs/webservices/trunk/ChangeLog
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/webservices/trunk/ChangeLog?rev=38004&r1=38003&r2=38004&view=diff
==============================================================================
--- libs/webservices/trunk/ChangeLog    (original)
+++ libs/webservices/trunk/ChangeLog    Thu Jul 24 11:34:32 2014
@@ -1,3 +1,13 @@
+2014-07-24 Richard Frith-Macdonald  <[email protected]>
+
+       * GWSHash.h: Declare ([+salt:size:])
+       * GWSHash.m: Implement ([+salt:size:])
+        * WSSUsernameToken.m: Use ([GWSHash+salt:size:])
+       * GNUmakefile: bump version for release (Version 0.7.1)
+       Remove redundant salt generation code, combining use of gnutls
+       falling back to /dev/urandom and finally the C library routines.
+       Expose for use by other code.
+
 2014-07-18 Richard Frith-Macdonald  <[email protected]>
 
        * WSSUsernameToken.h:

Modified: libs/webservices/trunk/GNUmakefile
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/webservices/trunk/GNUmakefile?rev=38004&r1=38003&r2=38004&view=diff
==============================================================================
--- libs/webservices/trunk/GNUmakefile  (original)
+++ libs/webservices/trunk/GNUmakefile  Thu Jul 24 11:34:32 2014
@@ -21,7 +21,7 @@
 -include config.make
 
 PACKAGE_NAME = WebServices
-PACKAGE_VERSION = 0.7.0
+PACKAGE_VERSION = 0.7.1
 WebServices_INTERFACE_VERSION=0.7
 CVS_MODULE_NAME = gnustep/dev-libs/WebServices
 CVS_TAG_NAME = WebServices

Modified: libs/webservices/trunk/GWSHash.h
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/webservices/trunk/GWSHash.h?rev=38004&r1=38003&r2=38004&view=diff
==============================================================================
--- libs/webservices/trunk/GWSHash.h    (original)
+++ libs/webservices/trunk/GWSHash.h    Thu Jul 24 11:34:32 2014
@@ -140,6 +140,15 @@
  */
 + (GWSHash*) hashWithString: (NSString*)string;
 
+/** Generates a cryptographically random salt of the specified length in
+ * the supplied buffer.  This attmpts to use the best random data source
+ * available (from gnutls or /dev/urandom or the C library random number
+ * generator).<br />
+ * This method is used internally to generate the nonce (which is a hex
+ * encoded string representation of 16 bytes of random data).
+ */
++ (void) salt: (uint8_t*)buffer size: (unsigned)length;
+
 /** Return the hash algorithm used by the receiver.
  */
 - (NSString*) hashAlgorithm;

Modified: libs/webservices/trunk/GWSHash.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/webservices/trunk/GWSHash.m?rev=38004&r1=38003&r2=38004&view=diff
==============================================================================
--- libs/webservices/trunk/GWSHash.m    (original)
+++ libs/webservices/trunk/GWSHash.m    Thu Jul 24 11:34:32 2014
@@ -45,6 +45,8 @@
 #endif
 
 #include "config.h"
+#include <unistd.h>
+#include <fcntl.h>
 
 #if  USE_GNUTLS == 1
 #include <gnutls/gnutls.h>
@@ -316,9 +318,9 @@
 
 static inline NSString* generateSalt(NSUInteger length)
 {
-#if  USE_GNUTLS == 1
   uint8_t stack[32];
   void *buffer;
+
   if (length <= 32)
     {
       // Use the stack as a buffer
@@ -333,15 +335,7 @@
                      format: @"Out of memory when allocating buffer for RNG"];
        }
     }
-  if (0 != gnutls_rnd(GNUTLS_RND_NONCE, buffer, length))
-    {
-      if (length > 32)
-        {
-         free(buffer);
-       }
-      [NSException raise: NSInternalInconsistencyException
-                 format: @"Error when generating random number"];
-    }
+  [GWSHash salt: buffer size: length];
   NSString *salt = [[GWSCoder coder] encodeHexBinaryFrom: 
     [NSData dataWithBytesNoCopy: buffer length: length freeWhenDone: NO]];
   if (length > 32)
@@ -349,11 +343,6 @@
       free(buffer);
     }
   return [salt lowercaseString];
-#else
-  [NSException raise: NSInvalidArgumentException
-              format: @"Random number generation disabled."];
-  return nil;
-#endif
 }
 
 
@@ -770,6 +759,70 @@
                                         salt: salt] autorelease];
 }
 
++ (void) salt: (uint8_t*)buffer size: (unsigned)length
+{
+  unsigned      pos = 0;
+
+#if  USE_GNUTLS == 1
+  if (0 == gnutls_rnd(GNUTLS_RND_NONCE, buffer, length))
+    {
+      pos = length;     // We managed to get data from gnutls
+    }
+#endif
+
+  if (pos < length)
+    {
+      int       desc;
+
+      /* Try to read random data from /dev/urandom ... the preferred
+       * source for cryptographically random data.
+       */
+      if ((desc = open("/dev/urandom", O_RDONLY)) > 0)
+        {
+          while (pos < length)
+            {
+              ssize_t result = read(desc, buffer + pos, length - pos);
+
+              if (result < 0)
+                {
+                  break;    // Failed to read random data
+                }
+              pos += (unsigned)result;
+            }
+          close(desc);
+        }
+    }
+
+  if (pos < length)
+    {
+      uint32_t  r;
+
+#ifdef __MINGW__
+#define RANDOM()   rand()
+#define SRANDOM(s)  srand(s)
+#else
+#define RANDOM()   random()
+#define SRANDOM(s)  srandom(s)
+#endif
+
+      /* Anything we couldn't get from /dev/urandom comes from the C library
+       * pseudo-random data function instead.
+       */
+      SRANDOM((unsigned)[[NSDate date] timeIntervalSinceReferenceDate]);
+      while (length - pos >= 4)
+        {
+          r = (uint32_t)RANDOM();
+          memcpy(buffer + pos, &r, 4);
+          pos += 4;
+        }
+      if (pos < length)
+        {
+          r = (uint32_t)RANDOM();
+          memcpy(buffer + pos, &r, length - pos);
+        }
+    }
+}
+
 - (BOOL) verifyWithParameters: (NSDictionary*)parameters
                         order: (NSArray*)order
                         extra: (id)additionalValue

Modified: libs/webservices/trunk/WSSUsernameToken.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/webservices/trunk/WSSUsernameToken.m?rev=38004&r1=38003&r2=38004&view=diff
==============================================================================
--- libs/webservices/trunk/WSSUsernameToken.m   (original)
+++ libs/webservices/trunk/WSSUsernameToken.m   Thu Jul 24 11:34:32 2014
@@ -25,6 +25,7 @@
 
 #import <Foundation/Foundation.h>
 #import "GWSPrivate.h"
+#import "GWSHash.h"
 #import "WSSUsernameToken.h"
 #include <config.h>
 #include <stdlib.h>
@@ -36,14 +37,6 @@
 
 static NSTimeZone      *gmt = nil;
 static GWSCoder                *coder = nil;
-
-#ifdef __MINGW__
-#define RANDOM()   rand()
-#define SRANDOM(s)  srand(s)
-#else
-#define RANDOM()   random()
-#define SRANDOM(s)  srandom(s)
-#endif
 
 @implementation        WSSUsernameToken
 
@@ -119,11 +112,8 @@
     {
       uint32_t buf[4];
 
-      buf[0] = (uint32_t)RANDOM();
-      buf[1] = (uint32_t)RANDOM();
-      buf[2] = (uint32_t)RANDOM();
-      buf[3] = (uint32_t)RANDOM();
-      nd = [NSData dataWithBytes: buf length: 16];
+      [GWSHash salt: (uint8_t*)buf size: sizeof(buf)];
+      nd = [NSData dataWithBytes: (const void*)buf length: 16];
       n = [coder encodeBase64From: nd];
       if (0 != nonce)
        {
@@ -158,7 +148,6 @@
 
 + (void) initialize
 {
-  SRANDOM((unsigned)[[NSDate date] timeIntervalSinceReferenceDate]);
   if (gmt == nil)
     {
       gmt = [[NSTimeZone timeZoneForSecondsFromGMT: 0] retain];


_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs

Reply via email to