This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.2
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 18d11b71141c7c8a4098e18b26bc2ac50b2b549c
Author: Felix Meschberger <[email protected]>
AuthorDate: Mon Sep 6 11:59:13 2010 +0000

    SLING-1729 Provide a simple and faster alternative to the default 
SecureRandom seeding. This might be of interest mostly for the Linux and 
Solaris platforms which seed SecureRandom from the blocking /dev/random by 
default.
    
    git-svn-id: 
https://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form@993004 
13f79535-47bb-0310-9956-ffa450edef68
---
 .../auth/form/impl/FormAuthenticationHandler.java  | 17 +++++-
 .../apache/sling/auth/form/impl/TokenStore.java    | 71 ++++++++++++++++++++--
 .../OSGI-INF/metatype/metatype.properties          |  7 +++
 3 files changed, 90 insertions(+), 5 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java 
b/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java
index e59975c..57b7ce3 100644
--- 
a/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java
+++ 
b/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java
@@ -153,6 +153,19 @@ public class FormAuthenticationHandler extends 
AbstractAuthenticationHandler {
     @Property(value = DEFAULT_TOKEN_FILE)
     private static final String PAR_TOKEN_FILE = "form.token.file";
 
+    private static final boolean DEFAULT_TOKEN_FAST_SEED = false;
+
+    /**
+     * Whether to use a less secure but faster seeding mechanism to seed the
+     * random number generator in the {@link TokenStore}. By default the faster
+     * mechanism is disabled and the platform provided seeding is used. This 
may
+     * however block the startup considerably, particularly on Linux and 
Solaris
+     * platforms which use the (blocking but secure) <code>/dev/random</code>
+     * device for seeding.
+     */
+    @Property(boolValue = DEFAULT_TOKEN_FAST_SEED)
+    private static final String PAR_TOKEN_FAST_SEED = "form.token.fastseed";
+
     /**
      * The default include value.
      *
@@ -758,8 +771,10 @@ public class FormAuthenticationHandler extends 
AbstractAuthenticationHandler {
             properties.get(PAR_TOKEN_FILE), DEFAULT_TOKEN_FILE);
         final File tokenFile = getTokenFile(tokenFileName,
             componentContext.getBundleContext());
+        final boolean fastSeed = OsgiUtil.toBoolean(
+            properties.get(PAR_TOKEN_FAST_SEED), DEFAULT_TOKEN_FAST_SEED);
         log.info("Storing tokens in {}", tokenFile.getAbsolutePath());
-        this.tokenStore = new TokenStore(tokenFile, sessionTimeout);
+        this.tokenStore = new TokenStore(tokenFile, sessionTimeout, fastSeed);
 
         this.loginModule = null;
         try {
diff --git a/src/main/java/org/apache/sling/auth/form/impl/TokenStore.java 
b/src/main/java/org/apache/sling/auth/form/impl/TokenStore.java
index 31a3977..d79e686 100644
--- a/src/main/java/org/apache/sling/auth/form/impl/TokenStore.java
+++ b/src/main/java/org/apache/sling/auth/form/impl/TokenStore.java
@@ -25,9 +25,9 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.security.InvalidKeyException;
+import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
-
 import javax.crypto.Mac;
 import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
@@ -109,9 +109,10 @@ class TokenStore {
      * @throws NullPointerException if <code>tokenFile</code> is
      *             <code>null</code>.
      */
-    TokenStore(final File tokenFile, final long sessionTimeout)
-            throws NoSuchAlgorithmException, InvalidKeyException,
-            IllegalStateException, UnsupportedEncodingException {
+    TokenStore(final File tokenFile, final long sessionTimeout,
+            final boolean fastSeed) throws NoSuchAlgorithmException,
+            InvalidKeyException, IllegalStateException,
+            UnsupportedEncodingException {
 
         if (tokenFile == null) {
             throw new NullPointerException("tokenfile");
@@ -126,6 +127,9 @@ class TokenStore {
         loadTokens();
 
         // warm up the crypto API
+        if (fastSeed) {
+            random.setSeed(getFastEntropy());
+        }
         byte[] b = new byte[20];
         random.nextBytes(b);
         final SecretKey secretKey = new SecretKeySpec(b, HMAC_SHA1);
@@ -377,4 +381,63 @@ class TokenStore {
         }
         return new String(c);
     }
+
+    /**
+     * Creates a byte array of entry from the current state of the system:
+     * <ul>
+     * <li>The current system time in milliseconds since the epoch</li>
+     * <li>The number of nanoseconds since system startup</li>
+     * <li>The name, size and last modification time of the files in the
+     * <code>java.io.tmpdir</code> folder.</li>
+     * </ul>
+     * <p>
+     * <b>NOTE</b> This method generates entropy fast but not necessairily
+     * secure enough for seeding the random number generator.
+     *
+     * @return bytes of entropy
+     */
+    private static byte[] getFastEntropy() {
+        final MessageDigest md;
+
+        try {
+            md = MessageDigest.getInstance("SHA");
+        } catch (NoSuchAlgorithmException nsae) {
+            throw new InternalError("internal error: SHA-1 not available.");
+        }
+
+        // update with XorShifted time values
+        update(md, System.currentTimeMillis());
+        update(md, System.nanoTime());
+
+        // scan the temp file system
+        File file = new File(System.getProperty("java.io.tmpdir"));
+        File[] entries = file.listFiles();
+        if (entries != null) {
+            for (File entry : entries) {
+                md.update(entry.getName().getBytes());
+                update(md, entry.lastModified());
+                update(md, entry.length());
+            }
+        }
+
+        return md.digest();
+    }
+
+    /**
+     * Updates the message digest with an XOR-Shifted value.
+     *
+     * @param md The MessageDigest to update
+     * @param value The original value to be XOR-Shifted first before taking 
the
+     *            bytes ot update the message digest
+     */
+    private static void update(final MessageDigest md, long value) {
+        value ^= (value << 21);
+        value ^= (value >>> 35);
+        value ^= (value << 4);
+
+        for (int i = 0; i < 8; i++) {
+            md.update((byte) value);
+            value >>= 8;
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties 
b/src/main/resources/OSGI-INF/metatype/metatype.properties
index 5aa2bd7..2d92666 100644
--- a/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ b/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -67,6 +67,13 @@ form.token.file.description = The name of the file used to 
persist the \
  working directory. In the future this file may be store in the JCR Repository 
\
  to support clustering scenarios.
 
+form.token.fastseed.name = Fast Seed Generator
+form.token.fastseed.description = Defines whether the random number generator \
+ should be seeded with a fast but less secure method. If this property is not \
+ set or is set to "false" the seed generator of the Java platform will be \
+ used. By default the secure seed generator is used, which may block startup \
+ on Linux and Solaris systems due to accessing /dev/random.
+
 service.ranking.name = Ranking
 service.ranking.description = The relative ranking of this service.
 

-- 
To stop receiving notification emails like this one, please contact
"[email protected]" <[email protected]>.

Reply via email to